diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5a42941c..12e00855 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -8,7 +8,7 @@ "homepage": "https://github.com/alirezarezvani/claude-skills", "repository": "https://github.com/alirezarezvani/claude-skills", "metadata": { - "description": "364 production-ready skills across 18 domains (engineering, engineering-core, marketing, product, c-level, compliance-os, project management, RA/QM, business growth, finance, productivity, marketing top-level, research, research-ops, business-operations, commercial, markdown-html, loop-library, plus standards). 666 Python tools, 749 reference guides, 104 agents (cs-* + personas), 119 slash commands across 90 marketplace plugins. v2.11.2 vendors engineering/skillopt-sleep — a verbatim copy of microsoft/SkillOpt's stdlib-only skillopt_sleep engine + Claude Code plugin surface, giving a local agent a nightly gated self-improvement cycle (read-only session harvest -> mine -> offline replay -> held-out-gated CLAUDE.md/SKILL.md edits -> staged for explicit /skillopt-sleep adopt). productivity/fable-goal (unreleased, post-v2.11.1) converts a rambling description of a desired outcome into one polished /goal prompt for a fresh autonomous session. v2.11.1 turns product-team and project-management into agent-harness domains: fork-orchestrators with deterministic goal routers, a Jira MCP snapshot bridge (Kanban flow metrics + Monte Carlo forecasting), a delegation-governance loop gate, a continuous-discovery cadence tracker, and an Opportunity Solution Tree linter, with /cs:pm and /cs:product command families. v2.10.3 completes the markdown-html domain with md-slides — slide-deck converter (arrow-key / Space / PgDn / Home/End / P keyboard navigation + presenter mode with split-view clock + speaker notes + next-slide preview + URL-hash deep linking like #3 for direct slide jumps + @media print page-per-slide for browser-native PDF export). Reuses md-document's markdown parser; vanilla JS only (no framework runtime); Prism.js opt-in via --syntax. Joins md-review (v2.10.2 code-review converter), md-document (v2.10.1 long-form converter), and the v2.10.0 foundation (orchestrator + design-system). Compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, OpenClaw, Hermes Agent, Mistral Vibe, and 5 more coding agents.", + "description": "371 production-ready skills across 19 domains (engineering, engineering-core, marketing, product, c-level, c-level-agents, compliance-os, project management, RA/QM, business growth, finance, productivity, marketing top-level, research, research-ops, business-operations, commercial, markdown-html, loop-library, plus standards). 675 Python tools, 812 reference guides, 104 agents (cs-* + personas), 120 slash commands across 93 marketplace plugins. v2.11.2 vendors engineering/skillopt-sleep — a verbatim copy of microsoft/SkillOpt's stdlib-only skillopt_sleep engine + Claude Code plugin surface, giving a local agent a nightly gated self-improvement cycle (read-only session harvest -> mine -> offline replay -> held-out-gated CLAUDE.md/SKILL.md edits -> staged for explicit /skillopt-sleep adopt). productivity/fable-goal (unreleased, post-v2.11.1) converts a rambling description of a desired outcome into one polished /goal prompt for a fresh autonomous session. v2.11.1 turns product-team and project-management into agent-harness domains: fork-orchestrators with deterministic goal routers, a Jira MCP snapshot bridge (Kanban flow metrics + Monte Carlo forecasting), a delegation-governance loop gate, a continuous-discovery cadence tracker, and an Opportunity Solution Tree linter, with /cs:pm and /cs:product command families. v2.10.3 completes the markdown-html domain with md-slides — slide-deck converter (arrow-key / Space / PgDn / Home/End / P keyboard navigation + presenter mode with split-view clock + speaker notes + next-slide preview + URL-hash deep linking like #3 for direct slide jumps + @media print page-per-slide for browser-native PDF export). Reuses md-document's markdown parser; vanilla JS only (no framework runtime); Prism.js opt-in via --syntax. Joins md-review (v2.10.2 code-review converter), md-document (v2.10.1 long-form converter), and the v2.10.0 foundation (orchestrator + design-system). Compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, OpenClaw, Hermes Agent, Mistral Vibe, and 5 more coding agents.", "version": "2.11.2" }, "plugins": [ @@ -39,7 +39,7 @@ { "name": "c-level-skills", "source": "./c-level-advisor", - "description": "33 C-level advisory skills + c-level-agents plugin layer: virtual board of directors (CEO, CTO, COO, CPO, CMO, CFO, CRO, CISO, CHRO) plus General Counsel, CDO, CAIO, CCO, and VP of Engineering (DORA delivery throughput analyzer, engineering hiring funnel calculator with conversion + pipeline gap, eng team structure designer with squad/tribe + manager-trigger), executive mentor, founder coach, orchestration (Chief of Staff, board meetings, decision logger), strategic capabilities (board deck builder, scenario war room, competitive intel, M&A playbook), culture frameworks, and 13 cs-* persona agents + 21 /cs:* slash commands (founder-mode router, office-hours intake, multi-role boardroom, strategic sprint pipeline, cross-model consensus, cooldown freeze).", + "description": "33 C-level advisory skills (install the separate companion c-level-agents plugin for the persona layer): virtual board of directors (CEO, CTO, COO, CPO, CMO, CFO, CRO, CISO, CHRO) plus General Counsel, CDO, CAIO, CCO, and VP of Engineering (DORA delivery throughput analyzer, engineering hiring funnel calculator with conversion + pipeline gap, eng team structure designer with squad/tribe + manager-trigger), executive mentor, founder coach, orchestration (Chief of Staff, board meetings, decision logger), strategic capabilities (board deck builder, scenario war room, competitive intel, M&A playbook), culture frameworks. The 13 cs-* persona agents + 21 /cs:* slash commands (founder-mode router, office-hours intake, multi-role boardroom, strategic sprint pipeline, cross-model consensus, cooldown freeze) ship in the companion c-level-agents plugin.", "version": "2.9.0", "author": { "name": "Alireza Rezvani" @@ -60,7 +60,7 @@ }, { "name": "c-level-agents", - "source": "./c-level-advisor/c-level-agents", + "source": "./c-level-agents", "description": "Founder-mode executive team plugin: 13 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, Chief of Staff, General Counsel, Chief Data Officer, Chief AI Officer, Chief Customer Officer, VP of Engineering) with distinct cognitive voices, plus 21 /cs:* slash commands — forcing-question office hours (CFO/CMO/CPO/CRO/CTO/CISO/GC/CDO/CAIO/CCO/VPE reviews), strategic sprint pipeline (brief → boardroom → decide → execute → post-mortem), and meta routing (/cs:founder-mode auto-router, /cs:onboard, /cs:cross-eval multi-model consensus, /cs:freeze cooldown lock). Wraps the 33 c-level skills with cognitive gearing, persona voice, and artifact-driven handoffs. The business-domain answer to YC Garry Tan's gstack.", "version": "2.9.0", "author": { @@ -245,7 +245,7 @@ { "name": "engineering-advanced-skills", "source": "./engineering", - "description": "37 advanced engineering skills: agent designer, agent workflow designer, RAG architect, database designer + schema designer + SQL assistant, migration architect, observability designer, dependency auditor, changelog generator (with semantic version bumper and hotfix/rollback procedures), API design reviewer, API test suite builder, CI/CD pipeline builder, MCP server builder, skill security auditor, skill tester, performance profiler, focused-fix, browser-automation, full-page-screenshot, git-worktree-manager, monorepo-navigator, codebase-onboarding, interview-system-designer, runbook-generator, spec-driven-workflow, secrets-vault-manager, env-secrets-manager, pr-review-expert, self-eval, tc-tracker (task context tracker with lifecycle and handoff format), feature-flags-architect, kubernetes-operator, chaos-engineering, ship-gate (pre-production 8-category audit with deploy-intent intercept), slo-architect (SLO designer, error-budget calculator with multi-window burn-rate alerts, SLO reviewer per Google SRE Workbook), and tech-debt-tracker. Agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw.", + "description": "37 advanced engineering skills: agent designer, agent workflow designer, RAG architect, database designer + schema designer + SQL assistant, migration architect, observability designer, dependency auditor, changelog generator (semantic version bumper + hotfix/rollback), API design reviewer, API test suite builder, CI/CD pipeline builder, MCP server builder, skill security auditor, skill tester, performance profiler, focused-fix, browser-automation, full-page-screenshot, git-worktree-manager, monorepo-navigator, codebase-onboarding, interview-system-designer, runbook-generator, spec-driven-workflow, secrets-vault-manager, env-secrets-manager, pr-review-expert, self-eval, tc-tracker, feature-flags-architect, kubernetes-operator, chaos-engineering, ship-gate (pre-production 8-category audit), slo-architect (error-budget + multi-window burn-rate alerts per Google SRE Workbook), and tech-debt-tracker. Agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw.", "version": "2.9.0", "author": { "name": "Alireza Rezvani" @@ -436,7 +436,7 @@ { "name": "autoresearch-agent", "source": "./engineering/autoresearch-agent", - "description": "Autonomous experiment loop — optimize any file by a measurable metric. 5 slash commands (/ar:setup, /ar:run, /ar:loop, /ar:status, /ar:resume), 8 built-in evaluators, configurable loop intervals (10min to monthly).", + "description": "Autonomous experiment loop — optimize any file by a measurable metric. 5 slash commands (/ar:setup, /ar:run, /ar:loop, /ar:ar-status, /ar:ar-resume), 8 built-in evaluators, configurable loop intervals (10min to monthly).", "version": "2.9.0", "author": { "name": "Alireza Rezvani" @@ -501,7 +501,7 @@ { "name": "agenthub", "source": "./engineering/agenthub", - "description": "Multi-agent collaboration — spawn N parallel subagents that compete on code optimization, content drafts, research approaches, or any task that benefits from diverse solutions. 7 slash commands (/hub:init, /hub:spawn, /hub:status, /hub:eval, /hub:merge, /hub:board, /hub:run), agent templates, DAG-based orchestration, LLM judge mode, message board coordination.", + "description": "Multi-agent collaboration — spawn N parallel subagents that compete on code optimization, content drafts, research approaches, or any task that benefits from diverse solutions. 7 slash commands (/hub:hub-init, /hub:spawn, /hub:hub-status, /hub:eval, /hub:merge, /hub:board, /hub:run), agent templates, DAG-based orchestration, LLM judge mode, message board coordination.", "version": "2.9.0", "author": { "name": "Alireza Rezvani" @@ -961,6 +961,27 @@ ], "category": "development" }, + { + "name": "memory-engineering", + "source": "./engineering/memory-engineering", + "description": "Engineer an agent's forgetting, not just its remembering. Four deterministic stdlib scripts implement the four lenses of agent memory: a cost profiler that splits construction from query spend and reports cost per correct answer (construction energy exceeds total query energy across 300 queries in the Stanford characterization); an architecture picker that scores the four paradigm families — long-context, flat RAG, structure-augmented RAG, agentic — disqualifies on hard constraints, names the cost the winning choice makes you pay, and refuses to pick when the top two tie; a density auditor that classifies every record in a memory directory or JSONL export as FACT / SKILL / LOG / PROSE, finds near-duplicates, and flags stale wording; and a forgetting-policy linter that fails any design with no forgetting rule. Ships cs-memory-engineer agent, /cs:memory-engineering and /cs:forgetting-audit commands, 4 references, and a seven-question forcing worksheet.", + "version": "2.11.2", + "author": { + "name": "Alireza Rezvani" + }, + "keywords": [ + "agent-memory", + "memory-engineering", + "forgetting-policy", + "context-engineering", + "rag", + "kv-cache", + "retention", + "write-path-cost", + "engineering" + ], + "category": "development" + }, { "name": "grill-me", "source": "./engineering/grill-me", @@ -1205,6 +1226,24 @@ ], "category": "productivity" }, + { + "name": "swedish-mentor", + "source": "./productivity/swedish-mentor", + "description": "CEFR-leveled Swedish-learning mentor: two-question placement probe, listening-first learning paths, vetted YouTube/podcast catalog (SFI, Radio Sweden pa latt svenska, Klartext), never-invent-a-URL rule.", + "version": "2.11.2", + "author": { + "name": "mh-mansouri" + }, + "keywords": [ + "productivity", + "language-learning", + "swedish", + "cefr", + "sfi", + "mentor" + ], + "category": "productivity" + }, { "name": "landing", "source": "./marketing/landing", @@ -1404,6 +1443,25 @@ ], "category": "research" }, + { + "name": "deepread", + "source": "./research/deepread", + "description": "Evidence-first reading of supplied documents. Five modes (quick/deep/map/feynman/book), claim-reason-evidence decomposition, confidence labels, evidence ledger, knowledge maps, Feynman teach-back.", + "version": "2.11.2", + "author": { + "name": "xiehuan123" + }, + "keywords": [ + "research", + "reading", + "deep-read", + "feynman", + "knowledge-map", + "evidence", + "comprehension" + ], + "category": "research" + }, { "name": "aeo", "source": "./marketing-skill/skills/aeo", @@ -1570,7 +1628,7 @@ { "name": "research-ops-skills", "source": "./research-ops", - "description": "Enterprise / cross-functional Research Operations domain — the managed counterpart to the academic research/ domain. v2.9.0 ships 5 skills: orchestrator (context: fork) + clinical-research (study design: protocol synopsis + endpoint selection + sample-size/power for means/proportions/survival + phase-gate feasibility) + research-finance (R&D program budgeting with F&A split + burn/runway + capitalize-vs-expense routing + portfolio ROI) + market-research (TAM/SAM/SOM computed both top-down and bottoms-up + survey sampling with FPC and per-segment minima + Kotler segmentation scoring) + product-research (goal-matched study design + method-based saturation with confidence + insight synthesis that flags single-source anecdotes). Hard rules: clinical outputs are estimates with a named clinical owner (never fact), finance outputs surface assumptions and route capex-vs-opex to a named finance owner (never auto-decide), market sizes show method + assumptions (never a single number), product insights require recurrence across independent participants. Each sub-skill ships per-skill onboarding questions (onboard.py), a customization config consumed by every tool, and an isolated opt-in autoresearch evaluator (ar_evaluator.py) bridging to engineering/autoresearch-agent. 24 stdlib Python tools (12 analysis + 12 onboarding/customization/autoresearch), 12 reference docs. Distinct from ra-qm-team (regulatory/QM submission), finance (corporate close/valuation), research/grants (funding discovery), product-team (persona/journey/live experiments), marketing-skill (campaign analytics).", + "description": "Enterprise / cross-functional Research Operations domain — the managed counterpart to the academic research/ domain. v2.9.0 ships 5 skills: orchestrator (context: fork), clinical-research (protocol synopsis, endpoint selection, sample-size/power for means/proportions/survival, phase-gate feasibility), research-finance (R&D budgeting with F&A split, burn/runway, capitalize-vs-expense routing, portfolio ROI), market-research (TAM/SAM/SOM top-down and bottoms-up, survey sampling with FPC, Kotler segmentation), and product-research (goal-matched study design, method-based saturation, insight synthesis flagging single-source anecdotes). Hard rules: outputs are estimates routed to a named clinical or finance owner, market sizes show method + assumptions, product insights require recurrence across independent participants. 24 stdlib Python tools, 12 reference docs. Distinct from ra-qm-team, finance, research/grants, product-team, and marketing-skill.", "version": "2.9.0", "author": { "name": "Alireza Rezvani" @@ -1617,7 +1675,7 @@ { "name": "markdown-html-skills", "source": "./markdown-html", - "description": "Convert long markdown files into world-class single-file interactive HTML — DOMAIN COMPLETE at v2.10.3 (5 skills). v2.10.3 adds md-slides — the slide-deck converter (arrow-key / Space / PgDn / Home / End / P keyboard navigation + presenter mode with split-view clock + speaker notes + next-slide preview + URL-hash deep linking like #3 + @media print page-per-slide for browser-native PDF export; reuses md-document's markdown parser; vanilla JS only; Prism.js opt-in via --syntax for code-heavy decks). Joins md-review (v2.10.2 code-review converter: 2-col diff + severity-tagged margin annotations + WCAG-1.4.1 badges + mandatory named reviewer footer), md-document (v2.10.1 long-form converter: sticky TOC + scrollspy + search + code-copy + Prism autoloader), markdown-html-orchestrator (v2.10.0 context: fork; deterministic doc-type classifier; refuses < 100 lines per Shihipar; refuses without onboarding), and design-system (v2.10.0 10-question onboarding wizard; WCAG-AA 12-token palette; project > global > defaults precedence; MARKDOWN_HTML_NO_CONFIG=1 bypass). 15 stdlib-only Python tools, 15 references citing 5-7 sources each, 4 template/schema assets. Inspired by Thariq Shihipar's Claude Code HTML output essay (Medium, 2026).", + "description": "Convert long markdown files into world-class single-file interactive HTML — DOMAIN COMPLETE at v2.10.3 (5 skills). v2.10.3 adds md-slides, the slide-deck converter (arrow/Space/PgDn/Home/End/P navigation, presenter mode with clock + speaker notes + next-slide preview, URL-hash deep linking, @media print page-per-slide for browser-native PDF export; vanilla JS only; Prism.js opt-in via --syntax). Joins md-review (v2.10.2 code-review converter: 2-col diff, severity-tagged margin annotations, WCAG-1.4.1 badges, named reviewer footer), md-document (v2.10.1 long-form: sticky TOC, scrollspy, search, code-copy, Prism autoloader), markdown-html-orchestrator (v2.10.0 context: fork; deterministic doc-type classifier), and design-system (v2.10.0 onboarding wizard; WCAG-AA 12-token palette). 15 stdlib-only Python tools, 15 references, 4 template assets. Inspired by Thariq Shihipar's Claude Code HTML output essay.", "version": "2.10.3", "author": { "name": "Alireza Rezvani" diff --git a/.claude/commands/focused-fix.md b/.claude/commands/focused-fix.md index 0f15a49c..db1b0614 100644 --- a/.claude/commands/focused-fix.md +++ b/.claude/commands/focused-fix.md @@ -1,5 +1,5 @@ --- -description: Deep-dive feature repair — systematically fix an entire feature/module. Usage: /focused-fix +description: "Deep-dive feature repair — systematically fix an entire feature/module. Usage: /focused-fix " --- Systematically repair the feature/module at `$ARGUMENTS` using the focused-fix 5-phase protocol. diff --git a/.codex/skills-index.json b/.codex/skills-index.json index 64af8bbc..41e50ea2 100644 --- a/.codex/skills-index.json +++ b/.codex/skills-index.json @@ -3,7 +3,7 @@ "name": "claude-code-skills", "description": "Production-ready skill packages for AI agents - Marketing, Engineering, Product, C-Level, PM, and RA/QM", "repository": "https://github.com/alirezarezvani/claude-skills", - "total_skills": 361, + "total_skills": 346, "skills": [ { "name": "business-growth-skills", @@ -113,48 +113,12 @@ "category": "c-level", "description": "Board meeting preparation for the adversarial scenario, not the friendly one. Forces numbers-cold mastery, anticipates hard questions, builds a narrative that acknowledges weakness without losing the room. Use when preparing for a board meeting, an investor update, fundraising presentation, or any high-stakes adversarial review where every number must live in your head not just on a slide." }, - { - "name": "boardroom", - "source": "../../c-level-advisor/c-level-agents/skills/boardroom", - "category": "c-level", - "description": "/cs:boardroom \u2014 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo. Use when a decision spans multiple executive domains \u2014 e.g. a pricing change touching finance, positioning, and product, or a raise-vs-cut runway call." - }, - { - "name": "brief", - "source": "../../c-level-advisor/c-level-agents/skills/brief", - "category": "c-level", - "description": "/cs:brief \u2014 Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline. Use when a strategic question needs to be framed before boardroom deliberation \u2014 e.g. locking options, assumptions, and success criteria for a pricing change or a market-entry decision." - }, - { - "name": "c-level-agents", - "source": "../../c-level-advisor/c-level-agents/skills/c-level-agents", - "category": "c-level", - "description": "Founder-mode executive team. 13 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, GC, CDO, CAIO, CCO, VPE, Chief of Staff) and 21 /cs:* slash commands for forcing-question office hours, multi-role boardroom deliberation, strategic sprint pipeline, and meta routing. Use when the founder needs a virtual executive team, when invoking /cs:* commands, or when orchestrating multi-role decisions." - }, { "name": "c-level-skills", "source": "../../c-level-advisor/skills/c-level-skills", "category": "c-level", "description": "Index and router for the C-level advisory bundle: 33 skills covering 14 C-suite roles, orchestration, cross-cutting capabilities, and culture. Use when exploring what the c-level-advisor bundle contains, deciding which advisor skill fits a question, or finding the entry points (cs-onboard interview, chief-of-staff routing, board-meeting protocol)." }, - { - "name": "caio-review", - "source": "../../c-level-advisor/c-level-agents/skills/caio-review", - "category": "c-level", - "description": "/cs:caio-review \u2014 Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring. Use when shipping an AI feature without an eval set, choosing between API, fine-tune, and self-hosted, or classifying a use case under the EU AI Act." - }, - { - "name": "cco-review", - "source": "../../c-level-advisor/c-level-agents/skills/cco-review", - "category": "c-level", - "description": "/cs:cco-review \u2014 Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring. Use when gross retention is slipping, before approving CSM headcount, or when deciding which customer segments to keep or fire." - }, - { - "name": "cdo-review", - "source": "../../c-level-advisor/c-level-agents/skills/cdo-review", - "category": "c-level", - "description": "/cs:cdo-review \u2014 Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring. Use when validating training-data rights before model work, choosing warehouse vs lakehouse vs mesh, or valuing data assets for productization or M&A." - }, { "name": "ceo-advisor", "source": "../../c-level-advisor/skills/ceo-advisor", @@ -167,12 +131,6 @@ "category": "c-level", "description": "Financial leadership for startups and scaling companies. Financial modeling, unit economics, fundraising strategy, cash management, and board financial packages. Use when building financial models, analyzing unit economics, planning fundraising, managing cash runway, preparing board materials, or when user mentions CFO, burn rate, runway, fundraising, unit economics, LTV, CAC, term sheets, or financial strategy." }, - { - "name": "cfo-review", - "source": "../../c-level-advisor/c-level-agents/skills/cfo-review", - "category": "c-level", - "description": "/cs:cfo-review \u2014 Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation. Use when a plan commits meaningful spend \u2014 e.g. a hiring wave, a fundraise decision, or a new channel budget." - }, { "name": "challenge", "source": "../../c-level-advisor/executive-mentor/skills/challenge", @@ -239,24 +197,12 @@ "category": "c-level", "description": "Security leadership for growth-stage companies. Risk quantification in dollars, compliance roadmap (SOC 2/ISO 27001/HIPAA/GDPR), security architecture strategy, incident response leadership, and board-level security reporting. Use when building security programs, justifying security budget, selecting compliance frameworks, managing incidents, assessing vendor risk, or when user mentions CISO, security strategy, compliance roadmap, zero trust, or board security reporting." }, - { - "name": "ciso-review", - "source": "../../c-level-advisor/c-level-agents/skills/ciso-review", - "category": "c-level", - "description": "/cs:ciso-review \u2014 Risk-paranoid interrogation of any plan that touches data, compliance, or production access. Use when launching features that handle customer data, before a SOC 2 / ISO audit, or after any incident or near-miss." - }, { "name": "cmo-advisor", "source": "../../c-level-advisor/skills/cmo-advisor", "category": "c-level", "description": "Marketing leadership for scaling companies. Brand positioning, growth model design, marketing budget allocation, and marketing org design. Use when designing brand strategy, selecting growth models (PLG vs sales-led vs community-led), allocating marketing budgets, building marketing teams, or when user mentions CMO, brand strategy, growth model, CAC, LTV, channel mix, or marketing ROI." }, - { - "name": "cmo-review", - "source": "../../c-level-advisor/c-level-agents/skills/cmo-review", - "category": "c-level", - "description": "/cs:cmo-review \u2014 Narrative-first interrogation of positioning, ICP, message house, and channel mix. Use when launching a campaign or repositioning, or when CAC is rising and the one-sentence positioning test fails." - }, { "name": "company-os", "source": "../../c-level-advisor/skills/company-os", @@ -287,30 +233,12 @@ "category": "c-level", "description": "Product leadership for scaling companies. Product vision, portfolio strategy, product-market fit, and product org design. Use when setting product vision, managing a product portfolio, measuring PMF, designing product teams, prioritizing at the portfolio level, reporting to the board on product, or when user mentions CPO, product strategy, product-market fit, product organization, portfolio prioritization, or roadmap strategy." }, - { - "name": "cpo-review", - "source": "../../c-level-advisor/c-level-agents/skills/cpo-review", - "category": "c-level", - "description": "/cs:cpo-review \u2014 JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus. Use when committing a quarter's roadmap, deciding whether to kill a feature, or claiming PMF without a retention curve." - }, { "name": "cro-advisor", "source": "../../c-level-advisor/skills/cro-advisor", "category": "c-level", "description": "Revenue leadership for B2B SaaS companies. Revenue forecasting, sales model design, pricing strategy, net revenue retention, and sales team scaling. Use when designing the revenue engine, setting quotas, modeling NRR, evaluating pricing, building board forecasts, or when user mentions CRO, chief revenue officer, revenue strategy, sales model, ARR growth, NRR, expansion revenue, churn, pricing strategy, or sales capacity." }, - { - "name": "cro-review", - "source": "../../c-level-advisor/c-level-agents/skills/cro-review", - "category": "c-level", - "description": "/cs:cro-review \u2014 Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time. Use when the forecast misses pipeline coverage, win rates drop, or before scaling the sales team." - }, - { - "name": "cross-eval", - "source": "../../c-level-advisor/c-level-agents/skills/cross-eval", - "category": "c-level", - "description": "/cs:cross-eval \u2014 Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation. Use when a high-stakes memo needs an independent sanity check before the boardroom \u2014 e.g. a bet-the-company pivot or fundraise terms." - }, { "name": "cs-onboard", "source": "../../c-level-advisor/skills/cs-onboard", @@ -323,36 +251,18 @@ "category": "c-level", "description": "Technical leadership guidance for engineering teams, architecture decisions, and technology strategy. Use when assessing technical debt, scaling engineering teams, evaluating technologies, making architecture decisions, establishing engineering metrics, or when user mentions CTO, tech debt, technical debt, team scaling, architecture decisions, technology evaluation, engineering metrics, DORA metrics, or technology strategy." }, - { - "name": "cto-review", - "source": "../../c-level-advisor/c-level-agents/skills/cto-review", - "category": "c-level", - "description": "/cs:cto-review \u2014 Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy. Use when committing to an architecture, planning for 10x load, or weighing a rebuild against a vendor." - }, { "name": "culture-architect", "source": "../../c-level-advisor/skills/culture-architect", "category": "c-level", "description": "Build, measure, and evolve company culture as operational behavior \u2014 not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code." }, - { - "name": "decide", - "source": "../../c-level-advisor/c-level-agents/skills/decide", - "category": "c-level", - "description": "/cs:decide \u2014 Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference. Use when the founder has approved a boardroom memo and the decision must become durable company memory \u2014 e.g. right after /cs:boardroom concludes." - }, { "name": "decision-logger", "source": "../../c-level-advisor/skills/decision-logger", "category": "c-level", "description": "Two-layer memory architecture for board meeting decisions. Manages raw transcripts (Layer 1) and approved decisions (Layer 2). Use when logging decisions after a board meeting, reviewing past decisions with /cs:decisions, or checking overdue action items with /cs:review. Invoked automatically by the board-meeting skill after Phase 5 founder approval." }, - { - "name": "execute", - "source": "../../c-level-advisor/c-level-agents/skills/execute", - "category": "c-level", - "description": "/cs:execute \u2014 Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision. Use when a logged decision needs to become an operating plan \u2014 e.g. turning an approved market-entry call into weekly milestones with DRIs." - }, { "name": "executive-mentor", "source": "../../c-level-advisor/executive-mentor/skills/executive-mentor", @@ -365,24 +275,6 @@ "category": "c-level", "description": "Personal leadership development for founders and first-time CEOs. Covers founder archetype identification, delegation frameworks, energy management, CEO calendar audits, leadership style evolution, blind spot identification, imposter syndrome, founder mental health, and succession planning. Use when a founder feels like the bottleneck, struggles to delegate, is burning out, transitioning from IC to executive, managing a board, or when user mentions founder mode, CEO growth, leadership development, delegation, burnout, or imposter syndrome." }, - { - "name": "founder-mode", - "source": "../../c-level-advisor/c-level-agents/skills/founder-mode", - "category": "c-level", - "description": "/cs:founder-mode \u2014 Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point. Use when a founder asks any strategic question without knowing which advisor or command fits \u2014 e.g. 'runway pressure' routes to the CFO, 'gross retention dropped' routes to the CCO." - }, - { - "name": "freeze", - "source": "../../c-level-advisor/c-level-agents/skills/freeze", - "category": "c-level", - "description": "/cs:freeze \u2014 Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer. Use when an irreversible decision was made under pressure \u2014 e.g. a layoff plan or multi-year contract \u2014 and deserves a cooling-off lock before execution." - }, - { - "name": "gc-review", - "source": "../../c-level-advisor/c-level-agents/skills/gc-review", - "category": "c-level", - "description": "/cs:gc-review \u2014 General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface. Use when reviewing a term sheet before signing, redlining a customer MSA, or checking IP assignment and regulatory exposure on a new product." - }, { "name": "general-counsel-advisor", "source": "../../c-level-advisor/skills/general-counsel-advisor", @@ -419,30 +311,12 @@ "category": "c-level", "description": "M&A strategy for acquiring companies or being acquired. Due diligence, valuation, integration, and deal structure. Use when evaluating acquisitions, preparing for acquisition, M&A due diligence, integration planning, or deal negotiation." }, - { - "name": "office-hours", - "source": "../../c-level-advisor/c-level-agents/skills/office-hours", - "category": "c-level", - "description": "/cs:office-hours \u2014 YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit. Use when a founder question is too vague to route \u2014 e.g. 'should we grow faster?' \u2014 or before drafting a strategy brief." - }, - { - "name": "onboard", - "source": "../../c-level-advisor/c-level-agents/skills/onboard", - "category": "c-level", - "description": "/cs:onboard \u2014 Founder interview that populates ~/.claude/company-context.md using the canonical 7-dimension cs-onboard schema. The first command to run when starting with c-level-agents. Use when setting up the virtual C-suite for a new company, or when advisors lack company context \u2014 e.g. before a first /cs:boardroom or after a fundraise changes the numbers." - }, { "name": "org-health-diagnostic", "source": "../../c-level-advisor/skills/org-health-diagnostic", "category": "c-level", "description": "Cross-functional organizational health check combining signals from all C-suite roles. Scores 8 dimensions on a traffic-light scale with drill-down recommendations. Use when assessing overall company health, preparing for board reviews, identifying at-risk functions, or when user mentions org health, health check, or health dashboard." }, - { - "name": "post-mortem", - "source": "../../c-level-advisor/c-level-agents/skills/post-mortem", - "category": "c-level", - "description": "/cs:post-mortem \u2014 Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop. Use when a decision hits its 90-day review checkpoint or its kill criteria trigger \u2014 e.g. scoring last quarter's pricing change against its pre-committed success metrics." - }, { "name": "postmortem", "source": "../../c-level-advisor/executive-mentor/skills/postmortem", @@ -479,12 +353,6 @@ "category": "c-level", "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships." }, - { - "name": "vpe-review", - "source": "../../c-level-advisor/c-level-agents/skills/vpe-review", - "category": "c-level", - "description": "/cs:vpe-review \u2014 Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline. Use when cycle time balloons, DORA metrics slide, or before committing to an eng hiring wave or a reorg." - }, { "name": "channel-economics", "source": "../../commercial/skills/channel-economics", @@ -591,7 +459,7 @@ "name": "design-system", "source": "../../markdown-html/skills/design-system", "category": "documentation", - "description": "Captures the user's brand identity once via a 10-question onboarding wizard (primary/accent HEX + heading + body Google Fonts + design style editorial/technical/minimal/playful + default output directory + syntax theme + TOC behavior + optional logo/company), validates body-text and link contrast against WCAG 2.2 AA, derives 12 CSS custom properties in HSL space, and stores the result for every markdown-html converter to consume. Use before any markdown-html conversion. Triggers on first-run onboarding (\"set up the brand\", \"configure markdown-html\", \"run onboarding\"), on explicit reset (\"reset the design system\", \"re-onboard\"), and is checked by every converter via config_loader.py before rendering. Refuses to save if body-text contrast fails AA 4.5:1 or the output dir isn't writable. Precedence: project (./.markdown-html/) > global (~/.config/markdown-html/) > built-in defaults; MARKDOWN_HTML_NO_CONFIG=1 bypasses." + "description": "Captures the user's brand identity once via a 10-question onboarding wizard (primary/accent HEX + heading + body Google Fonts + design style editorial/technical/minimal/playful + default output directory + syntax theme + TOC behavior + optional logo/company), validates body-text and link contrast against WCAG 2.2 AA, derives 12 CSS custom properties in HSL space, and stores the result for every markdown-html converter to consume. Use before any markdown-html conversion. Triggers on first-run onboarding (\"set up the brand\", \"configure markdown-html\", \"run onboarding\"), on explicit reset (\"reset the design system\", \"re-onboard\"), and is checked by every converter via config_loader.py before rendering. Refuses to save if body-text contrast fails AA 4.5:1 or the output dir isn't writable. Precedence is project (./.markdown-html/) > global (~/.config/markdown-html/) > built-in defaults; MARKDOWN_HTML_NO_CONFIG=1 bypasses." }, { "name": "markdown-html-orchestrator", @@ -615,7 +483,7 @@ "name": "md-slides", "source": "../../markdown-html/skills/md-slides", "category": "documentation", - "description": "Converts a markdown deck (slides separated by `" + "description": "\"Converts a markdown deck (slides separated by `" }, { "name": "a11y-audit", @@ -677,6 +545,12 @@ "category": "engineering", "description": "Build complete transactional email systems: React Email templates, provider integration (Resend, Postmark, SendGrid, AWS SES), preview server, i18n support, dark mode, spam optimization, analytics tracking. Use when adding transactional email to a new product, migrating between email providers, refactoring legacy email templates for accessibility, or adding internationalization to existing templates." }, + { + "name": "embedded-iot-mentor", + "source": "../../engineering-team/skills/embedded-iot-mentor", + "category": "engineering", + "description": "Mentor for embedded and IoT hardware projects. Helps select MCUs, dev boards, and toolchains, decides where sensor readings end up (phone, PC, dashboard, or alert), and gives time/cost estimates and a phased build plan from breadboard MVP to production PCB. Use when the user mentions embedded, IoT, microcontroller, ESP32, STM32, Arduino, Raspberry Pi Pico, firmware, PCB, KiCad, EasyEDA, PlatformIO, MQTT, Home Assistant, ESPHome, Grafana, an IoT dashboard, seeing sensor data on a phone, or asks for hardware tool recommendations, project planning, or cost/time estimates for an electronics project." + }, { "name": "engineering-skills", "source": "../../engineering-team/skills/engineering-skills", @@ -731,12 +605,6 @@ "category": "engineering", "description": "Use when a security incident has been detected or declared and needs classification, triage, escalation path determination, and forensic evidence collection. Covers SEV1-SEV4 classification, false positive filtering, incident taxonomy, and NIST SP 800-61 lifecycle." }, - { - "name": "init", - "source": "../../engineering-team/playwright-pro/skills/init", - "category": "engineering", - "description": ">-" - }, { "name": "memory-review", "source": "../../engineering-team/self-improving-agent/skills/memory-review", @@ -779,6 +647,18 @@ "category": "engineering", "description": "Production-grade Playwright testing toolkit. Use when the user mentions Playwright tests, end-to-end testing, browser automation, fixing flaky tests, test migration, CI/CD testing, or test suites. Generate tests, fix flaky failures, migrate from Cypress/Selenium, sync with TestRail, run on BrowserStack. 55 templates, 3 agents, smart reporting." }, + { + "name": "pw-init", + "source": "../../engineering-team/playwright-pro/skills/pw-init", + "category": "engineering", + "description": ">-" + }, + { + "name": "pw-review", + "source": "../../engineering-team/playwright-pro/skills/pw-review", + "category": "engineering", + "description": ">-" + }, { "name": "red-team", "source": "../../engineering-team/skills/red-team", @@ -797,12 +677,6 @@ "category": "engineering", "description": ">-" }, - { - "name": "review", - "source": "../../engineering-team/playwright-pro/skills/review", - "category": "engineering", - "description": ">-" - }, { "name": "security-pen-testing", "source": "../../engineering-team/skills/security-pen-testing", @@ -965,6 +839,18 @@ "category": "engineering-advanced", "description": "Use when the user asks to generate API tests, create integration test suites, test REST endpoints, or build contract tests." }, + { + "name": "ar-resume", + "source": "../../engineering/autoresearch-agent/skills/ar-resume", + "category": "engineering-advanced", + "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:ar-resume or asks to pick up a previously started autoresearch experiment." + }, + { + "name": "ar-status", + "source": "../../engineering/autoresearch-agent/skills/ar-status", + "category": "engineering-advanced", + "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going." + }, { "name": "autoresearch-agent", "source": "../../engineering/autoresearch-agent/skills/autoresearch-agent", @@ -989,6 +875,12 @@ "category": "engineering-advanced", "description": "Converts books, documentation folders, and source collections (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into structured agent skills \u2014 extracting named frameworks, principles, techniques, and anti-patterns into a master SKILL.md plus on-demand chapter files, a glossary, a patterns file, and a decision cheatsheet. Use when the user wants to study a document with an agent, apply an author's frameworks while working, turn internal docs or standards into a reusable knowledge base, or package a compiled book skill as a claude-skills plugin." }, + { + "name": "boost-asio-pro", + "source": "../../engineering/boost-asio-pro", + "category": "engineering-advanced", + "description": "Use when writing or reviewing asynchronous C++ networking code with Boost.Asio or standalone Asio \u2014 TCP/UDP servers and clients, SSL/TLS, timers, strands, io_context, co_spawn, awaitable, async_read/async_write, asio::spawn, yield_context, or pre-C++20 completion-handler callbacks." + }, { "name": "browser-automation", "source": "../../engineering/skills/browser-automation", @@ -1158,10 +1050,16 @@ "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw \u2014 chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test." }, { - "name": "init", - "source": "../../engineering/agenthub/skills/init", + "name": "hub-init", + "source": "../../engineering/agenthub/skills/hub-init", "category": "engineering-advanced", - "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:init or asks to start a multi-agent competition on a task." + "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:hub-init or asks to start a multi-agent competition on a task." + }, + { + "name": "hub-status", + "source": "../../engineering/agenthub/skills/hub-status", + "category": "engineering-advanced", + "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:hub-status or asks how the AgentHub agents are doing." }, { "name": "interview-system-designer", @@ -1211,6 +1109,12 @@ "category": "engineering-advanced", "description": "Design and ship production-ready MCP (Model Context Protocol) servers from OpenAPI contracts instead of hand-written tool wrappers. Python and TypeScript support, schema validation, safe evolution. Use when exposing an existing API as an MCP server, building tool integrations for Claude or Codex or Cursor, or scaffolding an MCP project from scratch." }, + { + "name": "memory-engineering", + "source": "../../engineering/memory-engineering/skills/memory-engineering", + "category": "engineering-advanced", + "description": "Use when designing, reviewing, or paying for an agent memory system \u2014 adding memory to an agent, choosing between long-context / RAG / graph / agentic memory, auditing what a CLAUDE.md or memory directory actually holds, deciding what to keep and what to expire, or when a memory store keeps growing and nobody has said what leaves it. Prices the write path, picks which cost to pay, classifies records as facts / skills / logs, and refuses a design that has no forgetting policy." + }, { "name": "merge", "source": "../../engineering/agenthub/skills/merge", @@ -1266,10 +1170,10 @@ "description": "Use when the user asks to design a RAG pipeline, choose a chunking strategy or embedding model, pick a vector database, or evaluate retrieval quality (precision@k, recall@k, NDCG). Examples: 'design a RAG system for our docs', 'what chunk size should I use for this corpus', 'evaluate my retriever against ground truth'. NOT for general LLM cost tuning (use llm-cost-optimizer) or agent loops over retrieval (use agenthub)." }, { - "name": "resume", - "source": "../../engineering/autoresearch-agent/skills/resume", + "name": "run", + "source": "../../engineering/agenthub/skills/run", "category": "engineering-advanced", - "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:resume or asks to pick up a previously started autoresearch experiment." + "description": "One-shot lifecycle command that chains init \u2192 baseline \u2192 spawn \u2192 eval \u2192 merge in a single invocation. Use when the user runs /hub:run or asks to execute a full AgentHub competition end-to-end." }, { "name": "run", @@ -1277,12 +1181,6 @@ "category": "engineering-advanced", "description": "Run a single experiment iteration. Edit the target file, evaluate, keep or discard. Use when the user runs /ar:run or asks for one manual autoresearch iteration." }, - { - "name": "run", - "source": "../../engineering/agenthub/skills/run", - "category": "engineering-advanced", - "description": "One-shot lifecycle command that chains init \u2192 baseline \u2192 spawn \u2192 eval \u2192 merge in a single invocation. Use when the user runs /hub:run or asks to execute a full AgentHub competition end-to-end." - }, { "name": "runbook-generator", "source": "../../engineering/skills/runbook-generator", @@ -1373,18 +1271,6 @@ "category": "engineering-advanced", "description": "Run hypothesis tests, analyze A/B experiment results, calculate sample sizes, and interpret statistical significance with effect sizes. Use when you need to validate whether observed differences are real, size an experiment correctly before launch, or interpret test results with confidence." }, - { - "name": "status", - "source": "../../engineering/autoresearch-agent/skills/status", - "category": "engineering-advanced", - "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:status or asks how an autoresearch experiment is going." - }, - { - "name": "status", - "source": "../../engineering/agenthub/skills/status", - "category": "engineering-advanced", - "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:status or asks how the AgentHub agents are doing." - }, { "name": "strict-api", "source": "../../engineering/strict-api", @@ -1457,6 +1343,12 @@ "category": "finance", "description": "SaaS financial health advisor. Use when a user shares revenue or customer numbers, or mentions ARR, MRR, churn, LTV, CAC, NRR, or asks how their SaaS business is doing." }, + { + "name": "stock-analysis", + "source": "../../finance/skills/stock-analysis", + "category": "finance", + "description": "Produce a rigorous, sector-relative, multi-factor fundamental analysis of a publicly listed company \u2014 Indian (NSE/BSE) or US/global. Use this skill whenever the user asks to analyse, research, evaluate, value, or \"look into\" a stock, ticker, or listed company; asks whether a business is fundamentally strong or weak, cheap or expensive; asks to compare two or more companies or benchmark one against its sector; mentions metrics like OPM, ROCE, ROE, ROIC, P/E, EV/EBITDA, free cash flow, NIM, GNPA, CASA, promoter holding or pledging; or shares an annual report, 10-K, concall transcript, or screener page and wants it interpreted. Use it too for accounting-quality and forensic questions \u2014 \"is the profit real\", \"are they cooking the books\", \"the cash flow doesn't match the profit\", \"why is profit rising but cash isn't\", \"should I worry about this company's accounting\", auditor qualifications, promoter pledging, or related-party concerns \u2014 which route to the forensic-only mode. Use it for **IPOs and not-yet-listed companies** too \u2014 \"should I apply to this IPO\", \"is this IPO worth it\", \"is the price band expensive\", DRHP/RHP or S-1 questions, grey market premium, anchor allotment, lock-in expiry \u2014 which route to the IPO mode. Use it even when the request sounds casual (\"is Infosys any good?\", \"thoughts on HDFC Bank?\", \"why is this company's margin so low?\"). Do not use it for personalised investment advice, portfolio allocation, or trading signals." + }, { "name": "ab-test-setup", "source": "../../marketing-skill/skills/ab-test-setup", @@ -1493,6 +1385,12 @@ "category": "marketing", "description": "When the user wants to apply, document, or enforce brand guidelines for any product or company. Also use when the user mentions 'brand guidelines,' 'brand colors,' 'typography,' 'logo usage,' 'brand voice,' 'visual identity,' 'tone of voice,' 'brand standards,' 'style guide,' 'brand consistency,' or 'company design standards.' Covers color systems, typography, logo rules, imagery guidelines, and tone matrix for any brand \u2014 including Anthropic's official identity." }, + { + "name": "business-name-fit", + "source": "../../marketing-skill/skills/business-name-fit", + "category": "marketing", + "description": "Suggest, pick, or vet a business, startup, or product name that stays true to the founder's cultural origin while working professionally in the markets they want to sell into. Use whenever someone is naming a company, brand, or product and cares about how it lands across languages and regions \u2014 for example a name that sounds right at home but might read oddly to English speakers, or an authentic name they want to check before committing. Trigger this for any request about choosing a business name, checking if a name \"works\" abroad, spotting bad meanings in other languages, or making a name sound trustworthy in a specific market \u2014 even if the person doesn't say the word \"skill\"." + }, { "name": "campaign-analytics", "source": "../../marketing-skill/skills/campaign-analytics", @@ -1913,6 +1811,12 @@ "category": "productivity", "description": "Use when someone asks to roast an idea, pressure-test or stress-test an idea, validate a business idea, \"convene the panel\", get a brutal second opinion before building something, or says \"/roast\". Spins up a 5-angle panel (Critic, Champion, Analyst, Investigator, Customer) that attacks the idea from every angle, then a Judge returns one GO / RESHAPE / KILL verdict with the cheapest test to de-risk it." }, + { + "name": "swedish-mentor", + "source": "../../productivity/swedish-mentor", + "category": "productivity", + "description": "Mentor Swedish language learners by selecting YouTube video clips and podcast episodes by CEFR level and skill (listening, reading, writing, speaking), and building a simple learning path. Use when the user asks about a Swedish learning path, YouTube clips or podcasts for Swedish, SFI videos, level assessment for svenska, or requests for Peter SFI / L\u00e4tt Svenska med Oskar / Radio Sweden p\u00e5 l\u00e4tt svenska / Klartext-style recommendations." + }, { "name": "weekly-review", "source": "../../productivity/weekly-review/skills/weekly-review", @@ -2099,6 +2003,12 @@ "category": "research", "description": "Decision-grade entity research skill \u2014 produces a hypothesis-tested dossier on a specific company, person, nonprofit, or government org, not a generic profile. Forcing intake makes the user state their hypothesis upfront (what they already believe and want to verify or disprove) so the dossier tests it rather than confirms it. Output is an editable Word document (.docx) with verdict on the hypothesis, identity facts, 12-month activity timeline, network and reputation signals, red flags, conversation hooks tied to specific findings, and source-provenance audit log. Uses WebSearch + WebFetch + free APIs (SEC EDGAR, GitHub, ProPublica) as workhorses; optional BYOK MCPs enhance coverage. Use when the user asks for background research, diligence, or meeting prep on a specific entity (e.g., 'prep me for a meeting with [person/company]', 'due diligence on [company]'). Honors sensitivity exclusions for journalism + personal-vetting contexts." }, + { + "name": "dsh-deepread", + "source": "../../research/dsh-deepread", + "category": "research", + "description": "Use when the user asks to deeply read a book, article, PDF, or document set; extract claims and evidence; build a knowledge map; or learn through Feynman explanation and recall. Covers quick, deep, map, Feynman, and whole-book reading modes." + }, { "name": "grants", "source": "../../research/grants/skills/grants", @@ -2184,7 +2094,7 @@ "description": "Internal BizOps skills (v2.8.0): process mapping, vendor management, capacity planning (Erlang-C), internal comms (ADKAR+Kotter), knowledge ops (SOP+runbook), procurement (UNSPSC)" }, "c-level": { - "count": 68, + "count": 46, "source": "../../c-level-advisor", "description": "Executive leadership and advisory skills" }, @@ -2204,22 +2114,22 @@ "description": "Markdown-to-HTML converter (v2.10.0 foundation): orchestrator (context: fork, deterministic doctype classifier, refuses < 100 lines per Shihipar) + design-system (one-time onboarding wizard with WCAG-AA-validated 12-token palette, project > global > defaults precedence). Converter sub-skills (md-document, md-review, md-slides) land in v2.10.1." }, "engineering": { - "count": 52, + "count": 53, "source": "../../engineering-team", "description": "Software engineering and technical skills" }, "engineering-advanced": { - "count": 84, + "count": 86, "source": "../../engineering", "description": "Advanced engineering skills - agents, RAG, MCP, CI/CD, databases, observability" }, "finance": { - "count": 4, + "count": 5, "source": "../../finance", "description": "Financial analysis, valuation, and forecasting skills" }, "marketing": { - "count": 49, + "count": 50, "source": "../../marketing-skill", "description": "Marketing, content, and demand generation skills" }, @@ -2229,7 +2139,7 @@ "description": "Product management and design skills" }, "productivity": { - "count": 11, + "count": 12, "source": "../../productivity", "description": "Personal-productivity skills - capture, email, reflect, handoff, andreessen, roast, weekly-review, deep-work, meetings" }, @@ -2244,7 +2154,7 @@ "description": "Regulatory affairs and quality management skills" }, "research": { - "count": 9, + "count": 10, "source": "../../research", "description": "Research orchestrator + 6 specialists (pulse, litreview, grants, dossier, patent, syllabus, notebooklm)" }, diff --git a/.codex/skills/ar-resume b/.codex/skills/ar-resume new file mode 120000 index 00000000..5ca61fb2 --- /dev/null +++ b/.codex/skills/ar-resume @@ -0,0 +1 @@ +../../engineering/autoresearch-agent/skills/ar-resume \ No newline at end of file diff --git a/.codex/skills/ar-status b/.codex/skills/ar-status new file mode 120000 index 00000000..51dab228 --- /dev/null +++ b/.codex/skills/ar-status @@ -0,0 +1 @@ +../../engineering/autoresearch-agent/skills/ar-status \ No newline at end of file diff --git a/.codex/skills/boardroom b/.codex/skills/boardroom index 0da036e7..348d04b2 120000 --- a/.codex/skills/boardroom +++ b/.codex/skills/boardroom @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/boardroom \ No newline at end of file +../../c-level-agents/skills/boardroom \ No newline at end of file diff --git a/.codex/skills/boost-asio-pro b/.codex/skills/boost-asio-pro new file mode 120000 index 00000000..268fcb8a --- /dev/null +++ b/.codex/skills/boost-asio-pro @@ -0,0 +1 @@ +../../engineering/boost-asio-pro \ No newline at end of file diff --git a/.codex/skills/brief b/.codex/skills/brief index 09b1c771..7a2ad08f 120000 --- a/.codex/skills/brief +++ b/.codex/skills/brief @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/brief \ No newline at end of file +../../c-level-agents/skills/brief \ No newline at end of file diff --git a/.codex/skills/business-name-fit b/.codex/skills/business-name-fit new file mode 120000 index 00000000..c7fde415 --- /dev/null +++ b/.codex/skills/business-name-fit @@ -0,0 +1 @@ +../../marketing-skill/skills/business-name-fit \ No newline at end of file diff --git a/.codex/skills/c-level-agents b/.codex/skills/c-level-agents index 1ab66539..4bd7bd19 120000 --- a/.codex/skills/c-level-agents +++ b/.codex/skills/c-level-agents @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/c-level-agents \ No newline at end of file +../../c-level-agents/skills/c-level-agents \ No newline at end of file diff --git a/.codex/skills/caio-review b/.codex/skills/caio-review index 5be69c44..5877e4d1 120000 --- a/.codex/skills/caio-review +++ b/.codex/skills/caio-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/caio-review \ No newline at end of file +../../c-level-agents/skills/caio-review \ No newline at end of file diff --git a/.codex/skills/cco-review b/.codex/skills/cco-review index 30936ce9..79645059 120000 --- a/.codex/skills/cco-review +++ b/.codex/skills/cco-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cco-review \ No newline at end of file +../../c-level-agents/skills/cco-review \ No newline at end of file diff --git a/.codex/skills/cdo-review b/.codex/skills/cdo-review index e95de5c0..3f5545bd 120000 --- a/.codex/skills/cdo-review +++ b/.codex/skills/cdo-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cdo-review \ No newline at end of file +../../c-level-agents/skills/cdo-review \ No newline at end of file diff --git a/.codex/skills/cfo-review b/.codex/skills/cfo-review index dc55a9bd..d43d6017 120000 --- a/.codex/skills/cfo-review +++ b/.codex/skills/cfo-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cfo-review \ No newline at end of file +../../c-level-agents/skills/cfo-review \ No newline at end of file diff --git a/.codex/skills/ciso-review b/.codex/skills/ciso-review index 0297a2a0..6887cc32 120000 --- a/.codex/skills/ciso-review +++ b/.codex/skills/ciso-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/ciso-review \ No newline at end of file +../../c-level-agents/skills/ciso-review \ No newline at end of file diff --git a/.codex/skills/cmo-review b/.codex/skills/cmo-review index ed4811d5..008ce664 120000 --- a/.codex/skills/cmo-review +++ b/.codex/skills/cmo-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cmo-review \ No newline at end of file +../../c-level-agents/skills/cmo-review \ No newline at end of file diff --git a/.codex/skills/cpo-review b/.codex/skills/cpo-review index 3dc1102a..7ff39caf 120000 --- a/.codex/skills/cpo-review +++ b/.codex/skills/cpo-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cpo-review \ No newline at end of file +../../c-level-agents/skills/cpo-review \ No newline at end of file diff --git a/.codex/skills/cro-review b/.codex/skills/cro-review index ff1f6230..dda329be 120000 --- a/.codex/skills/cro-review +++ b/.codex/skills/cro-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cro-review \ No newline at end of file +../../c-level-agents/skills/cro-review \ No newline at end of file diff --git a/.codex/skills/cross-eval b/.codex/skills/cross-eval index c79020ee..83119149 120000 --- a/.codex/skills/cross-eval +++ b/.codex/skills/cross-eval @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cross-eval \ No newline at end of file +../../c-level-agents/skills/cross-eval \ No newline at end of file diff --git a/.codex/skills/cto-review b/.codex/skills/cto-review index 52caef5b..d3abf6d4 120000 --- a/.codex/skills/cto-review +++ b/.codex/skills/cto-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/cto-review \ No newline at end of file +../../c-level-agents/skills/cto-review \ No newline at end of file diff --git a/.codex/skills/decide b/.codex/skills/decide index 2db83744..6426b5df 120000 --- a/.codex/skills/decide +++ b/.codex/skills/decide @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/decide \ No newline at end of file +../../c-level-agents/skills/decide \ No newline at end of file diff --git a/.codex/skills/dsh-deepread b/.codex/skills/dsh-deepread new file mode 120000 index 00000000..22377845 --- /dev/null +++ b/.codex/skills/dsh-deepread @@ -0,0 +1 @@ +../../research/dsh-deepread \ No newline at end of file diff --git a/.codex/skills/embedded-iot-mentor b/.codex/skills/embedded-iot-mentor new file mode 120000 index 00000000..9bd23de7 --- /dev/null +++ b/.codex/skills/embedded-iot-mentor @@ -0,0 +1 @@ +../../engineering-team/skills/embedded-iot-mentor \ No newline at end of file diff --git a/.codex/skills/execute b/.codex/skills/execute index b6398532..8dd0f0b1 120000 --- a/.codex/skills/execute +++ b/.codex/skills/execute @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/execute \ No newline at end of file +../../c-level-agents/skills/execute \ No newline at end of file diff --git a/.codex/skills/founder-mode b/.codex/skills/founder-mode index 90a6223e..4fa506b7 120000 --- a/.codex/skills/founder-mode +++ b/.codex/skills/founder-mode @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/founder-mode \ No newline at end of file +../../c-level-agents/skills/founder-mode \ No newline at end of file diff --git a/.codex/skills/freeze b/.codex/skills/freeze index b100d841..4ff428da 120000 --- a/.codex/skills/freeze +++ b/.codex/skills/freeze @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/freeze \ No newline at end of file +../../c-level-agents/skills/freeze \ No newline at end of file diff --git a/.codex/skills/gc-review b/.codex/skills/gc-review index 2a8791d2..698f9aa1 120000 --- a/.codex/skills/gc-review +++ b/.codex/skills/gc-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/gc-review \ No newline at end of file +../../c-level-agents/skills/gc-review \ No newline at end of file diff --git a/.codex/skills/hub-init b/.codex/skills/hub-init new file mode 120000 index 00000000..1e9056ba --- /dev/null +++ b/.codex/skills/hub-init @@ -0,0 +1 @@ +../../engineering/agenthub/skills/hub-init \ No newline at end of file diff --git a/.codex/skills/hub-status b/.codex/skills/hub-status new file mode 120000 index 00000000..cbfcd0fc --- /dev/null +++ b/.codex/skills/hub-status @@ -0,0 +1 @@ +../../engineering/agenthub/skills/hub-status \ No newline at end of file diff --git a/.codex/skills/init b/.codex/skills/init deleted file mode 120000 index 00a9cc12..00000000 --- a/.codex/skills/init +++ /dev/null @@ -1 +0,0 @@ -../../engineering/agenthub/skills/init \ No newline at end of file diff --git a/.codex/skills/memory-engineering b/.codex/skills/memory-engineering new file mode 120000 index 00000000..aa7f60b0 --- /dev/null +++ b/.codex/skills/memory-engineering @@ -0,0 +1 @@ +../../engineering/memory-engineering/skills/memory-engineering \ No newline at end of file diff --git a/.codex/skills/office-hours b/.codex/skills/office-hours index 04c67a57..2193b3a7 120000 --- a/.codex/skills/office-hours +++ b/.codex/skills/office-hours @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/office-hours \ No newline at end of file +../../c-level-agents/skills/office-hours \ No newline at end of file diff --git a/.codex/skills/onboard b/.codex/skills/onboard index 6e0a7b6d..42277c77 120000 --- a/.codex/skills/onboard +++ b/.codex/skills/onboard @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/onboard \ No newline at end of file +../../c-level-agents/skills/onboard \ No newline at end of file diff --git a/.codex/skills/post-mortem b/.codex/skills/post-mortem index 4aeef7c9..e4475489 120000 --- a/.codex/skills/post-mortem +++ b/.codex/skills/post-mortem @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/post-mortem \ No newline at end of file +../../c-level-agents/skills/post-mortem \ No newline at end of file diff --git a/.codex/skills/pw-init b/.codex/skills/pw-init new file mode 120000 index 00000000..529a4e6a --- /dev/null +++ b/.codex/skills/pw-init @@ -0,0 +1 @@ +../../engineering-team/playwright-pro/skills/pw-init \ No newline at end of file diff --git a/.codex/skills/pw-review b/.codex/skills/pw-review new file mode 120000 index 00000000..0eb09595 --- /dev/null +++ b/.codex/skills/pw-review @@ -0,0 +1 @@ +../../engineering-team/playwright-pro/skills/pw-review \ No newline at end of file diff --git a/.codex/skills/resume b/.codex/skills/resume deleted file mode 120000 index d3e3d951..00000000 --- a/.codex/skills/resume +++ /dev/null @@ -1 +0,0 @@ -../../engineering/autoresearch-agent/skills/resume \ No newline at end of file diff --git a/.codex/skills/review b/.codex/skills/review deleted file mode 120000 index 647ec915..00000000 --- a/.codex/skills/review +++ /dev/null @@ -1 +0,0 @@ -../../engineering-team/playwright-pro/skills/review \ No newline at end of file diff --git a/.codex/skills/run b/.codex/skills/run index 5a27dff7..2aff8ba0 120000 --- a/.codex/skills/run +++ b/.codex/skills/run @@ -1 +1 @@ -../../engineering/agenthub/skills/run \ No newline at end of file +../../engineering/autoresearch-agent/skills/run \ No newline at end of file diff --git a/.codex/skills/status b/.codex/skills/status deleted file mode 120000 index 01d19414..00000000 --- a/.codex/skills/status +++ /dev/null @@ -1 +0,0 @@ -../../engineering/agenthub/skills/status \ No newline at end of file diff --git a/.codex/skills/stock-analysis b/.codex/skills/stock-analysis new file mode 120000 index 00000000..6f553f2a --- /dev/null +++ b/.codex/skills/stock-analysis @@ -0,0 +1 @@ +../../finance/skills/stock-analysis \ No newline at end of file diff --git a/.codex/skills/swedish-mentor b/.codex/skills/swedish-mentor new file mode 120000 index 00000000..625a2684 --- /dev/null +++ b/.codex/skills/swedish-mentor @@ -0,0 +1 @@ +../../productivity/swedish-mentor \ No newline at end of file diff --git a/.codex/skills/vpe-review b/.codex/skills/vpe-review index 9878237e..ff74bced 120000 --- a/.codex/skills/vpe-review +++ b/.codex/skills/vpe-review @@ -1 +1 @@ -../../c-level-advisor/c-level-agents/skills/vpe-review \ No newline at end of file +../../c-level-agents/skills/vpe-review \ No newline at end of file diff --git a/.gemini/skills-index.json b/.gemini/skills-index.json index 7a4677ff..2b3f8002 100644 --- a/.gemini/skills-index.json +++ b/.gemini/skills-index.json @@ -1,7 +1,7 @@ { "version": "1.0.0", "name": "gemini-cli-skills", - "total_skills": 435, + "total_skills": 414, "skills": [ { "name": "README", @@ -258,41 +258,11 @@ "category": "c-level", "description": "Board meeting preparation for the adversarial scenario, not the friendly one. Forces numbers-cold mastery, anticipates hard questions, builds a narrative that acknowledges weakness without losing the room. Use when preparing for a board meeting, an investor update, fundraising presentation, or any high-stakes adversarial review where every number must live in your head not just on a slide." }, - { - "name": "boardroom", - "category": "c-level", - "description": "/cs:boardroom \u2014 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo. Use when a decision spans multiple executive domains \u2014 e.g. a pricing change touching finance, positioning, and product, or a raise-vs-cut runway call." - }, - { - "name": "brief", - "category": "c-level", - "description": "/cs:brief \u2014 Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline. Use when a strategic question needs to be framed before boardroom deliberation \u2014 e.g. locking options, assumptions, and success criteria for a pricing change or a market-entry decision." - }, - { - "name": "c-level-agents", - "category": "c-level", - "description": "Founder-mode executive team. 13 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, GC, CDO, CAIO, CCO, VPE, Chief of Staff) and 21 /cs:* slash commands for forcing-question office hours, multi-role boardroom deliberation, strategic sprint pipeline, and meta routing. Use when the founder needs a virtual executive team, when invoking /cs:* commands, or when orchestrating multi-role decisions." - }, { "name": "c-level-skills", "category": "c-level", "description": "Index and router for the C-level advisory bundle: 33 skills covering 14 C-suite roles, orchestration, cross-cutting capabilities, and culture. Use when exploring what the c-level-advisor bundle contains, deciding which advisor skill fits a question, or finding the entry points (cs-onboard interview, chief-of-staff routing, board-meeting protocol)." }, - { - "name": "caio-review", - "category": "c-level", - "description": "/cs:caio-review \u2014 Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring. Use when shipping an AI feature without an eval set, choosing between API, fine-tune, and self-hosted, or classifying a use case under the EU AI Act." - }, - { - "name": "cco-review", - "category": "c-level", - "description": "/cs:cco-review \u2014 Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring. Use when gross retention is slipping, before approving CSM headcount, or when deciding which customer segments to keep or fire." - }, - { - "name": "cdo-review", - "category": "c-level", - "description": "/cs:cdo-review \u2014 Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring. Use when validating training-data rights before model work, choosing warehouse vs lakehouse vs mesh, or valuing data assets for productization or M&A." - }, { "name": "ceo-advisor", "category": "c-level", @@ -303,11 +273,6 @@ "category": "c-level", "description": "Financial leadership for startups and scaling companies. Financial modeling, unit economics, fundraising strategy, cash management, and board financial packages. Use when building financial models, analyzing unit economics, planning fundraising, managing cash runway, preparing board materials, or when user mentions CFO, burn rate, runway, fundraising, unit economics, LTV, CAC, term sheets, or financial strategy." }, - { - "name": "cfo-review", - "category": "c-level", - "description": "/cs:cfo-review \u2014 Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation. Use when a plan commits meaningful spend \u2014 e.g. a hiring wave, a fundraise decision, or a new channel budget." - }, { "name": "challenge", "category": "c-level", @@ -348,21 +313,11 @@ "category": "c-level", "description": "Security leadership for growth-stage companies. Risk quantification in dollars, compliance roadmap (SOC 2/ISO 27001/HIPAA/GDPR), security architecture strategy, incident response leadership, and board-level security reporting. Use when building security programs, justifying security budget, selecting compliance frameworks, managing incidents, assessing vendor risk, or when user mentions CISO, security strategy, compliance roadmap, zero trust, or board security reporting." }, - { - "name": "ciso-review", - "category": "c-level", - "description": "/cs:ciso-review \u2014 Risk-paranoid interrogation of any plan that touches data, compliance, or production access. Use when launching features that handle customer data, before a SOC 2 / ISO audit, or after any incident or near-miss." - }, { "name": "cmo-advisor", "category": "c-level", "description": "Marketing leadership for scaling companies. Brand positioning, growth model design, marketing budget allocation, and marketing org design. Use when designing brand strategy, selecting growth models (PLG vs sales-led vs community-led), allocating marketing budgets, building marketing teams, or when user mentions CMO, brand strategy, growth model, CAC, LTV, channel mix, or marketing ROI." }, - { - "name": "cmo-review", - "category": "c-level", - "description": "/cs:cmo-review \u2014 Narrative-first interrogation of positioning, ICP, message house, and channel mix. Use when launching a campaign or repositioning, or when CAC is rising and the one-sentence positioning test fails." - }, { "name": "company-os", "category": "c-level", @@ -388,26 +343,11 @@ "category": "c-level", "description": "Product leadership for scaling companies. Product vision, portfolio strategy, product-market fit, and product org design. Use when setting product vision, managing a product portfolio, measuring PMF, designing product teams, prioritizing at the portfolio level, reporting to the board on product, or when user mentions CPO, product strategy, product-market fit, product organization, portfolio prioritization, or roadmap strategy." }, - { - "name": "cpo-review", - "category": "c-level", - "description": "/cs:cpo-review \u2014 JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus. Use when committing a quarter's roadmap, deciding whether to kill a feature, or claiming PMF without a retention curve." - }, { "name": "cro-advisor", "category": "c-level", "description": "Revenue leadership for B2B SaaS companies. Revenue forecasting, sales model design, pricing strategy, net revenue retention, and sales team scaling. Use when designing the revenue engine, setting quotas, modeling NRR, evaluating pricing, building board forecasts, or when user mentions CRO, chief revenue officer, revenue strategy, sales model, ARR growth, NRR, expansion revenue, churn, pricing strategy, or sales capacity." }, - { - "name": "cro-review", - "category": "c-level", - "description": "/cs:cro-review \u2014 Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time. Use when the forecast misses pipeline coverage, win rates drop, or before scaling the sales team." - }, - { - "name": "cross-eval", - "category": "c-level", - "description": "/cs:cross-eval \u2014 Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation. Use when a high-stakes memo needs an independent sanity check before the boardroom \u2014 e.g. a bet-the-company pivot or fundraise terms." - }, { "name": "cs-onboard", "category": "c-level", @@ -418,31 +358,16 @@ "category": "c-level", "description": "Technical leadership guidance for engineering teams, architecture decisions, and technology strategy. Use when assessing technical debt, scaling engineering teams, evaluating technologies, making architecture decisions, establishing engineering metrics, or when user mentions CTO, tech debt, technical debt, team scaling, architecture decisions, technology evaluation, engineering metrics, DORA metrics, or technology strategy." }, - { - "name": "cto-review", - "category": "c-level", - "description": "/cs:cto-review \u2014 Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy. Use when committing to an architecture, planning for 10x load, or weighing a rebuild against a vendor." - }, { "name": "culture-architect", "category": "c-level", "description": "Build, measure, and evolve company culture as operational behavior \u2014 not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code." }, - { - "name": "decide", - "category": "c-level", - "description": "/cs:decide \u2014 Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference. Use when the founder has approved a boardroom memo and the decision must become durable company memory \u2014 e.g. right after /cs:boardroom concludes." - }, { "name": "decision-logger", "category": "c-level", "description": "Two-layer memory architecture for board meeting decisions. Manages raw transcripts (Layer 1) and approved decisions (Layer 2). Use when logging decisions after a board meeting, reviewing past decisions with /cs:decisions, or checking overdue action items with /cs:review. Invoked automatically by the board-meeting skill after Phase 5 founder approval." }, - { - "name": "execute", - "category": "c-level", - "description": "/cs:execute \u2014 Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision. Use when a logged decision needs to become an operating plan \u2014 e.g. turning an approved market-entry call into weekly milestones with DRIs." - }, { "name": "executive-mentor", "category": "c-level", @@ -453,21 +378,6 @@ "category": "c-level", "description": "Personal leadership development for founders and first-time CEOs. Covers founder archetype identification, delegation frameworks, energy management, CEO calendar audits, leadership style evolution, blind spot identification, imposter syndrome, founder mental health, and succession planning. Use when a founder feels like the bottleneck, struggles to delegate, is burning out, transitioning from IC to executive, managing a board, or when user mentions founder mode, CEO growth, leadership development, delegation, burnout, or imposter syndrome." }, - { - "name": "founder-mode", - "category": "c-level", - "description": "/cs:founder-mode \u2014 Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point. Use when a founder asks any strategic question without knowing which advisor or command fits \u2014 e.g. 'runway pressure' routes to the CFO, 'gross retention dropped' routes to the CCO." - }, - { - "name": "freeze", - "category": "c-level", - "description": "/cs:freeze \u2014 Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer. Use when an irreversible decision was made under pressure \u2014 e.g. a layoff plan or multi-year contract \u2014 and deserves a cooling-off lock before execution." - }, - { - "name": "gc-review", - "category": "c-level", - "description": "/cs:gc-review \u2014 General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface. Use when reviewing a term sheet before signing, redlining a customer MSA, or checking IP assignment and regulatory exposure on a new product." - }, { "name": "general-counsel-advisor", "category": "c-level", @@ -493,26 +403,11 @@ "category": "c-level", "description": "M&A strategy for acquiring companies or being acquired. Due diligence, valuation, integration, and deal structure. Use when evaluating acquisitions, preparing for acquisition, M&A due diligence, integration planning, or deal negotiation." }, - { - "name": "office-hours", - "category": "c-level", - "description": "/cs:office-hours \u2014 YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit. Use when a founder question is too vague to route \u2014 e.g. 'should we grow faster?' \u2014 or before drafting a strategy brief." - }, - { - "name": "onboard", - "category": "c-level", - "description": "/cs:onboard \u2014 Founder interview that populates ~/.claude/company-context.md using the canonical 7-dimension cs-onboard schema. The first command to run when starting with c-level-agents. Use when setting up the virtual C-suite for a new company, or when advisors lack company context \u2014 e.g. before a first /cs:boardroom or after a fundraise changes the numbers." - }, { "name": "org-health-diagnostic", "category": "c-level", "description": "Cross-functional organizational health check combining signals from all C-suite roles. Scores 8 dimensions on a traffic-light scale with drill-down recommendations. Use when assessing overall company health, preparing for board reviews, identifying at-risk functions, or when user mentions org health, health check, or health dashboard." }, - { - "name": "post-mortem", - "category": "c-level", - "description": "/cs:post-mortem \u2014 Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop. Use when a decision hits its 90-day review checkpoint or its kill criteria trigger \u2014 e.g. scoring last quarter's pricing change against its pre-committed success metrics." - }, { "name": "postmortem", "category": "c-level", @@ -568,11 +463,6 @@ "category": "c-level", "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships." }, - { - "name": "vpe-review", - "category": "c-level", - "description": "/cs:vpe-review \u2014 Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline. Use when cycle time balloons, DORA metrics slide, or before committing to an eng hiring wave or a reorg." - }, { "name": "changelog", "category": "command", @@ -983,6 +873,16 @@ "category": "engineering", "description": "Production-grade Playwright testing toolkit. Use when the user mentions Playwright tests, end-to-end testing, browser automation, fixing flaky tests, test migration, CI/CD testing, or test suites. Generate tests, fix flaky failures, migrate from Cypress/Selenium, sync with TestRail, run on BrowserStack. 55 templates, 3 agents, smart reporting." }, + { + "name": "pw-init", + "category": "engineering", + "description": ">-" + }, + { + "name": "pw-review", + "category": "engineering", + "description": ">-" + }, { "name": "red-team", "category": "engineering", @@ -998,11 +898,6 @@ "category": "engineering", "description": ">-" }, - { - "name": "review", - "category": "engineering", - "description": ">-" - }, { "name": "security-pen-testing", "category": "engineering", @@ -1078,11 +973,6 @@ "category": "engineering", "description": "Use when the user asks for STRIDE threat modeling, DREAD risk scoring, data-flow-diagram threat analysis, or a quick secret scan \u2014 or when a security request needs routing to the right specialist skill (pen-testing, incident response, cloud posture, red team, AI security, threat hunting, secure code review). This skill owns threat modeling; everything else routes to a sibling." }, - { - "name": "skills-init", - "category": "engineering", - "description": ">-" - }, { "name": "snowflake-development", "category": "engineering", @@ -1143,6 +1033,16 @@ "category": "engineering-advanced", "description": "Use when the user asks to generate API tests, create integration test suites, test REST endpoints, or build contract tests." }, + { + "name": "ar-resume", + "category": "engineering-advanced", + "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:ar-resume or asks to pick up a previously started autoresearch experiment." + }, + { + "name": "ar-status", + "category": "engineering-advanced", + "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going." + }, { "name": "autoresearch-agent", "category": "engineering-advanced", @@ -1289,9 +1189,14 @@ "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw \u2014 chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test." }, { - "name": "init", + "name": "hub-init", "category": "engineering-advanced", - "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:init or asks to start a multi-agent competition on a task." + "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:hub-init or asks to start a multi-agent competition on a task." + }, + { + "name": "hub-status", + "category": "engineering-advanced", + "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:hub-status or asks how the AgentHub agents are doing." }, { "name": "interview-system-designer", @@ -1328,6 +1233,11 @@ "category": "engineering-advanced", "description": "Design and ship production-ready MCP (Model Context Protocol) servers from OpenAPI contracts instead of hand-written tool wrappers. Python and TypeScript support, schema validation, safe evolution. Use when exposing an existing API as an MCP server, building tool integrations for Claude or Codex or Cursor, or scaffolding an MCP project from scratch." }, + { + "name": "memory-engineering", + "category": "engineering-advanced", + "description": "Use when designing, reviewing, or paying for an agent memory system \u2014 adding memory to an agent, choosing between long-context / RAG / graph / agentic memory, auditing what a CLAUDE.md or memory directory actually holds, deciding what to keep and what to expire, or when a memory store keeps growing and nobody has said what leaves it. Prices the write path, picks which cost to pay, classifies records as facts / skills / logs, and refuses a design that has no forgetting policy." + }, { "name": "merge", "category": "engineering-advanced", @@ -1373,11 +1283,6 @@ "category": "engineering-advanced", "description": "Use when the user asks to design a RAG pipeline, choose a chunking strategy or embedding model, pick a vector database, or evaluate retrieval quality (precision@k, recall@k, NDCG). Examples: 'design a RAG system for our docs', 'what chunk size should I use for this corpus', 'evaluate my retriever against ground truth'. NOT for general LLM cost tuning (use llm-cost-optimizer) or agent loops over retrieval (use agenthub)." }, - { - "name": "resume", - "category": "engineering-advanced", - "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:resume or asks to pick up a previously started autoresearch experiment." - }, { "name": "run", "category": "engineering-advanced", @@ -1463,11 +1368,6 @@ "category": "engineering-advanced", "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill \u2014 specifically the SLO discipline." }, - { - "name": "skills-status", - "category": "engineering-advanced", - "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:status or asks how the AgentHub agents are doing." - }, { "name": "slo-architect", "category": "engineering-advanced", @@ -1493,11 +1393,6 @@ "category": "engineering-advanced", "description": "Run hypothesis tests, analyze A/B experiment results, calculate sample sizes, and interpret statistical significance with effect sizes. Use when you need to validate whether observed differences are real, size an experiment correctly before launch, or interpret test results with confidence." }, - { - "name": "status", - "category": "engineering-advanced", - "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:status or asks how an autoresearch experiment is going." - }, { "name": "strict-api", "category": "engineering-advanced", @@ -2193,7 +2088,7 @@ "description": "Business-operations resources" }, "c-level": { - "count": 68, + "count": 46, "description": "C-level resources" }, "command": { @@ -2213,7 +2108,7 @@ "description": "Engineering resources" }, "engineering-advanced": { - "count": 85, + "count": 86, "description": "Engineering-advanced resources" }, "finance": { diff --git a/.gemini/skills/ar-resume/SKILL.md b/.gemini/skills/ar-resume/SKILL.md new file mode 120000 index 00000000..9a3c3c87 --- /dev/null +++ b/.gemini/skills/ar-resume/SKILL.md @@ -0,0 +1 @@ +../../../engineering/autoresearch-agent/skills/ar-resume/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/ar-status/SKILL.md b/.gemini/skills/ar-status/SKILL.md new file mode 120000 index 00000000..271892f8 --- /dev/null +++ b/.gemini/skills/ar-status/SKILL.md @@ -0,0 +1 @@ +../../../engineering/autoresearch-agent/skills/ar-status/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/boardroom/SKILL.md b/.gemini/skills/boardroom/SKILL.md index 5ea94ac8..4b0c82e0 120000 --- a/.gemini/skills/boardroom/SKILL.md +++ b/.gemini/skills/boardroom/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/boardroom/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/boardroom/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/brief/SKILL.md b/.gemini/skills/brief/SKILL.md index 9582e70f..0d7b4260 120000 --- a/.gemini/skills/brief/SKILL.md +++ b/.gemini/skills/brief/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/brief/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/brief/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/c-level-agents/SKILL.md b/.gemini/skills/c-level-agents/SKILL.md index 52b75d2a..a0ff7790 120000 --- a/.gemini/skills/c-level-agents/SKILL.md +++ b/.gemini/skills/c-level-agents/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/c-level-agents/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/c-level-agents/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/caio-review/SKILL.md b/.gemini/skills/caio-review/SKILL.md index da2be713..ab201c75 120000 --- a/.gemini/skills/caio-review/SKILL.md +++ b/.gemini/skills/caio-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/caio-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/caio-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cco-review/SKILL.md b/.gemini/skills/cco-review/SKILL.md index dcbf2b4e..2d16d7f0 120000 --- a/.gemini/skills/cco-review/SKILL.md +++ b/.gemini/skills/cco-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cco-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cco-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cdo-review/SKILL.md b/.gemini/skills/cdo-review/SKILL.md index 6084624f..3010f4c3 120000 --- a/.gemini/skills/cdo-review/SKILL.md +++ b/.gemini/skills/cdo-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cdo-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cfo-review/SKILL.md b/.gemini/skills/cfo-review/SKILL.md index e98847a7..7060d3c2 120000 --- a/.gemini/skills/cfo-review/SKILL.md +++ b/.gemini/skills/cfo-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cfo-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cfo-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/ciso-review/SKILL.md b/.gemini/skills/ciso-review/SKILL.md index c044c44a..0e129965 120000 --- a/.gemini/skills/ciso-review/SKILL.md +++ b/.gemini/skills/ciso-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/ciso-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/ciso-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cmo-review/SKILL.md b/.gemini/skills/cmo-review/SKILL.md index f77945cd..63656a6e 120000 --- a/.gemini/skills/cmo-review/SKILL.md +++ b/.gemini/skills/cmo-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cmo-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cmo-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cpo-review/SKILL.md b/.gemini/skills/cpo-review/SKILL.md index 3057005f..ce6d47c3 120000 --- a/.gemini/skills/cpo-review/SKILL.md +++ b/.gemini/skills/cpo-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cpo-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cpo-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cro-review/SKILL.md b/.gemini/skills/cro-review/SKILL.md index 96d584f3..fddec72f 120000 --- a/.gemini/skills/cro-review/SKILL.md +++ b/.gemini/skills/cro-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cro-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cro-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cross-eval/SKILL.md b/.gemini/skills/cross-eval/SKILL.md index 6c6f7677..9b60d36c 120000 --- a/.gemini/skills/cross-eval/SKILL.md +++ b/.gemini/skills/cross-eval/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cross-eval/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cross-eval/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/cto-review/SKILL.md b/.gemini/skills/cto-review/SKILL.md index 401891de..4eae21fd 120000 --- a/.gemini/skills/cto-review/SKILL.md +++ b/.gemini/skills/cto-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/cto-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/cto-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/decide/SKILL.md b/.gemini/skills/decide/SKILL.md index 31ae20e4..6070a559 120000 --- a/.gemini/skills/decide/SKILL.md +++ b/.gemini/skills/decide/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/decide/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/decide/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/execute/SKILL.md b/.gemini/skills/execute/SKILL.md index 0e50eb7f..f7a66bcb 120000 --- a/.gemini/skills/execute/SKILL.md +++ b/.gemini/skills/execute/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/execute/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/execute/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/founder-mode/SKILL.md b/.gemini/skills/founder-mode/SKILL.md index f9baa3cb..f0475b06 120000 --- a/.gemini/skills/founder-mode/SKILL.md +++ b/.gemini/skills/founder-mode/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/founder-mode/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/founder-mode/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/freeze/SKILL.md b/.gemini/skills/freeze/SKILL.md index 3affe9a4..f4608b88 120000 --- a/.gemini/skills/freeze/SKILL.md +++ b/.gemini/skills/freeze/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/freeze/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/freeze/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/gc-review/SKILL.md b/.gemini/skills/gc-review/SKILL.md index 66df33a0..fe50dd55 120000 --- a/.gemini/skills/gc-review/SKILL.md +++ b/.gemini/skills/gc-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/gc-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/gc-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/hub-init/SKILL.md b/.gemini/skills/hub-init/SKILL.md new file mode 120000 index 00000000..bba7c381 --- /dev/null +++ b/.gemini/skills/hub-init/SKILL.md @@ -0,0 +1 @@ +../../../engineering/agenthub/skills/hub-init/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/hub-status/SKILL.md b/.gemini/skills/hub-status/SKILL.md new file mode 120000 index 00000000..bcbf6505 --- /dev/null +++ b/.gemini/skills/hub-status/SKILL.md @@ -0,0 +1 @@ +../../../engineering/agenthub/skills/hub-status/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/init/SKILL.md b/.gemini/skills/init/SKILL.md deleted file mode 120000 index 05c0f65e..00000000 --- a/.gemini/skills/init/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering/agenthub/skills/init/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/memory-engineering/SKILL.md b/.gemini/skills/memory-engineering/SKILL.md new file mode 120000 index 00000000..3d690101 --- /dev/null +++ b/.gemini/skills/memory-engineering/SKILL.md @@ -0,0 +1 @@ +../../../engineering/memory-engineering/skills/memory-engineering/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/office-hours/SKILL.md b/.gemini/skills/office-hours/SKILL.md index 7227eb47..68fca912 120000 --- a/.gemini/skills/office-hours/SKILL.md +++ b/.gemini/skills/office-hours/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/office-hours/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/office-hours/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/onboard/SKILL.md b/.gemini/skills/onboard/SKILL.md index 7c6d8e42..c93841b3 120000 --- a/.gemini/skills/onboard/SKILL.md +++ b/.gemini/skills/onboard/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/onboard/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/onboard/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/post-mortem/SKILL.md b/.gemini/skills/post-mortem/SKILL.md index 9f5165fb..56bc4bd9 120000 --- a/.gemini/skills/post-mortem/SKILL.md +++ b/.gemini/skills/post-mortem/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/post-mortem/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/post-mortem/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/pw-init/SKILL.md b/.gemini/skills/pw-init/SKILL.md new file mode 120000 index 00000000..f5dd81f4 --- /dev/null +++ b/.gemini/skills/pw-init/SKILL.md @@ -0,0 +1 @@ +../../../engineering-team/playwright-pro/skills/pw-init/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/pw-review/SKILL.md b/.gemini/skills/pw-review/SKILL.md new file mode 120000 index 00000000..aa1bd7e2 --- /dev/null +++ b/.gemini/skills/pw-review/SKILL.md @@ -0,0 +1 @@ +../../../engineering-team/playwright-pro/skills/pw-review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/resume/SKILL.md b/.gemini/skills/resume/SKILL.md deleted file mode 120000 index 73cc34f9..00000000 --- a/.gemini/skills/resume/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering/autoresearch-agent/skills/resume/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/review/SKILL.md b/.gemini/skills/review/SKILL.md deleted file mode 120000 index b5dc77e3..00000000 --- a/.gemini/skills/review/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering-team/playwright-pro/skills/review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/skills-init/SKILL.md b/.gemini/skills/skills-init/SKILL.md deleted file mode 120000 index 1d516286..00000000 --- a/.gemini/skills/skills-init/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering-team/playwright-pro/skills/init/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/skills-review/SKILL.md b/.gemini/skills/skills-review/SKILL.md deleted file mode 120000 index b5dc77e3..00000000 --- a/.gemini/skills/skills-review/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering-team/playwright-pro/skills/review/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/skills-status-2/SKILL.md b/.gemini/skills/skills-status-2/SKILL.md deleted file mode 120000 index 34c41964..00000000 --- a/.gemini/skills/skills-status-2/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering-team/self-improving-agent/skills/status/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/skills-status/SKILL.md b/.gemini/skills/skills-status/SKILL.md deleted file mode 120000 index 2f7e0cf5..00000000 --- a/.gemini/skills/skills-status/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering/agenthub/skills/status/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/status/SKILL.md b/.gemini/skills/status/SKILL.md deleted file mode 120000 index ec526d34..00000000 --- a/.gemini/skills/status/SKILL.md +++ /dev/null @@ -1 +0,0 @@ -../../../engineering/autoresearch-agent/skills/status/SKILL.md \ No newline at end of file diff --git a/.gemini/skills/vpe-review/SKILL.md b/.gemini/skills/vpe-review/SKILL.md index c26e7984..96d7958f 120000 --- a/.gemini/skills/vpe-review/SKILL.md +++ b/.gemini/skills/vpe-review/SKILL.md @@ -1 +1 @@ -../../../c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md \ No newline at end of file +../../../c-level-agents/skills/vpe-review/SKILL.md \ No newline at end of file diff --git a/.github/workflows/ci-quality-gate.yml b/.github/workflows/ci-quality-gate.yml index 8e0b9fcd..52a0777f 100644 --- a/.github/workflows/ci-quality-gate.yml +++ b/.github/workflows/ci-quality-gate.yml @@ -92,6 +92,10 @@ jobs: run: | python scripts/check_plugin_json.py --all + - name: Built-in-shadowing skill names (blocking — guards #885) + run: | + python3 scripts/check_skill_names.py --all + # ---- Audit guardrails (newgen-2026-06 gates) ---------------------- # BLOCKING since PR-2 (flipped ahead of the 2026-07-01 SLA — every # advisory run was green through PR #835). If a gate misfires on a @@ -102,10 +106,25 @@ jobs: run: | python3 scripts/check_paths.py --all + # Every other gate reads frontmatter with a regex, so malformed YAML used + # to pass CI while Claude Code silently loaded the skill with no + # description. G10 parses it properly. + - name: Frontmatter YAML validator (gate G10 — blocking) + run: | + python3 scripts/check_frontmatter.py --all + - name: Dual-publish drift guard (gate G4 — blocking) run: | python3 scripts/check_dual_publish.py + # Proposed by audit/newgen-2026-06 and never built, which is why retired + # model IDs survived two later audits. The tree is now clean, so this is + # blocking. A deliberate reference needs an entry with a reason in + # scripts/check_model_freshness_allowlist.txt. + - name: Retired model identifier lint (gate G7 — blocking) + run: | + python3 scripts/check_model_freshness.py --all + - name: Script --help smoke gate (gate G8 — blocking) run: | python3 scripts/smoke_scripts.py diff --git a/.hermes/skills/claude-skills/c-level-advisor/boardroom b/.hermes/skills/claude-skills/c-level-advisor/boardroom index 83fb5230..da752e6a 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/boardroom +++ b/.hermes/skills/claude-skills/c-level-advisor/boardroom @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/boardroom \ No newline at end of file +../../../../c-level-agents/skills/boardroom \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/brief b/.hermes/skills/claude-skills/c-level-advisor/brief index 7c7c4105..7fd1d947 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/brief +++ b/.hermes/skills/claude-skills/c-level-advisor/brief @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/brief \ No newline at end of file +../../../../c-level-agents/skills/brief \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/c-level-agents b/.hermes/skills/claude-skills/c-level-advisor/c-level-agents index 96178fee..01d3f69b 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/c-level-agents +++ b/.hermes/skills/claude-skills/c-level-advisor/c-level-agents @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/c-level-agents \ No newline at end of file +../../../../c-level-agents/skills/c-level-agents \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/caio-review b/.hermes/skills/claude-skills/c-level-advisor/caio-review index 9b5f38de..b70a391c 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/caio-review +++ b/.hermes/skills/claude-skills/c-level-advisor/caio-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/caio-review \ No newline at end of file +../../../../c-level-agents/skills/caio-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cco-review b/.hermes/skills/claude-skills/c-level-advisor/cco-review index 7213ca76..02735ec9 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cco-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cco-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cco-review \ No newline at end of file +../../../../c-level-agents/skills/cco-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cdo-review b/.hermes/skills/claude-skills/c-level-advisor/cdo-review index 58d35f46..55e18a4e 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cdo-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cdo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cdo-review \ No newline at end of file +../../../../c-level-agents/skills/cdo-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cfo-review b/.hermes/skills/claude-skills/c-level-advisor/cfo-review index d167d736..b7992d66 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cfo-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cfo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cfo-review \ No newline at end of file +../../../../c-level-agents/skills/cfo-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/ciso-review b/.hermes/skills/claude-skills/c-level-advisor/ciso-review index 2861dab6..901f5298 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/ciso-review +++ b/.hermes/skills/claude-skills/c-level-advisor/ciso-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/ciso-review \ No newline at end of file +../../../../c-level-agents/skills/ciso-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cmo-review b/.hermes/skills/claude-skills/c-level-advisor/cmo-review index 9f3af619..6400e2eb 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cmo-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cmo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cmo-review \ No newline at end of file +../../../../c-level-agents/skills/cmo-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cpo-review b/.hermes/skills/claude-skills/c-level-advisor/cpo-review index d74e4b8f..a20e8c45 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cpo-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cpo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cpo-review \ No newline at end of file +../../../../c-level-agents/skills/cpo-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cro-review b/.hermes/skills/claude-skills/c-level-advisor/cro-review index e8575448..7c69c8c9 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cro-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cro-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cro-review \ No newline at end of file +../../../../c-level-agents/skills/cro-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cross-eval b/.hermes/skills/claude-skills/c-level-advisor/cross-eval index f71fb2cc..5d64720e 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cross-eval +++ b/.hermes/skills/claude-skills/c-level-advisor/cross-eval @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cross-eval \ No newline at end of file +../../../../c-level-agents/skills/cross-eval \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/cto-review b/.hermes/skills/claude-skills/c-level-advisor/cto-review index ae34b911..06ff1511 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/cto-review +++ b/.hermes/skills/claude-skills/c-level-advisor/cto-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cto-review \ No newline at end of file +../../../../c-level-agents/skills/cto-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/decide b/.hermes/skills/claude-skills/c-level-advisor/decide index 104673bb..65f100fa 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/decide +++ b/.hermes/skills/claude-skills/c-level-advisor/decide @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/decide \ No newline at end of file +../../../../c-level-agents/skills/decide \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/execute b/.hermes/skills/claude-skills/c-level-advisor/execute index 14c56d76..3cd98daa 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/execute +++ b/.hermes/skills/claude-skills/c-level-advisor/execute @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/execute \ No newline at end of file +../../../../c-level-agents/skills/execute \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/founder-mode b/.hermes/skills/claude-skills/c-level-advisor/founder-mode index fb0bb211..f3319f24 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/founder-mode +++ b/.hermes/skills/claude-skills/c-level-advisor/founder-mode @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/founder-mode \ No newline at end of file +../../../../c-level-agents/skills/founder-mode \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/freeze b/.hermes/skills/claude-skills/c-level-advisor/freeze index 60f320f2..7549d40a 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/freeze +++ b/.hermes/skills/claude-skills/c-level-advisor/freeze @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/freeze \ No newline at end of file +../../../../c-level-agents/skills/freeze \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/gc-review b/.hermes/skills/claude-skills/c-level-advisor/gc-review index 96f566db..742b72b9 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/gc-review +++ b/.hermes/skills/claude-skills/c-level-advisor/gc-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/gc-review \ No newline at end of file +../../../../c-level-agents/skills/gc-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/office-hours b/.hermes/skills/claude-skills/c-level-advisor/office-hours index 475bdf47..ad336771 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/office-hours +++ b/.hermes/skills/claude-skills/c-level-advisor/office-hours @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/office-hours \ No newline at end of file +../../../../c-level-agents/skills/office-hours \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/onboard b/.hermes/skills/claude-skills/c-level-advisor/onboard index 4d40491e..4b693c47 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/onboard +++ b/.hermes/skills/claude-skills/c-level-advisor/onboard @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/onboard \ No newline at end of file +../../../../c-level-agents/skills/onboard \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/post-mortem b/.hermes/skills/claude-skills/c-level-advisor/post-mortem index 9c0e56a3..f8f661a8 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/post-mortem +++ b/.hermes/skills/claude-skills/c-level-advisor/post-mortem @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/post-mortem \ No newline at end of file +../../../../c-level-agents/skills/post-mortem \ No newline at end of file diff --git a/.hermes/skills/claude-skills/c-level-advisor/vpe-review b/.hermes/skills/claude-skills/c-level-advisor/vpe-review index bc22bb9a..47a99016 120000 --- a/.hermes/skills/claude-skills/c-level-advisor/vpe-review +++ b/.hermes/skills/claude-skills/c-level-advisor/vpe-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/vpe-review \ No newline at end of file +../../../../c-level-agents/skills/vpe-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/init b/.hermes/skills/claude-skills/engineering-team/init deleted file mode 120000 index c285e57a..00000000 --- a/.hermes/skills/claude-skills/engineering-team/init +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/playwright-pro/skills/init \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/memory-review b/.hermes/skills/claude-skills/engineering-team/memory-review new file mode 120000 index 00000000..a1aee6fb --- /dev/null +++ b/.hermes/skills/claude-skills/engineering-team/memory-review @@ -0,0 +1 @@ +../../../../engineering-team/self-improving-agent/skills/memory-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/memory-status b/.hermes/skills/claude-skills/engineering-team/memory-status new file mode 120000 index 00000000..23628479 --- /dev/null +++ b/.hermes/skills/claude-skills/engineering-team/memory-status @@ -0,0 +1 @@ +../../../../engineering-team/self-improving-agent/skills/memory-status \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/pw-init b/.hermes/skills/claude-skills/engineering-team/pw-init new file mode 120000 index 00000000..238ec8b6 --- /dev/null +++ b/.hermes/skills/claude-skills/engineering-team/pw-init @@ -0,0 +1 @@ +../../../../engineering-team/playwright-pro/skills/pw-init \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/pw-review b/.hermes/skills/claude-skills/engineering-team/pw-review new file mode 120000 index 00000000..c88ff4d1 --- /dev/null +++ b/.hermes/skills/claude-skills/engineering-team/pw-review @@ -0,0 +1 @@ +../../../../engineering-team/playwright-pro/skills/pw-review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/review b/.hermes/skills/claude-skills/engineering-team/review deleted file mode 120000 index 6562335f..00000000 --- a/.hermes/skills/claude-skills/engineering-team/review +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/playwright-pro/skills/review \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering-team/status b/.hermes/skills/claude-skills/engineering-team/status deleted file mode 120000 index 62619be4..00000000 --- a/.hermes/skills/claude-skills/engineering-team/status +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/self-improving-agent/skills/status \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/ar-resume b/.hermes/skills/claude-skills/engineering/ar-resume new file mode 120000 index 00000000..8c56cf7c --- /dev/null +++ b/.hermes/skills/claude-skills/engineering/ar-resume @@ -0,0 +1 @@ +../../../../engineering/autoresearch-agent/skills/ar-resume \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/ar-status b/.hermes/skills/claude-skills/engineering/ar-status new file mode 120000 index 00000000..54df8ede --- /dev/null +++ b/.hermes/skills/claude-skills/engineering/ar-status @@ -0,0 +1 @@ +../../../../engineering/autoresearch-agent/skills/ar-status \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/hub-init b/.hermes/skills/claude-skills/engineering/hub-init new file mode 120000 index 00000000..6eee19f2 --- /dev/null +++ b/.hermes/skills/claude-skills/engineering/hub-init @@ -0,0 +1 @@ +../../../../engineering/agenthub/skills/hub-init \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/hub-status b/.hermes/skills/claude-skills/engineering/hub-status new file mode 120000 index 00000000..60aa7499 --- /dev/null +++ b/.hermes/skills/claude-skills/engineering/hub-status @@ -0,0 +1 @@ +../../../../engineering/agenthub/skills/hub-status \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/init b/.hermes/skills/claude-skills/engineering/init deleted file mode 120000 index 92ea232d..00000000 --- a/.hermes/skills/claude-skills/engineering/init +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/agenthub/skills/init \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/resume b/.hermes/skills/claude-skills/engineering/resume deleted file mode 120000 index 0ced05e0..00000000 --- a/.hermes/skills/claude-skills/engineering/resume +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/autoresearch-agent/skills/resume \ No newline at end of file diff --git a/.hermes/skills/claude-skills/engineering/status b/.hermes/skills/claude-skills/engineering/status deleted file mode 120000 index a1f9ba44..00000000 --- a/.hermes/skills/claude-skills/engineering/status +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/agenthub/skills/status \ No newline at end of file diff --git a/.hermes/skills/claude-skills/skills-index.json b/.hermes/skills/claude-skills/skills-index.json index 1e1eaa33..94e5c4ef 100644 --- a/.hermes/skills/claude-skills/skills-index.json +++ b/.hermes/skills/claude-skills/skills-index.json @@ -25,12 +25,12 @@ }, { "name": "book-to-skill", - "description": "Converts books, documentation folders, and source collections (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into structured agent skills \u2014 extracting named frameworks, principles, techniques, and anti-patterns into a master SKILL.md plus on-demand chapter files, a glossary, a patterns file, and a decision cheatsheet. Use when the user wants to study a document with an agent, apply an author's frameworks while working, turn internal docs or standards into a reusable knowledge base, or package a compiled book skill as a claude-skills plugin.", + "description": "Converts books, documentation folders, and source collections (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into structured agent skills — extracting named frameworks, principles, techniques, and anti-patterns into a master SKILL.md plus on-demand chapter files, a glossary, a patterns file, and a decision cheatsheet. Use when the user wants to study a document with an agent, apply an author's frameworks while working, turn internal docs or standards into a reusable knowledge base, or package a compiled book skill as a claude-skills plugin.", "path": "engineering/book-to-skill" }, { "name": "browser-automation", - "description": "Use when the user asks to automate browser tasks, scrape websites, fill forms, capture screenshots, extract structured data from web pages, or build web automation workflows. NOT for testing \u2014 use playwright-pro for that.", + "description": "Use when the user asks to automate browser tasks, scrape websites, fill forms, capture screenshots, extract structured data from web pages, or build web automation workflows. NOT for testing — use playwright-pro for that.", "path": "engineering/browser-automation" }, { @@ -45,7 +45,7 @@ }, { "name": "ci-cd-pipeline-builder", - "description": "Generate pragmatic CI/CD pipelines from detected project stack signals \u2014 fast baseline generation, repeatable checks, environment-aware deployment stages. Use when setting up CI for a new project, refactoring existing pipelines, or standardizing deployment workflows across multiple repos.", + "description": "Generate pragmatic CI/CD pipelines from detected project stack signals — fast baseline generation, repeatable checks, environment-aware deployment stages. Use when setting up CI for a new project, refactoring existing pipelines, or standardizing deployment workflows across multiple repos.", "path": "engineering/ci-cd-pipeline-builder" }, { @@ -90,7 +90,7 @@ }, { "name": "focused-fix", - "description": "Use when the user asks to fix, debug, or make a specific feature/module/area work end-to-end. Triggers: 'make X work', 'fix the Y feature', 'the Z module is broken', 'focus on [area]'. Not for quick single-bug fixes \u2014 this is for systematic deep-dive repair across all files and dependencies.", + "description": "Use when the user asks to fix, debug, or make a specific feature/module/area work end-to-end. Triggers: 'make X work', 'fix the Y feature', 'the Z module is broken', 'focus on [area]'. Not for quick single-bug fixes — this is for systematic deep-dive repair across all files and dependencies.", "path": "engineering/focused-fix" }, { @@ -110,7 +110,7 @@ }, { "name": "kubernetes-operator", - "description": "Use when building a Kubernetes Operator \u2014 custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill \u2014 specifically the Operator pattern.", + "description": "Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill — specifically the Operator pattern.", "path": "engineering/kubernetes-operator" }, { @@ -155,7 +155,7 @@ }, { "name": "runbook-generator", - "description": "Generate operational runbooks from a service name \u2014 deployment, incident response, maintenance, and rollback workflows. Templated structure customizable per environment. Use when documenting on-call procedures for a new service, standardizing incident response across teams, or producing runbooks before launching to production.", + "description": "Generate operational runbooks from a service name — deployment, incident response, maintenance, and rollback workflows. Templated structure customizable per environment. Use when documenting on-call procedures for a new service, standardizing incident response across teams, or producing runbooks before launching to production.", "path": "engineering/runbook-generator" }, { @@ -185,7 +185,7 @@ }, { "name": "slo-architect", - "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill \u2014 specifically the SLO discipline.", + "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill — specifically the SLO discipline.", "path": "engineering/slo-architect" }, { @@ -210,7 +210,7 @@ }, { "name": "agenthub", - "description": "Multi-agent collaboration plugin that spawns N parallel subagents competing on the same task via git worktree isolation. Agents work independently, results are evaluated by metric or LLM judge, and the best branch is merged. Use when: user wants multiple approaches tried in parallel \u2014 code optimization, content variation, research exploration, or any task that benefits from parallel competition. Requires: a git repo.", + "description": "Multi-agent collaboration plugin that spawns N parallel subagents competing on the same task via git worktree isolation. Agents work independently, results are evaluated by metric or LLM judge, and the best branch is merged. Use when: user wants multiple approaches tried in parallel — code optimization, content variation, research exploration, or any task that benefits from parallel competition. Requires: a git repo.", "path": "engineering/agenthub" }, { @@ -224,9 +224,9 @@ "path": "engineering/eval" }, { - "name": "init", + "name": "hub-init", "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria.", - "path": "engineering/init" + "path": "engineering/hub-init" }, { "name": "merge", @@ -235,7 +235,7 @@ }, { "name": "run", - "description": "One-shot lifecycle command that chains init \u2192 baseline \u2192 spawn \u2192 eval \u2192 merge in a single invocation.", + "description": "One-shot lifecycle command that chains init → baseline → spawn → eval → merge in a single invocation.", "path": "engineering/run" }, { @@ -244,9 +244,9 @@ "path": "engineering/spawn" }, { - "name": "status", + "name": "hub-status", "description": "Show DAG state, agent progress, and branch status for an AgentHub session.", - "path": "engineering/status" + "path": "engineering/hub-status" }, { "name": "autoresearch-agent", @@ -259,9 +259,9 @@ "path": "engineering/loop" }, { - "name": "resume", + "name": "ar-resume", "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating.", - "path": "engineering/resume" + "path": "engineering/ar-resume" }, { "name": "run", @@ -273,14 +273,9 @@ "description": "Set up a new autoresearch experiment interactively. Collects domain, target file, eval command, metric, direction, and evaluator.", "path": "engineering/setup" }, - { - "name": "status", - "description": "Show experiment dashboard with results, active loops, and progress.", - "path": "engineering/status" - }, { "name": "behuman", - "description": "Use when the user wants more human-like AI responses \u2014 less robotic, less listy, more authentic. Triggers: 'behuman', 'be real', 'like a human', 'more human', 'less AI', 'talk like a person', 'mirror mode', 'stop being so AI', or when conversations are emotionally charged (grief, job loss, relationship advice, fear). NOT for technical questions, code generation, or factual lookups.", + "description": "Use when the user wants more human-like AI responses — less robotic, less listy, more authentic. Triggers: 'behuman', 'be real', 'like a human', 'more human', 'less AI', 'talk like a person', 'mirror mode', 'stop being so AI', or when conversations are emotionally charged (grief, job loss, relationship advice, fear). NOT for technical questions, code generation, or factual lookups.", "path": "engineering/behuman" }, { @@ -295,7 +290,7 @@ }, { "name": "code-tour", - "description": "Use when the user asks to create a CodeTour .tour file \u2014 persona-targeted, step-by-step walkthroughs that link to real files and line numbers. Trigger for: create a tour, onboarding tour, architecture tour, PR review tour, explain how X works, vibe check, RCA tour, contributor guide, or any structured code walkthrough request.", + "description": "Use when the user asks to create a CodeTour .tour file — persona-targeted, step-by-step walkthroughs that link to real files and line numbers. Trigger for: create a tour, onboarding tour, architecture tour, PR review tour, explain how X works, vibe check, RCA tour, contributor guide, or any structured code walkthrough request.", "path": "engineering/code-tour" }, { @@ -325,7 +320,7 @@ }, { "name": "grill-with-docs", - "description": "Docs-anchored grilling session \u2014 challenges a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), and updates those files inline as terminology and decisions crystallise. Use when user wants to stress-test a plan against documented domain language, or mentions \"grill with docs\".", + "description": "Docs-anchored grilling session — challenges a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), and updates those files inline as terminology and decisions crystallise. Use when user wants to stress-test a plan against documented domain language, or mentions \"grill with docs\".", "path": "engineering/grill-with-docs" }, { @@ -335,17 +330,17 @@ }, { "name": "helm-chart-builder", - "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw \u2014 chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.", + "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw — chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.", "path": "engineering/helm-chart-builder" }, { "name": "karpathy-coder", - "description": "Use when writing, reviewing, or committing code to enforce Karpathy's 4 coding principles \u2014 surface assumptions before coding, keep it simple, make surgical changes, define verifiable goals. Triggers on \"review my diff\", \"check complexity\", \"am I overcomplicating this\", \"karpathy check\", \"before I commit\", or any code quality concern where the LLM might be overcoding.", + "description": "Use when writing, reviewing, or committing code to enforce Karpathy's 4 coding principles — surface assumptions before coding, keep it simple, make surgical changes, define verifiable goals. Triggers on \"review my diff\", \"check complexity\", \"am I overcomplicating this\", \"karpathy check\", \"before I commit\", or any code quality concern where the LLM might be overcoding.", "path": "engineering/karpathy-coder" }, { "name": "kubernetes-operator", - "description": "Use when building a Kubernetes Operator \u2014 custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill \u2014 specifically the Operator pattern.", + "description": "Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill — specifically the Operator pattern.", "path": "engineering/kubernetes-operator" }, { @@ -365,12 +360,12 @@ }, { "name": "security-guidance", - "description": "PreToolUse security-anti-pattern hook for Claude Code. Catches 12 common security risks (command injection, XSS, SQL injection, unsafe deserialization, GitHub Actions workflow injection, eval/new Function code injection) BEFORE the Edit/Write/MultiEdit operation completes. Session-state caching prevents duplicate warnings on the same file+rule combo. Stdlib only \u2014 no dependencies. Use when you want a safety net during Claude Code sessions that touch security-sensitive code (auth, payments, user input handling, IaC). Disable with ENABLE_SECURITY_REMINDER=0 if you need to perform a verified-safe operation that would otherwise trip a pattern. Triggers \u2014 \"add security hook\", \"block unsafe code\", \"detect command injection before write\", \"prevent SQL injection patterns\", \"security warning hook\".", + "description": "PreToolUse security-anti-pattern hook for Claude Code. Catches 12 common security risks (command injection, XSS, SQL injection, unsafe deserialization, GitHub Actions workflow injection, eval/new Function code injection) BEFORE the Edit/Write/MultiEdit operation completes. Session-state caching prevents duplicate warnings on the same file+rule combo. Stdlib only — no dependencies. Use when you want a safety net during Claude Code sessions that touch security-sensitive code (auth, payments, user input handling, IaC). Disable with ENABLE_SECURITY_REMINDER=0 if you need to perform a verified-safe operation that would otherwise trip a pattern. Triggers — \"add security hook\", \"block unsafe code\", \"detect command injection before write\", \"prevent SQL injection patterns\", \"security warning hook\".", "path": "engineering/security-guidance" }, { "name": "slo-architect", - "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill \u2014 specifically the SLO discipline.", + "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill — specifically the SLO discipline.", "path": "engineering/slo-architect" }, { @@ -387,6 +382,11 @@ "name": "write-a-skill", "description": "Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, build, or author a new skill.", "path": "engineering/write-a-skill" + }, + { + "name": "ar-status", + "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going.", + "path": "engineering/ar-status" } ], "engineering-team": [ @@ -487,7 +487,7 @@ }, { "name": "senior-data-scientist", - "description": "World-class senior data scientist skill specialising in statistical modeling, experiment design, causal inference, and predictive analytics. Covers A/B testing (sample sizing, two-proportion z-tests, Bonferroni correction), difference-in-differences, feature engineering pipelines (Scikit-learn, XGBoost), cross-validated model evaluation (AUC-ROC, AUC-PR, SHAP), and MLflow experiment tracking \u2014 using Python (NumPy, Pandas, Scikit-learn), R, and SQL. Use when designing or analysing controlled experiments, building and evaluating classification or regression models, performing causal analysis on observational data, engineering features for structured tabular datasets, or translating statistical findings into data-driven business decisions.", + "description": "World-class senior data scientist skill specialising in statistical modeling, experiment design, causal inference, and predictive analytics. Covers A/B testing (sample sizing, two-proportion z-tests, Bonferroni correction), difference-in-differences, feature engineering pipelines (Scikit-learn, XGBoost), cross-validated model evaluation (AUC-ROC, AUC-PR, SHAP), and MLflow experiment tracking — using Python (NumPy, Pandas, Scikit-learn), R, and SQL. Use when designing or analysing controlled experiments, building and evaluating classification or regression models, performing causal analysis on observational data, engineering features for structured tabular datasets, or translating statistical findings into data-driven business decisions.", "path": "engineering-team/senior-data-scientist" }, { @@ -581,9 +581,9 @@ "path": "engineering-team/generate" }, { - "name": "init", + "name": "pw-init", "description": ">-", - "path": "engineering-team/init" + "path": "engineering-team/pw-init" }, { "name": "migrate", @@ -601,9 +601,9 @@ "path": "engineering-team/report" }, { - "name": "review", + "name": "pw-review", "description": ">-", - "path": "engineering-team/review" + "path": "engineering-team/pw-review" }, { "name": "testrail", @@ -626,9 +626,9 @@ "path": "engineering-team/remember" }, { - "name": "review", + "name": "memory-review", "description": "Analyze auto-memory for promotion candidates, stale entries, consolidation opportunities, and health metrics.", - "path": "engineering-team/review" + "path": "engineering-team/memory-review" }, { "name": "self-improving-agent", @@ -636,9 +636,9 @@ "path": "engineering-team/self-improving-agent" }, { - "name": "status", + "name": "memory-status", "description": "Memory health dashboard showing line counts, topic files, capacity, stale entries, and recommendations.", - "path": "engineering-team/status" + "path": "engineering-team/memory-status" }, { "name": "snowflake-development", @@ -659,7 +659,7 @@ }, { "name": "landing-page-generator", - "description": "Generates high-converting landing pages as complete Next.js/React (TSX) components with Tailwind CSS. Creates hero sections, feature grids, pricing tables, FAQ accordions, testimonial blocks, and CTA sections using proven copy frameworks (PAS, AIDA, BAB). Outputs SEO meta tags, structured data, and performance-optimised code targeting Core Web Vitals (LCP < 1s, CLS < 0.1). Use when the user asks to create a landing page, marketing page, homepage, single-page site, lead capture page, campaign page, promo page, or conversion-optimised web page \u2014 or when they want to A/B test landing page variants or replace a static page with one designed to convert.", + "description": "Generates high-converting landing pages as complete Next.js/React (TSX) components with Tailwind CSS. Creates hero sections, feature grids, pricing tables, FAQ accordions, testimonial blocks, and CTA sections using proven copy frameworks (PAS, AIDA, BAB). Outputs SEO meta tags, structured data, and performance-optimised code targeting Core Web Vitals (LCP < 1s, CLS < 0.1). Use when the user asks to create a landing page, marketing page, homepage, single-page site, lead capture page, campaign page, promo page, or conversion-optimised web page — or when they want to A/B test landing page variants or replace a static page with one designed to convert.", "path": "product-team/landing-page-generator" }, { @@ -741,22 +741,22 @@ }, { "name": "ad-creative", - "description": "When the user needs to generate, iterate, or scale ad creative for paid advertising. Use when they say 'write ad copy,' 'generate headlines,' 'create ad variations,' 'bulk creative,' 'iterate on ads,' 'ad copy validation,' 'RSA headlines,' 'Meta ad copy,' 'LinkedIn ad,' or 'creative testing.' This is pure creative production \u2014 distinct from paid-ads (campaign strategy). Use ad-creative when you need the copy, not the campaign plan.", + "description": "When the user needs to generate, iterate, or scale ad creative for paid advertising. Use when they say 'write ad copy,' 'generate headlines,' 'create ad variations,' 'bulk creative,' 'iterate on ads,' 'ad copy validation,' 'RSA headlines,' 'Meta ad copy,' 'LinkedIn ad,' or 'creative testing.' This is pure creative production — distinct from paid-ads (campaign strategy). Use ad-creative when you need the copy, not the campaign plan.", "path": "marketing-skill/ad-creative" }, { "name": "aeo", - "description": "Answer Engine Optimization (AEO) skill \u2014 optimize content to be cited by AI language models (ChatGPT, Perplexity, Claude, Gemini, Mistral) as authoritative sources. Distinct from SEO: AEO optimizes for citation in LLM-generated responses, not search rankings. Use when planning content for AI-first search audiences, auditing existing content for E-E-A-T signals, tracking which pages get cited by which LLMs, or building a citation-friendly content strategy. Triggers \u2014 \"AEO audit\", \"optimize for ChatGPT\", \"get cited by Perplexity\", \"LLM citation strategy\", \"answer engine optimization\", \"content for AI search\", \"E-E-A-T audit\". Output is a markdown audit report (default) or JSON for pipeline integration. Stdlib-only Python tools.", + "description": "Answer Engine Optimization (AEO) skill — optimize content to be cited by AI language models (ChatGPT, Perplexity, Claude, Gemini, Mistral) as authoritative sources. Distinct from SEO: AEO optimizes for citation in LLM-generated responses, not search rankings. Use when planning content for AI-first search audiences, auditing existing content for E-E-A-T signals, tracking which pages get cited by which LLMs, or building a citation-friendly content strategy. Triggers — \"AEO audit\", \"optimize for ChatGPT\", \"get cited by Perplexity\", \"LLM citation strategy\", \"answer engine optimization\", \"content for AI search\", \"E-E-A-T audit\". Output is a markdown audit report (default) or JSON for pipeline integration. Stdlib-only Python tools.", "path": "marketing-skill/aeo" }, { "name": "ai-seo", - "description": "Optimize content to get cited by AI search engines \u2014 ChatGPT, Perplexity, Google AI Overviews, Claude, Gemini, Copilot. Use when you want your content to appear in AI-generated answers, not just ranked in blue links. Triggers: 'optimize for AI search', 'get cited by ChatGPT', 'AI Overviews', 'Perplexity citations', 'AI SEO', 'generative search', 'LLM visibility', 'GEO' (generative engine optimization). NOT for traditional SEO ranking (use seo-audit). NOT for content creation (use content-production).", + "description": "Optimize content to get cited by AI search engines — ChatGPT, Perplexity, Google AI Overviews, Claude, Gemini, Copilot. Use when you want your content to appear in AI-generated answers, not just ranked in blue links. Triggers: 'optimize for AI search', 'get cited by ChatGPT', 'AI Overviews', 'Perplexity citations', 'AI SEO', 'generative search', 'LLM visibility', 'GEO' (generative engine optimization). NOT for traditional SEO ranking (use seo-audit). NOT for content creation (use content-production).", "path": "marketing-skill/ai-seo" }, { "name": "analytics-tracking", - "description": "Set up, audit, and debug analytics tracking implementation \u2014 GA4, Google Tag Manager, event taxonomy, conversion tracking, and data quality. Use when building a tracking plan from scratch, auditing existing analytics for gaps or errors, debugging missing events, or setting up GTM. Trigger keywords: GA4 setup, Google Tag Manager, GTM, event tracking, analytics implementation, conversion tracking, tracking plan, event taxonomy, custom dimensions, UTM tracking, analytics audit, missing events, tracking broken. NOT for analyzing marketing campaign data \u2014 use campaign-analytics for that. NOT for BI dashboards \u2014 use product-analytics for in-product event analysis.", + "description": "Set up, audit, and debug analytics tracking implementation — GA4, Google Tag Manager, event taxonomy, conversion tracking, and data quality. Use when building a tracking plan from scratch, auditing existing analytics for gaps or errors, debugging missing events, or setting up GTM. Trigger keywords: GA4 setup, Google Tag Manager, GTM, event tracking, analytics implementation, conversion tracking, tracking plan, event taxonomy, custom dimensions, UTM tracking, analytics audit, missing events, tracking broken. NOT for analyzing marketing campaign data — use campaign-analytics for that. NOT for BI dashboards — use product-analytics for in-product event analysis.", "path": "marketing-skill/analytics-tracking" }, { @@ -766,7 +766,7 @@ }, { "name": "brand-guidelines", - "description": "When the user wants to apply, document, or enforce brand guidelines for any product or company. Also use when the user mentions 'brand guidelines,' 'brand colors,' 'typography,' 'logo usage,' 'brand voice,' 'visual identity,' 'tone of voice,' 'brand standards,' 'style guide,' 'brand consistency,' or 'company design standards.' Covers color systems, typography, logo rules, imagery guidelines, and tone matrix for any brand \u2014 including Anthropic's official identity.", + "description": "When the user wants to apply, document, or enforce brand guidelines for any product or company. Also use when the user mentions 'brand guidelines,' 'brand colors,' 'typography,' 'logo usage,' 'brand voice,' 'visual identity,' 'tone of voice,' 'brand standards,' 'style guide,' 'brand consistency,' or 'company design standards.' Covers color systems, typography, logo rules, imagery guidelines, and tone matrix for any brand — including Anthropic's official identity.", "path": "marketing-skill/brand-guidelines" }, { @@ -776,12 +776,12 @@ }, { "name": "churn-prevention", - "description": "Reduce voluntary and involuntary churn through cancel flow design, save offers, exit surveys, and dunning sequences. Use when designing or optimizing a cancel flow, building save offers, setting up dunning emails, or reducing failed-payment churn. Trigger keywords: cancel flow, churn reduction, save offers, dunning, exit survey, payment recovery, win-back, involuntary churn, failed payments, cancel page. NOT for customer health scoring or expansion revenue \u2014 use customer-success-manager for that.", + "description": "Reduce voluntary and involuntary churn through cancel flow design, save offers, exit surveys, and dunning sequences. Use when designing or optimizing a cancel flow, building save offers, setting up dunning emails, or reducing failed-payment churn. Trigger keywords: cancel flow, churn reduction, save offers, dunning, exit survey, payment recovery, win-back, involuntary churn, failed payments, cancel page. NOT for customer health scoring or expansion revenue — use customer-success-manager for that.", "path": "marketing-skill/churn-prevention" }, { "name": "cold-email", - "description": "When the user wants to write, improve, or build a sequence of B2B cold outreach emails to prospects who haven't asked to hear from them. Use when the user mentions 'cold email,' 'cold outreach,' 'prospecting emails,' 'SDR emails,' 'sales emails,' 'first touch email,' 'follow-up sequence,' or 'email prospecting.' Also use when they share an email draft that sounds too sales-y and needs to be humanized. Distinct from email-sequence (lifecycle/nurture to opted-in subscribers) \u2014 this is unsolicited outreach to new prospects. NOT for lifecycle emails, newsletters, or drip campaigns (use email-sequence).", + "description": "When the user wants to write, improve, or build a sequence of B2B cold outreach emails to prospects who haven't asked to hear from them. Use when the user mentions 'cold email,' 'cold outreach,' 'prospecting emails,' 'SDR emails,' 'sales emails,' 'first touch email,' 'follow-up sequence,' or 'email prospecting.' Also use when they share an email draft that sounds too sales-y and needs to be humanized. Distinct from email-sequence (lifecycle/nurture to opted-in subscribers) — this is unsolicited outreach to new prospects. NOT for lifecycle emails, newsletters, or drip campaigns (use email-sequence).", "path": "marketing-skill/cold-email" }, { @@ -791,17 +791,17 @@ }, { "name": "content-creator", - "description": "Deprecated redirect skill that routes legacy 'content creator' requests to the correct specialist. Use when a user invokes 'content creator', asks to write a blog post, article, guide, or brand voice analysis (routes to content-production), or asks to plan content, build a topic cluster, or create a content calendar (routes to content-strategy). Does not handle requests directly \u2014 identifies user intent and redirects to content-production for writing/SEO/brand-voice tasks or content-strategy for planning tasks.", + "description": "Deprecated redirect skill that routes legacy 'content creator' requests to the correct specialist. Use when a user invokes 'content creator', asks to write a blog post, article, guide, or brand voice analysis (routes to content-production), or asks to plan content, build a topic cluster, or create a content calendar (routes to content-strategy). Does not handle requests directly — identifies user intent and redirects to content-production for writing/SEO/brand-voice tasks or content-strategy for planning tasks.", "path": "marketing-skill/content-creator" }, { "name": "content-humanizer", - "description": "Makes AI-generated content sound genuinely human \u2014 not just cleaned up, but alive. Use when content feels robotic, uses too many AI clich\u00e9s, lacks personality, or reads like it was written by committee. Triggers: 'this sounds like AI', 'make it more human', 'add personality', 'it feels generic', 'sounds robotic', 'fix AI writing', 'inject our voice'. NOT for initial content creation (use content-production). NOT for SEO optimization (use content-production Mode 3).", + "description": "Makes AI-generated content sound genuinely human — not just cleaned up, but alive. Use when content feels robotic, uses too many AI clichés, lacks personality, or reads like it was written by committee. Triggers: 'this sounds like AI', 'make it more human', 'add personality', 'it feels generic', 'sounds robotic', 'fix AI writing', 'inject our voice'. NOT for initial content creation (use content-production). NOT for SEO optimization (use content-production Mode 3).", "path": "marketing-skill/content-humanizer" }, { "name": "content-production", - "description": "Full content production pipeline \u2014 takes a topic from blank page to published-ready piece. Use when you need to execute content: write a blog post, article, or guide end-to-end. Triggers: 'write a post about', 'draft an article', 'create content for', 'help me write', 'I need a blog post'. NOT for content strategy or calendar planning (use content-strategy). NOT for repurposing existing content (use content-repurposing). NOT for social captions only.", + "description": "Full content production pipeline — takes a topic from blank page to published-ready piece. Use when you need to execute content: write a blog post, article, or guide end-to-end. Triggers: 'write a post about', 'draft an article', 'create content for', 'help me write', 'I need a blog post'. NOT for content strategy or calendar planning (use content-strategy). NOT for repurposing existing content (use content-repurposing). NOT for social captions only.", "path": "marketing-skill/content-production" }, { @@ -816,7 +816,7 @@ }, { "name": "copywriting", - "description": "When the user wants to write, rewrite, or improve marketing copy for any page \u2014 including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says \\\"write copy for,\\\" \\\"improve this copy,\\\" \\\"rewrite this page,\\\" \\\"marketing copy,\\\" \\\"headline help,\\\" or \\\"CTA copy.\\\" For email copy, see email-sequence. For popup copy, see popup-cro.", + "description": "When the user wants to write, rewrite, or improve marketing copy for any page — including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says \\\"write copy for,\\\" \\\"improve this copy,\\\" \\\"rewrite this page,\\\" \\\"marketing copy,\\\" \\\"headline help,\\\" or \\\"CTA copy.\\\" For email copy, see email-sequence. For popup copy, see popup-cro.", "path": "marketing-skill/copywriting" }, { @@ -826,12 +826,12 @@ }, { "name": "form-cro", - "description": "When the user wants to optimize any form that is NOT signup/registration \u2014 including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions \"form optimization,\" \"lead form conversions,\" \"form friction,\" \"form fields,\" \"form completion rate,\" or \"contact form.\" For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro.", + "description": "When the user wants to optimize any form that is NOT signup/registration — including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions \"form optimization,\" \"lead form conversions,\" \"form friction,\" \"form fields,\" \"form completion rate,\" or \"contact form.\" For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro.", "path": "marketing-skill/form-cro" }, { "name": "free-tool-strategy", - "description": "When the user wants to build a free tool for marketing \u2014 lead generation, SEO value, or brand awareness. Use when they mention 'engineering as marketing,' 'free tool,' 'calculator,' 'generator,' 'checker,' 'grader,' 'marketing tool,' 'lead gen tool,' 'build something for traffic,' 'interactive tool,' or 'free resource.' Covers idea evaluation, tool design, and launch strategy. For pure SEO content strategy (no tool), use seo-audit or content-strategy instead.", + "description": "When the user wants to build a free tool for marketing — lead generation, SEO value, or brand awareness. Use when they mention 'engineering as marketing,' 'free tool,' 'calculator,' 'generator,' 'checker,' 'grader,' 'marketing tool,' 'lead gen tool,' 'build something for traffic,' 'interactive tool,' or 'free resource.' Covers idea evaluation, tool design, and launch strategy. For pure SEO content strategy (no tool), use seo-audit or content-strategy instead.", "path": "marketing-skill/free-tool-strategy" }, { @@ -881,7 +881,7 @@ }, { "name": "page-cro", - "description": "When the user wants to optimize, improve, or increase conversions on any marketing page \u2014 including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says \"CRO,\" \"conversion rate optimization,\" \"this page isn't converting,\" \"improve conversions,\" or \"why isn't this page working.\" For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro.", + "description": "When the user wants to optimize, improve, or increase conversions on any marketing page — including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says \"CRO,\" \"conversion rate optimization,\" \"this page isn't converting,\" \"improve conversions,\" or \"why isn't this page working.\" For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro.", "path": "marketing-skill/page-cro" }, { @@ -891,7 +891,7 @@ }, { "name": "paywall-upgrade-cro", - "description": "When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions \"paywall,\" \"upgrade screen,\" \"upgrade modal,\" \"upsell,\" \"feature gate,\" \"convert free to paid,\" \"freemium conversion,\" \"trial expiration screen,\" \"limit reached screen,\" \"plan upgrade prompt,\" or \"in-app pricing.\" Distinct from public pricing pages (see page-cro) \u2014 this skill focuses on in-product upgrade moments where the user has already experienced value.", + "description": "When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions \"paywall,\" \"upgrade screen,\" \"upgrade modal,\" \"upsell,\" \"feature gate,\" \"convert free to paid,\" \"freemium conversion,\" \"trial expiration screen,\" \"limit reached screen,\" \"plan upgrade prompt,\" or \"in-app pricing.\" Distinct from public pricing pages (see page-cro) — this skill focuses on in-product upgrade moments where the user has already experienced value.", "path": "marketing-skill/paywall-upgrade-cro" }, { @@ -901,7 +901,7 @@ }, { "name": "pricing-strategy", - "description": "Design, optimize, and communicate SaaS pricing \u2014 tier structure, value metrics, pricing pages, and price increase strategy. Use when building a pricing model from scratch, redesigning existing pricing, planning a price increase, or improving a pricing page. Trigger keywords: pricing tiers, pricing page, price increase, packaging, value metric, per seat pricing, usage-based pricing, freemium, good-better-best, pricing strategy, monetization, pricing page conversion, Van Westendorp. NOT for broader product strategy \u2014 use product-strategist for that. NOT for customer success or renewals \u2014 use customer-success-manager for expansion revenue.", + "description": "Design, optimize, and communicate SaaS pricing — tier structure, value metrics, pricing pages, and price increase strategy. Use when building a pricing model from scratch, redesigning existing pricing, planning a price increase, or improving a pricing page. Trigger keywords: pricing tiers, pricing page, price increase, packaging, value metric, per seat pricing, usage-based pricing, freemium, good-better-best, pricing strategy, monetization, pricing page conversion, Van Westendorp. NOT for broader product strategy — use product-strategist for that. NOT for customer success or renewals — use customer-success-manager for expansion revenue.", "path": "marketing-skill/pricing-strategy" }, { @@ -916,7 +916,7 @@ }, { "name": "referral-program", - "description": "When the user wants to design, launch, or optimize a referral or affiliate program. Use when they mention 'referral program,' 'affiliate program,' 'word of mouth,' 'refer a friend,' 'incentive program,' 'customer referrals,' 'brand ambassador,' 'partner program,' 'referral link,' or 'growth through referrals.' Covers program mechanics, incentive design, and optimization \u2014 not just the idea of referrals but the actual system.", + "description": "When the user wants to design, launch, or optimize a referral or affiliate program. Use when they mention 'referral program,' 'affiliate program,' 'word of mouth,' 'refer a friend,' 'incentive program,' 'customer referrals,' 'brand ambassador,' 'partner program,' 'referral link,' or 'growth through referrals.' Covers program mechanics, incentive design, and optimization — not just the idea of referrals but the actual system.", "path": "marketing-skill/referral-program" }, { @@ -1003,17 +1003,17 @@ }, { "name": "chief-ai-officer-advisor", - "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only \u2014 does not duplicate engineering AI/ML skills.", + "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only — does not duplicate engineering AI/ML skills.", "path": "c-level-advisor/chief-ai-officer-advisor" }, { "name": "chief-customer-officer-advisor", - "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only \u2014 does not duplicate engineering/business-growth tactical skills.", + "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only — does not duplicate engineering/business-growth tactical skills.", "path": "c-level-advisor/chief-customer-officer-advisor" }, { "name": "chief-data-officer-advisor", - "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill \u2014 strategic decisions only.", + "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill — strategic decisions only.", "path": "c-level-advisor/chief-data-officer-advisor" }, { @@ -1038,7 +1038,7 @@ }, { "name": "company-os", - "description": "The meta-framework for how a company runs \u2014 the connective tissue between all C-suite roles. Covers operating system selection (EOS, Scaling Up, OKR-native, hybrid), accountability charts, scorecards, meeting pulse, issue resolution, and 90-day rocks. Use when setting up company operations, selecting a management framework, designing meeting rhythms, building accountability systems, implementing OKRs, or when user mentions EOS, Scaling Up, operating system, L10 meetings, rocks, scorecard, accountability chart, or quarterly planning.", + "description": "The meta-framework for how a company runs — the connective tissue between all C-suite roles. Covers operating system selection (EOS, Scaling Up, OKR-native, hybrid), accountability charts, scorecards, meeting pulse, issue resolution, and 90-day rocks. Use when setting up company operations, selecting a management framework, designing meeting rhythms, building accountability systems, implementing OKRs, or when user mentions EOS, Scaling Up, operating system, L10 meetings, rocks, scorecard, accountability chart, or quarterly planning.", "path": "c-level-advisor/company-os" }, { @@ -1078,7 +1078,7 @@ }, { "name": "culture-architect", - "description": "Build, measure, and evolve company culture as operational behavior \u2014 not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code.", + "description": "Build, measure, and evolve company culture as operational behavior — not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code.", "path": "c-level-advisor/culture-architect" }, { @@ -1093,12 +1093,12 @@ }, { "name": "general-counsel-advisor", - "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel \u2014 surfaces questions to bring to qualified attorneys.", + "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel — surfaces questions to bring to qualified attorneys.", "path": "c-level-advisor/general-counsel-advisor" }, { "name": "internal-narrative", - "description": "Build and maintain one coherent company story across all audiences \u2014 employees, investors, customers, candidates, and partners. Detects narrative contradictions and ensures the same truth is framed for each audience's needs. Use when preparing investor updates, all-hands presentations, board communications, recruiting narratives, crisis communications, or when user mentions company narrative, messaging consistency, storytelling, all-hands, investor update, or crisis communication.", + "description": "Build and maintain one coherent company story across all audiences — employees, investors, customers, candidates, and partners. Detects narrative contradictions and ensures the same truth is framed for each audience's needs. Use when preparing investor updates, all-hands presentations, board communications, recruiting narratives, crisis communications, or when user mentions company narrative, messaging consistency, storytelling, all-hands, investor update, or crisis communication.", "path": "c-level-advisor/internal-narrative" }, { @@ -1128,132 +1128,132 @@ }, { "name": "vpe-advisor", - "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships.", + "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing → screen → onsite → offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) — VPE owns delivery operations and how the team ships.", "path": "c-level-advisor/vpe-advisor" }, { "name": "boardroom", - "description": "/cs:boardroom \u2014 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo.", + "description": "/cs:boardroom — 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo.", "path": "c-level-advisor/boardroom" }, { "name": "brief", - "description": "/cs:brief \u2014 Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline.", + "description": "/cs:brief — Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline.", "path": "c-level-advisor/brief" }, { "name": "c-level-agents", "description": "Founder-mode executive team. 8 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, Chief of Staff) and 17 /cs:* slash commands for forcing-question office hours, multi-role boardroom deliberation, strategic sprint pipeline, and meta routing. Use when the founder needs a virtual executive team, when invoking /cs:* commands, or when orchestrating multi-role decisions.", - "path": "c-level-advisor/c-level-agents" + "path": "c-level-agents" }, { "name": "caio-review", - "description": "/cs:caio-review \u2014 Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring.", + "description": "/cs:caio-review — Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring.", "path": "c-level-advisor/caio-review" }, { "name": "cco-review", - "description": "/cs:cco-review \u2014 Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring.", + "description": "/cs:cco-review — Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring.", "path": "c-level-advisor/cco-review" }, { "name": "cdo-review", - "description": "/cs:cdo-review \u2014 Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring.", + "description": "/cs:cdo-review — Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring.", "path": "c-level-advisor/cdo-review" }, { "name": "cfo-review", - "description": "/cs:cfo-review \u2014 Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation.", + "description": "/cs:cfo-review — Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation.", "path": "c-level-advisor/cfo-review" }, { "name": "ciso-review", - "description": "/cs:ciso-review \u2014 Risk-paranoid interrogation of any plan that touches data, compliance, or production access.", + "description": "/cs:ciso-review — Risk-paranoid interrogation of any plan that touches data, compliance, or production access.", "path": "c-level-advisor/ciso-review" }, { "name": "cmo-review", - "description": "/cs:cmo-review \u2014 Narrative-first interrogation of positioning, ICP, message house, and channel mix.", + "description": "/cs:cmo-review — Narrative-first interrogation of positioning, ICP, message house, and channel mix.", "path": "c-level-advisor/cmo-review" }, { "name": "cpo-review", - "description": "/cs:cpo-review \u2014 JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus.", + "description": "/cs:cpo-review — JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus.", "path": "c-level-advisor/cpo-review" }, { "name": "cro-review", - "description": "/cs:cro-review \u2014 Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time.", + "description": "/cs:cro-review — Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time.", "path": "c-level-advisor/cro-review" }, { "name": "cross-eval", - "description": "/cs:cross-eval \u2014 Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation.", + "description": "/cs:cross-eval — Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation.", "path": "c-level-advisor/cross-eval" }, { "name": "cto-review", - "description": "/cs:cto-review \u2014 Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy.", + "description": "/cs:cto-review — Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy.", "path": "c-level-advisor/cto-review" }, { "name": "decide", - "description": "/cs:decide \u2014 Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference.", + "description": "/cs:decide — Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference.", "path": "c-level-advisor/decide" }, { "name": "execute", - "description": "/cs:execute \u2014 Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision.", + "description": "/cs:execute — Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision.", "path": "c-level-advisor/execute" }, { "name": "founder-mode", - "description": "/cs:founder-mode \u2014 Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point.", + "description": "/cs:founder-mode — Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point.", "path": "c-level-advisor/founder-mode" }, { "name": "freeze", - "description": "/cs:freeze \u2014 Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer.", + "description": "/cs:freeze — Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer.", "path": "c-level-advisor/freeze" }, { "name": "gc-review", - "description": "/cs:gc-review \u2014 General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface.", + "description": "/cs:gc-review — General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface.", "path": "c-level-advisor/gc-review" }, { "name": "office-hours", - "description": "/cs:office-hours \u2014 YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit.", + "description": "/cs:office-hours — YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit.", "path": "c-level-advisor/office-hours" }, { "name": "onboard", - "description": "/cs:onboard \u2014 Founder interview that populates ~/.claude/company-context.md. The first command to run when starting with c-level-agents.", + "description": "/cs:onboard — Founder interview that populates ~/.claude/company-context.md. The first command to run when starting with c-level-agents.", "path": "c-level-advisor/onboard" }, { "name": "post-mortem", - "description": "/cs:post-mortem \u2014 Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop.", + "description": "/cs:post-mortem — Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop.", "path": "c-level-advisor/post-mortem" }, { "name": "vpe-review", - "description": "/cs:vpe-review \u2014 Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline.", + "description": "/cs:vpe-review — Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline.", "path": "c-level-advisor/vpe-review" }, { "name": "chief-ai-officer-advisor", - "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only \u2014 does not duplicate engineering AI/ML skills.", + "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only — does not duplicate engineering AI/ML skills.", "path": "c-level-advisor/chief-ai-officer-advisor" }, { "name": "chief-customer-officer-advisor", - "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only \u2014 does not duplicate engineering/business-growth tactical skills.", + "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only — does not duplicate engineering/business-growth tactical skills.", "path": "c-level-advisor/chief-customer-officer-advisor" }, { "name": "chief-data-officer-advisor", - "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill \u2014 strategic decisions only.", + "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill — strategic decisions only.", "path": "c-level-advisor/chief-data-officer-advisor" }, { @@ -1273,27 +1273,27 @@ }, { "name": "hard-call", - "description": "/em -hard-call \u2014 Framework for Decisions With No Good Options", + "description": "/em -hard-call — Framework for Decisions With No Good Options", "path": "c-level-advisor/hard-call" }, { "name": "postmortem", - "description": "/em -postmortem \u2014 Honest Analysis of What Went Wrong", + "description": "/em -postmortem — Honest Analysis of What Went Wrong", "path": "c-level-advisor/postmortem" }, { "name": "stress-test", - "description": "/em -stress-test \u2014 Business Assumption Stress Testing", + "description": "/em -stress-test — Business Assumption Stress Testing", "path": "c-level-advisor/stress-test" }, { "name": "general-counsel-advisor", - "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel \u2014 surfaces questions to bring to qualified attorneys.", + "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel — surfaces questions to bring to qualified attorneys.", "path": "c-level-advisor/general-counsel-advisor" }, { "name": "vpe-advisor", - "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships.", + "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing → screen → onsite → offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) — VPE owns delivery operations and how the team ships.", "path": "c-level-advisor/vpe-advisor" } ], @@ -1320,7 +1320,7 @@ }, { "name": "meeting-analyzer", - "description": "Analyzes meeting transcripts and recordings to surface behavioral patterns, communication anti-patterns, and actionable coaching feedback. Use this skill whenever the user uploads or points to meeting transcripts (.txt, .md, .vtt, .srt, .docx), asks about their communication habits, wants feedback on how they run meetings, requests speaking ratio analysis, mentions filler words or conflict avoidance, or wants to compare their communication across time periods. Also trigger when users mention tools like Granola, Otter, Fireflies, or Zoom transcripts. Even if the user just says \"look at my meetings\" or \"how do I come across in meetings\" \u2014 use this skill.", + "description": "Analyzes meeting transcripts and recordings to surface behavioral patterns, communication anti-patterns, and actionable coaching feedback. Use this skill whenever the user uploads or points to meeting transcripts (.txt, .md, .vtt, .srt, .docx), asks about their communication habits, wants feedback on how they run meetings, requests speaking ratio analysis, mentions filler words or conflict avoidance, or wants to compare their communication across time periods. Also trigger when users mention tools like Granola, Otter, Fireflies, or Zoom transcripts. Even if the user just says \"look at my meetings\" or \"how do I come across in meetings\" — use this skill.", "path": "project-management/meeting-analyzer" }, { @@ -1335,12 +1335,12 @@ }, { "name": "senior-pm", - "description": "Senior Project Manager for enterprise software, SaaS, and digital transformation projects. Specializes in portfolio management, quantitative risk analysis, resource optimization, stakeholder alignment, and executive reporting. Uses advanced methodologies including EMV analysis, Monte Carlo simulation, WSJF prioritization, and multi-dimensional health scoring. Use when a user needs help with project plans, project status reports, risk assessments, resource allocation, project roadmaps, milestone tracking, team capacity planning, portfolio health reviews, program management, or executive-level project reporting \u2014 especially for enterprise-scale initiatives with multiple workstreams, complex dependencies, or multi-million dollar budgets.", + "description": "Senior Project Manager for enterprise software, SaaS, and digital transformation projects. Specializes in portfolio management, quantitative risk analysis, resource optimization, stakeholder alignment, and executive reporting. Uses advanced methodologies including EMV analysis, Monte Carlo simulation, WSJF prioritization, and multi-dimensional health scoring. Use when a user needs help with project plans, project status reports, risk assessments, resource allocation, project roadmaps, milestone tracking, team capacity planning, portfolio health reviews, program management, or executive-level project reporting — especially for enterprise-scale initiatives with multiple workstreams, complex dependencies, or multi-million dollar budgets.", "path": "project-management/senior-pm" }, { "name": "team-communications", - "description": "Write internal company communications \u2014 3P updates (Progress/Plans/Problems), company-wide newsletters, FAQ roundups, incident reports, leadership updates, status reports, project updates, and general internal comms. Use this skill any time the user asks to draft, edit, or format something meant for internal audiences. Trigger on keywords like \"3P\", \"weekly update\", \"newsletter\", \"FAQ\", \"internal comms\", \"status report\", \"company update\", \"team update\", \"incident report\", or any request to summarize work for leadership, teammates, or the broader company. Even casual requests like \"write my update\" or \"summarize what my team did this week\" should trigger this skill.", + "description": "Write internal company communications — 3P updates (Progress/Plans/Problems), company-wide newsletters, FAQ roundups, incident reports, leadership updates, status reports, project updates, and general internal comms. Use this skill any time the user asks to draft, edit, or format something meant for internal audiences. Trigger on keywords like \"3P\", \"weekly update\", \"newsletter\", \"FAQ\", \"internal comms\", \"status report\", \"company update\", \"team update\", \"incident report\", or any request to summarize work for leadership, teammates, or the broader company. Even casual requests like \"write my update\" or \"summarize what my team did this week\" should trigger this skill.", "path": "project-management/team-communications" } ], @@ -1352,7 +1352,7 @@ }, { "name": "eu-ai-act-specialist", - "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system \u2014 prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", + "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system — prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", "path": "ra-qm-team/eu-ai-act-specialist" }, { @@ -1427,7 +1427,7 @@ }, { "name": "eu-ai-act-specialist", - "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system \u2014 prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", + "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system — prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", "path": "ra-qm-team/eu-ai-act-specialist" }, { @@ -1444,7 +1444,7 @@ }, { "name": "contract-and-proposal-writer", - "description": "Generate professional, jurisdiction-aware business documents: freelance contracts, project proposals, SOWs, NDAs, and MSAs. Structured Markdown output with docx conversion instructions. Covers US (Delaware), EU (GDPR), UK, and DACH (German law) jurisdictions. Not a substitute for legal counsel \u2014 use as strong starting points. Use when drafting a freelance contract, preparing a client proposal, writing an SOW for a new engagement, or producing an NDA before sharing sensitive material.", + "description": "Generate professional, jurisdiction-aware business documents: freelance contracts, project proposals, SOWs, NDAs, and MSAs. Structured Markdown output with docx conversion instructions. Covers US (Delaware), EU (GDPR), UK, and DACH (German law) jurisdictions. Not a substitute for legal counsel — use as strong starting points. Use when drafting a freelance contract, preparing a client proposal, writing an SOW for a new engagement, or producing an NDA before sharing sensitive material.", "path": "business-growth/contract-and-proposal-writer" }, { @@ -1488,7 +1488,7 @@ "productivity": [ { "name": "capture", - "description": "Captures and organizes chaotic brain dumps into a structured, actionable system with zero information loss. Use this skill whenever the user says 'capture this', 'brain dump', 'let me dump some ideas', 'I've got a bunch of thoughts', 'here's everything on my mind', 'idea dump', 'let me get this out of my head', 'I need to organize my thoughts', 'here's what I'm thinking', or any variation where someone is unloading a messy stream of ideas, tasks, thoughts, and plans wanting them turned into something coherent. Also trigger when the user pastes or dictates a long, unstructured block of mixed ideas \u2014 even without the exact phrase \u2014 the intent is the same. Fast-to-action by design: no upfront intake. Output is four sections (Projects/Ideas, Tasks, Connections, How I Can Help) ending with a directive question. Asks at most one mid-organization clarifying question when a single item is genuinely ambiguous between task and project.", + "description": "Captures and organizes chaotic brain dumps into a structured, actionable system with zero information loss. Use this skill whenever the user says 'capture this', 'brain dump', 'let me dump some ideas', 'I've got a bunch of thoughts', 'here's everything on my mind', 'idea dump', 'let me get this out of my head', 'I need to organize my thoughts', 'here's what I'm thinking', or any variation where someone is unloading a messy stream of ideas, tasks, thoughts, and plans wanting them turned into something coherent. Also trigger when the user pastes or dictates a long, unstructured block of mixed ideas — even without the exact phrase — the intent is the same. Fast-to-action by design: no upfront intake. Output is four sections (Projects/Ideas, Tasks, Connections, How I Can Help) ending with a directive question. Asks at most one mid-organization clarifying question when a single item is genuinely ambiguous between task and project.", "path": "productivity/capture" }, { @@ -1503,7 +1503,7 @@ }, { "name": "reflect", - "description": "Mid-conversation reflection skill that pauses execution and zooms out from detail-mode to honestly reassess direction, assumptions, and bias. Use when the user says 'reflect', 'take a step back', 'step back', 'zoom out', 'are we missing something', 'bigger picture', 'sanity check this', 'are we on track', 'are we overthinking this', 'forest for the trees', or any variation signaling intent to break out of detail-mode and reassess. Also trigger when the conversation has gone deep on implementation details without strategic check-in, or when the user shows signs of being stuck \u2014 that's often a signal the framing needs a reset, not more detail work. Intentionally low-intake: runs the 5-dimension analysis immediately when prior context is rich enough; asks one forcing clarifier only when invocation context is too thin to reassess from.", + "description": "Mid-conversation reflection skill that pauses execution and zooms out from detail-mode to honestly reassess direction, assumptions, and bias. Use when the user says 'reflect', 'take a step back', 'step back', 'zoom out', 'are we missing something', 'bigger picture', 'sanity check this', 'are we on track', 'are we overthinking this', 'forest for the trees', or any variation signaling intent to break out of detail-mode and reassess. Also trigger when the conversation has gone deep on implementation details without strategic check-in, or when the user shows signs of being stuck — that's often a signal the framing needs a reset, not more detail work. Intentionally low-intake: runs the 5-dimension analysis immediately when prior context is rich enough; asks one forcing clarifier only when invocation context is too thin to reassess from.", "path": "productivity/reflect" } ], @@ -1517,27 +1517,27 @@ "research": [ { "name": "dossier", - "description": "Decision-grade entity research skill \u2014 produces a hypothesis-tested dossier on a specific company, person, nonprofit, or government org, not a generic profile. Forcing intake makes the user state their hypothesis upfront (what they already believe and want to verify or disprove) so the dossier tests it rather than confirms it. Output is an editable Word document (.docx) with verdict on the hypothesis, identity facts, 12-month activity timeline, network signals, reputation signals, red flags, 3-5 conversation hooks tied to specific findings, and source-provenance audit log. Uses WebSearch + WebFetch + free APIs (SEC EDGAR, GitHub, ProPublica Nonprofit Explorer) as workhorses; optional BYOK MCPs (LinkedIn, Crunchbase, Apollo, Pitchbook, SimilarWeb) enhance coverage. Triggers: 'research [company]', 'dossier on [person/company]', 'background check on [entity]', 'prep me for a meeting with [person/company]', 'due diligence on [company]', 'what should I know about [entity]', 'research [person] before I [meet/hire/invest]', 'competitor research on [company]', 'investor diligence [company]', 'interview prep for [company]'. Honors sensitivity exclusions for journalism + personal-vetting contexts.", + "description": "Decision-grade entity research skill — produces a hypothesis-tested dossier on a specific company, person, nonprofit, or government org, not a generic profile. Forcing intake makes the user state their hypothesis upfront (what they already believe and want to verify or disprove) so the dossier tests it rather than confirms it. Output is an editable Word document (.docx) with verdict on the hypothesis, identity facts, 12-month activity timeline, network signals, reputation signals, red flags, 3-5 conversation hooks tied to specific findings, and source-provenance audit log. Uses WebSearch + WebFetch + free APIs (SEC EDGAR, GitHub, ProPublica Nonprofit Explorer) as workhorses; optional BYOK MCPs (LinkedIn, Crunchbase, Apollo, Pitchbook, SimilarWeb) enhance coverage. Triggers: 'research [company]', 'dossier on [person/company]', 'background check on [entity]', 'prep me for a meeting with [person/company]', 'due diligence on [company]', 'what should I know about [entity]', 'research [person] before I [meet/hire/invest]', 'competitor research on [company]', 'investor diligence [company]', 'interview prep for [company]'. Honors sensitivity exclusions for journalism + personal-vetting contexts.", "path": "research/dossier" }, { "name": "grants", - "description": "NIH grant research skill for clinical researchers. Grill-me intake (research idea + career stage + preliminary data + environment + submission posture + known institute targets) locks down the funding strategy before any search runs. Runs a 5-facet Consensus positioning analysis (with draft Significance/Innovation language), maps the research to the right NIH institutes and study sections via RePORTER, finds NOSIs and funded overlap, and produces an editable Word document (.docx) with budget/scope-aware mechanism recommendations, submission timelines, and a mandatory program officer recommendation. Triggers: 'grants for [topic]', 'find grants for my research idea', 'what grants match my research', 'help me find NIH funding', 'grant opportunities for my research', or any grant-related request. NIH-only scope \u2014 non-NIH funders (PCORI, DOD CDMRP, VA, foundations) are out of scope and flagged at intake.", + "description": "NIH grant research skill for clinical researchers. Grill-me intake (research idea + career stage + preliminary data + environment + submission posture + known institute targets) locks down the funding strategy before any search runs. Runs a 5-facet Consensus positioning analysis (with draft Significance/Innovation language), maps the research to the right NIH institutes and study sections via RePORTER, finds NOSIs and funded overlap, and produces an editable Word document (.docx) with budget/scope-aware mechanism recommendations, submission timelines, and a mandatory program officer recommendation. Triggers: 'grants for [topic]', 'find grants for my research idea', 'what grants match my research', 'help me find NIH funding', 'grant opportunities for my research', or any grant-related request. NIH-only scope — non-NIH funders (PCORI, DOD CDMRP, VA, foundations) are out of scope and flagged at intake.", "path": "research/grants" }, { "name": "litreview", - "description": "Academic literature orientation skill that searches papers via Consensus, builds a strategic search plan using PICO (default) or SPIDER / Decomposition / hybrid as fallbacks, and synthesizes findings into a professionally formatted Word document (.docx) research guide. Grill-me intake (research question specificity + framework hint + tentative depth) before the recon search; a second forcing checkpoint after Phase 2 confirms framework + sub-areas + depth before searches consume budget. Configurable depth (5/10/20 queries) controls coverage vs. speed. Output is a 'launching pad' \u2014 not a finished review, but an orientation guide that lets a researcher dive in confidently. Triggers: 'litreview on [topic]', 'literature review on [topic]', 'I'm starting a literature review on X', 'I'm writing a paper on X', 'help me research X', 'I'm doing research on X', 'can you help me research X'. Do NOT trigger for single one-off paper searches where the user just wants a quick list \u2014 that's a plain Consensus search.", + "description": "Academic literature orientation skill that searches papers via Consensus, builds a strategic search plan using PICO (default) or SPIDER / Decomposition / hybrid as fallbacks, and synthesizes findings into a professionally formatted Word document (.docx) research guide. Grill-me intake (research question specificity + framework hint + tentative depth) before the recon search; a second forcing checkpoint after Phase 2 confirms framework + sub-areas + depth before searches consume budget. Configurable depth (5/10/20 queries) controls coverage vs. speed. Output is a 'launching pad' — not a finished review, but an orientation guide that lets a researcher dive in confidently. Triggers: 'litreview on [topic]', 'literature review on [topic]', 'I'm starting a literature review on X', 'I'm writing a paper on X', 'help me research X', 'I'm doing research on X', 'can you help me research X'. Do NOT trigger for single one-off paper searches where the user just wants a quick list — that's a plain Consensus search.", "path": "research/litreview" }, { "name": "notebooklm", - "description": "Browser automation skill for controlling Google's NotebookLM. Handles reading and querying notebooks, adding sources (URLs, text, files, YouTube links, synthesized content), generating Studio outputs (Audio Overview, infographics, slide decks, study guides, briefing docs, mind maps, timelines, FAQs), and creating new notebooks. Triggers on any phrase involving NotebookLM \u2014 'open NotebookLM', 'check my [name] notebook', 'pull info from NotebookLM', 'ask my notebook about X', 'add [source] to NotebookLM', 'create an infographic in NotebookLM', 'use NotebookLM Studio', 'generate a slide deck from my notebook', or any variation where the goal involves NotebookLM. Requires browser automation environment \u2014 fails gracefully when unavailable.", + "description": "Browser automation skill for controlling Google's NotebookLM. Handles reading and querying notebooks, adding sources (URLs, text, files, YouTube links, synthesized content), generating Studio outputs (Audio Overview, infographics, slide decks, study guides, briefing docs, mind maps, timelines, FAQs), and creating new notebooks. Triggers on any phrase involving NotebookLM — 'open NotebookLM', 'check my [name] notebook', 'pull info from NotebookLM', 'ask my notebook about X', 'add [source] to NotebookLM', 'create an infographic in NotebookLM', 'use NotebookLM Studio', 'generate a slide deck from my notebook', or any variation where the goal involves NotebookLM. Requires browser automation environment — fails gracefully when unavailable.", "path": "research/notebooklm" }, { "name": "patent", - "description": "Patent prior-art and landscape intelligence skill \u2014 not generic patent help. Commits to one of five sub-use-cases via forcing intake (novelty search / freedom-to-operate / competitive landscape / acquisition diligence / litigation prior-art) before any search runs. Searches Google Patents, Espacenet, USPTO, and optionally Lens.org for citation-graph signals. Output is an editable Word document (.docx) with verdict, ranked closest art (claim-text extracted), CPC-class-aware landscape, family-resolved hits, geographic coverage, FTO flags where applicable, strategy recommendations, and full audit log. Triggers: 'prior art search for [invention]', 'patent search on [topic]', 'freedom to operate analysis', 'FTO for [product]', 'patent landscape for [field]', 'is [invention] novel', 'patents on [topic]', 'competitive patent analysis', 'prior art for litigation', 'patent diligence on [company]'. Produces search signal, not legal advice \u2014 always recommends consulting a patent attorney before filing or licensing decisions. Trademark, copyright, and trade-secret questions are out of scope.", + "description": "Patent prior-art and landscape intelligence skill — not generic patent help. Commits to one of five sub-use-cases via forcing intake (novelty search / freedom-to-operate / competitive landscape / acquisition diligence / litigation prior-art) before any search runs. Searches Google Patents, Espacenet, USPTO, and optionally Lens.org for citation-graph signals. Output is an editable Word document (.docx) with verdict, ranked closest art (claim-text extracted), CPC-class-aware landscape, family-resolved hits, geographic coverage, FTO flags where applicable, strategy recommendations, and full audit log. Triggers: 'prior art search for [invention]', 'patent search on [topic]', 'freedom to operate analysis', 'FTO for [product]', 'patent landscape for [field]', 'is [invention] novel', 'patents on [topic]', 'competitive patent analysis', 'prior art for litigation', 'patent diligence on [company]'. Produces search signal, not legal advice — always recommends consulting a patent attorney before filing or licensing decisions. Trademark, copyright, and trade-secret questions are out of scope.", "path": "research/patent" }, { @@ -1547,14 +1547,14 @@ }, { "name": "research", - "description": "Default entry point for any research request \u2014 a hybrid router that classifies the question deterministically and either delegates to a specialist research skill (pulse for trends/sentiment, grants for NIH funding, litreview for academic literature, syllabus for course reading, patent for prior-art + IP landscape, dossier for entity research) or runs its own plan-decompose-multi-source-search-synthesize-cite fallback workflow when no specialist matches. Always surfaces the routing decision so users can override. Triggers \u2014 \"research [topic]\", \"look into [topic]\", \"what do we know about [topic]\", \"investigate [topic]\", \"find me information on [topic]\", \"do some research on [topic]\", \"I need to understand [topic]\", or any research request that doesn't obviously match a more-specific specialist skill. Output is a markdown briefing (default) or .docx document (on request) with full citations and an audit log.", + "description": "Default entry point for any research request — a hybrid router that classifies the question deterministically and either delegates to a specialist research skill (pulse for trends/sentiment, grants for NIH funding, litreview for academic literature, syllabus for course reading, patent for prior-art + IP landscape, dossier for entity research) or runs its own plan-decompose-multi-source-search-synthesize-cite fallback workflow when no specialist matches. Always surfaces the routing decision so users can override. Triggers — \"research [topic]\", \"look into [topic]\", \"what do we know about [topic]\", \"investigate [topic]\", \"find me information on [topic]\", \"do some research on [topic]\", \"I need to understand [topic]\", or any research request that doesn't obviously match a more-specific specialist skill. Output is a markdown briefing (default) or .docx document (on request) with full citations and an audit log.", "path": "research/research" }, { "name": "syllabus", - "description": "Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs \u2014 so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Triggers whenever a user uploads a syllabus, course outline, or curriculum document and wants supplementary readings. Also triggers on: 'syllabus reading list', 'find papers for my course', 'create a reading list from this syllabus', 'recent research for my class', 'supplementary readings', 'find journal articles for these topics', 'what recent papers cover this material', 'any new research on these course topics', 'update my syllabus with recent papers'. Even casual mentions when a syllabus is attached should trigger this skill.", + "description": "Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs — so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Triggers whenever a user uploads a syllabus, course outline, or curriculum document and wants supplementary readings. Also triggers on: 'syllabus reading list', 'find papers for my course', 'create a reading list from this syllabus', 'recent research for my class', 'supplementary readings', 'find journal articles for these topics', 'what recent papers cover this material', 'any new research on these course topics', 'update my syllabus with recent papers'. Even casual mentions when a syllabus is attached should trigger this skill.", "path": "research/syllabus" } ] } -} \ No newline at end of file +} diff --git a/.vibe/skills/claude-skills/c-level-advisor/boardroom b/.vibe/skills/claude-skills/c-level-advisor/boardroom index 83fb5230..da752e6a 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/boardroom +++ b/.vibe/skills/claude-skills/c-level-advisor/boardroom @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/boardroom \ No newline at end of file +../../../../c-level-agents/skills/boardroom \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/brief b/.vibe/skills/claude-skills/c-level-advisor/brief index 7c7c4105..7fd1d947 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/brief +++ b/.vibe/skills/claude-skills/c-level-advisor/brief @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/brief \ No newline at end of file +../../../../c-level-agents/skills/brief \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/c-level-agents b/.vibe/skills/claude-skills/c-level-advisor/c-level-agents index 96178fee..01d3f69b 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/c-level-agents +++ b/.vibe/skills/claude-skills/c-level-advisor/c-level-agents @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/c-level-agents \ No newline at end of file +../../../../c-level-agents/skills/c-level-agents \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/caio-review b/.vibe/skills/claude-skills/c-level-advisor/caio-review index 9b5f38de..b70a391c 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/caio-review +++ b/.vibe/skills/claude-skills/c-level-advisor/caio-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/caio-review \ No newline at end of file +../../../../c-level-agents/skills/caio-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cco-review b/.vibe/skills/claude-skills/c-level-advisor/cco-review index 7213ca76..02735ec9 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cco-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cco-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cco-review \ No newline at end of file +../../../../c-level-agents/skills/cco-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cdo-review b/.vibe/skills/claude-skills/c-level-advisor/cdo-review index 58d35f46..55e18a4e 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cdo-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cdo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cdo-review \ No newline at end of file +../../../../c-level-agents/skills/cdo-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cfo-review b/.vibe/skills/claude-skills/c-level-advisor/cfo-review index d167d736..b7992d66 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cfo-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cfo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cfo-review \ No newline at end of file +../../../../c-level-agents/skills/cfo-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/ciso-review b/.vibe/skills/claude-skills/c-level-advisor/ciso-review index 2861dab6..901f5298 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/ciso-review +++ b/.vibe/skills/claude-skills/c-level-advisor/ciso-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/ciso-review \ No newline at end of file +../../../../c-level-agents/skills/ciso-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cmo-review b/.vibe/skills/claude-skills/c-level-advisor/cmo-review index 9f3af619..6400e2eb 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cmo-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cmo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cmo-review \ No newline at end of file +../../../../c-level-agents/skills/cmo-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cpo-review b/.vibe/skills/claude-skills/c-level-advisor/cpo-review index d74e4b8f..a20e8c45 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cpo-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cpo-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cpo-review \ No newline at end of file +../../../../c-level-agents/skills/cpo-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cro-review b/.vibe/skills/claude-skills/c-level-advisor/cro-review index e8575448..7c69c8c9 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cro-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cro-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cro-review \ No newline at end of file +../../../../c-level-agents/skills/cro-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cross-eval b/.vibe/skills/claude-skills/c-level-advisor/cross-eval index f71fb2cc..5d64720e 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cross-eval +++ b/.vibe/skills/claude-skills/c-level-advisor/cross-eval @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cross-eval \ No newline at end of file +../../../../c-level-agents/skills/cross-eval \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/cto-review b/.vibe/skills/claude-skills/c-level-advisor/cto-review index ae34b911..06ff1511 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/cto-review +++ b/.vibe/skills/claude-skills/c-level-advisor/cto-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/cto-review \ No newline at end of file +../../../../c-level-agents/skills/cto-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/decide b/.vibe/skills/claude-skills/c-level-advisor/decide index 104673bb..65f100fa 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/decide +++ b/.vibe/skills/claude-skills/c-level-advisor/decide @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/decide \ No newline at end of file +../../../../c-level-agents/skills/decide \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/execute b/.vibe/skills/claude-skills/c-level-advisor/execute index 14c56d76..3cd98daa 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/execute +++ b/.vibe/skills/claude-skills/c-level-advisor/execute @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/execute \ No newline at end of file +../../../../c-level-agents/skills/execute \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/founder-mode b/.vibe/skills/claude-skills/c-level-advisor/founder-mode index fb0bb211..f3319f24 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/founder-mode +++ b/.vibe/skills/claude-skills/c-level-advisor/founder-mode @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/founder-mode \ No newline at end of file +../../../../c-level-agents/skills/founder-mode \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/freeze b/.vibe/skills/claude-skills/c-level-advisor/freeze index 60f320f2..7549d40a 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/freeze +++ b/.vibe/skills/claude-skills/c-level-advisor/freeze @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/freeze \ No newline at end of file +../../../../c-level-agents/skills/freeze \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/gc-review b/.vibe/skills/claude-skills/c-level-advisor/gc-review index 96f566db..742b72b9 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/gc-review +++ b/.vibe/skills/claude-skills/c-level-advisor/gc-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/gc-review \ No newline at end of file +../../../../c-level-agents/skills/gc-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/office-hours b/.vibe/skills/claude-skills/c-level-advisor/office-hours index 475bdf47..ad336771 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/office-hours +++ b/.vibe/skills/claude-skills/c-level-advisor/office-hours @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/office-hours \ No newline at end of file +../../../../c-level-agents/skills/office-hours \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/onboard b/.vibe/skills/claude-skills/c-level-advisor/onboard index 4d40491e..4b693c47 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/onboard +++ b/.vibe/skills/claude-skills/c-level-advisor/onboard @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/onboard \ No newline at end of file +../../../../c-level-agents/skills/onboard \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/post-mortem b/.vibe/skills/claude-skills/c-level-advisor/post-mortem index 9c0e56a3..f8f661a8 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/post-mortem +++ b/.vibe/skills/claude-skills/c-level-advisor/post-mortem @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/post-mortem \ No newline at end of file +../../../../c-level-agents/skills/post-mortem \ No newline at end of file diff --git a/.vibe/skills/claude-skills/c-level-advisor/vpe-review b/.vibe/skills/claude-skills/c-level-advisor/vpe-review index bc22bb9a..47a99016 120000 --- a/.vibe/skills/claude-skills/c-level-advisor/vpe-review +++ b/.vibe/skills/claude-skills/c-level-advisor/vpe-review @@ -1 +1 @@ -../../../../c-level-advisor/c-level-agents/skills/vpe-review \ No newline at end of file +../../../../c-level-agents/skills/vpe-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/init b/.vibe/skills/claude-skills/engineering-team/init deleted file mode 120000 index c285e57a..00000000 --- a/.vibe/skills/claude-skills/engineering-team/init +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/playwright-pro/skills/init \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/memory-review b/.vibe/skills/claude-skills/engineering-team/memory-review new file mode 120000 index 00000000..a1aee6fb --- /dev/null +++ b/.vibe/skills/claude-skills/engineering-team/memory-review @@ -0,0 +1 @@ +../../../../engineering-team/self-improving-agent/skills/memory-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/memory-status b/.vibe/skills/claude-skills/engineering-team/memory-status new file mode 120000 index 00000000..23628479 --- /dev/null +++ b/.vibe/skills/claude-skills/engineering-team/memory-status @@ -0,0 +1 @@ +../../../../engineering-team/self-improving-agent/skills/memory-status \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/pw-init b/.vibe/skills/claude-skills/engineering-team/pw-init new file mode 120000 index 00000000..238ec8b6 --- /dev/null +++ b/.vibe/skills/claude-skills/engineering-team/pw-init @@ -0,0 +1 @@ +../../../../engineering-team/playwright-pro/skills/pw-init \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/pw-review b/.vibe/skills/claude-skills/engineering-team/pw-review new file mode 120000 index 00000000..c88ff4d1 --- /dev/null +++ b/.vibe/skills/claude-skills/engineering-team/pw-review @@ -0,0 +1 @@ +../../../../engineering-team/playwright-pro/skills/pw-review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/review b/.vibe/skills/claude-skills/engineering-team/review deleted file mode 120000 index 6562335f..00000000 --- a/.vibe/skills/claude-skills/engineering-team/review +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/playwright-pro/skills/review \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering-team/status b/.vibe/skills/claude-skills/engineering-team/status deleted file mode 120000 index 62619be4..00000000 --- a/.vibe/skills/claude-skills/engineering-team/status +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering-team/self-improving-agent/skills/status \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/ar-resume b/.vibe/skills/claude-skills/engineering/ar-resume new file mode 120000 index 00000000..8c56cf7c --- /dev/null +++ b/.vibe/skills/claude-skills/engineering/ar-resume @@ -0,0 +1 @@ +../../../../engineering/autoresearch-agent/skills/ar-resume \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/ar-status b/.vibe/skills/claude-skills/engineering/ar-status new file mode 120000 index 00000000..54df8ede --- /dev/null +++ b/.vibe/skills/claude-skills/engineering/ar-status @@ -0,0 +1 @@ +../../../../engineering/autoresearch-agent/skills/ar-status \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/hub-init b/.vibe/skills/claude-skills/engineering/hub-init new file mode 120000 index 00000000..6eee19f2 --- /dev/null +++ b/.vibe/skills/claude-skills/engineering/hub-init @@ -0,0 +1 @@ +../../../../engineering/agenthub/skills/hub-init \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/hub-status b/.vibe/skills/claude-skills/engineering/hub-status new file mode 120000 index 00000000..60aa7499 --- /dev/null +++ b/.vibe/skills/claude-skills/engineering/hub-status @@ -0,0 +1 @@ +../../../../engineering/agenthub/skills/hub-status \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/init b/.vibe/skills/claude-skills/engineering/init deleted file mode 120000 index 92ea232d..00000000 --- a/.vibe/skills/claude-skills/engineering/init +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/agenthub/skills/init \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/resume b/.vibe/skills/claude-skills/engineering/resume deleted file mode 120000 index 0ced05e0..00000000 --- a/.vibe/skills/claude-skills/engineering/resume +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/autoresearch-agent/skills/resume \ No newline at end of file diff --git a/.vibe/skills/claude-skills/engineering/status b/.vibe/skills/claude-skills/engineering/status deleted file mode 120000 index a1f9ba44..00000000 --- a/.vibe/skills/claude-skills/engineering/status +++ /dev/null @@ -1 +0,0 @@ -../../../../engineering/agenthub/skills/status \ No newline at end of file diff --git a/.vibe/skills/claude-skills/skills-index.json b/.vibe/skills/claude-skills/skills-index.json index 2be4bb63..1c3832c0 100644 --- a/.vibe/skills/claude-skills/skills-index.json +++ b/.vibe/skills/claude-skills/skills-index.json @@ -25,12 +25,12 @@ }, { "name": "book-to-skill", - "description": "Converts books, documentation folders, and source collections (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into structured agent skills \u2014 extracting named frameworks, principles, techniques, and anti-patterns into a master SKILL.md plus on-demand chapter files, a glossary, a patterns file, and a decision cheatsheet. Use when the user wants to study a document with an agent, apply an author's frameworks while working, turn internal docs or standards into a reusable knowledge base, or package a compiled book skill as a claude-skills plugin.", + "description": "Converts books, documentation folders, and source collections (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into structured agent skills — extracting named frameworks, principles, techniques, and anti-patterns into a master SKILL.md plus on-demand chapter files, a glossary, a patterns file, and a decision cheatsheet. Use when the user wants to study a document with an agent, apply an author's frameworks while working, turn internal docs or standards into a reusable knowledge base, or package a compiled book skill as a claude-skills plugin.", "path": "engineering/book-to-skill" }, { "name": "browser-automation", - "description": "Use when the user asks to automate browser tasks, scrape websites, fill forms, capture screenshots, extract structured data from web pages, or build web automation workflows. NOT for testing \u2014 use playwright-pro for that.", + "description": "Use when the user asks to automate browser tasks, scrape websites, fill forms, capture screenshots, extract structured data from web pages, or build web automation workflows. NOT for testing — use playwright-pro for that.", "path": "engineering/browser-automation" }, { @@ -45,7 +45,7 @@ }, { "name": "ci-cd-pipeline-builder", - "description": "Generate pragmatic CI/CD pipelines from detected project stack signals \u2014 fast baseline generation, repeatable checks, environment-aware deployment stages. Use when setting up CI for a new project, refactoring existing pipelines, or standardizing deployment workflows across multiple repos.", + "description": "Generate pragmatic CI/CD pipelines from detected project stack signals — fast baseline generation, repeatable checks, environment-aware deployment stages. Use when setting up CI for a new project, refactoring existing pipelines, or standardizing deployment workflows across multiple repos.", "path": "engineering/ci-cd-pipeline-builder" }, { @@ -90,7 +90,7 @@ }, { "name": "focused-fix", - "description": "Use when the user asks to fix, debug, or make a specific feature/module/area work end-to-end. Triggers: 'make X work', 'fix the Y feature', 'the Z module is broken', 'focus on [area]'. Not for quick single-bug fixes \u2014 this is for systematic deep-dive repair across all files and dependencies.", + "description": "Use when the user asks to fix, debug, or make a specific feature/module/area work end-to-end. Triggers: 'make X work', 'fix the Y feature', 'the Z module is broken', 'focus on [area]'. Not for quick single-bug fixes — this is for systematic deep-dive repair across all files and dependencies.", "path": "engineering/focused-fix" }, { @@ -110,7 +110,7 @@ }, { "name": "kubernetes-operator", - "description": "Use when building a Kubernetes Operator \u2014 custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill \u2014 specifically the Operator pattern.", + "description": "Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill — specifically the Operator pattern.", "path": "engineering/kubernetes-operator" }, { @@ -155,7 +155,7 @@ }, { "name": "runbook-generator", - "description": "Generate operational runbooks from a service name \u2014 deployment, incident response, maintenance, and rollback workflows. Templated structure customizable per environment. Use when documenting on-call procedures for a new service, standardizing incident response across teams, or producing runbooks before launching to production.", + "description": "Generate operational runbooks from a service name — deployment, incident response, maintenance, and rollback workflows. Templated structure customizable per environment. Use when documenting on-call procedures for a new service, standardizing incident response across teams, or producing runbooks before launching to production.", "path": "engineering/runbook-generator" }, { @@ -185,7 +185,7 @@ }, { "name": "slo-architect", - "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill \u2014 specifically the SLO discipline.", + "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill — specifically the SLO discipline.", "path": "engineering/slo-architect" }, { @@ -210,7 +210,7 @@ }, { "name": "agenthub", - "description": "Multi-agent collaboration plugin that spawns N parallel subagents competing on the same task via git worktree isolation. Agents work independently, results are evaluated by metric or LLM judge, and the best branch is merged. Use when: user wants multiple approaches tried in parallel \u2014 code optimization, content variation, research exploration, or any task that benefits from parallel competition. Requires: a git repo.", + "description": "Multi-agent collaboration plugin that spawns N parallel subagents competing on the same task via git worktree isolation. Agents work independently, results are evaluated by metric or LLM judge, and the best branch is merged. Use when: user wants multiple approaches tried in parallel — code optimization, content variation, research exploration, or any task that benefits from parallel competition. Requires: a git repo.", "path": "engineering/agenthub" }, { @@ -224,9 +224,9 @@ "path": "engineering/eval" }, { - "name": "init", + "name": "hub-init", "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria.", - "path": "engineering/init" + "path": "engineering/hub-init" }, { "name": "merge", @@ -235,7 +235,7 @@ }, { "name": "run", - "description": "One-shot lifecycle command that chains init \u2192 baseline \u2192 spawn \u2192 eval \u2192 merge in a single invocation.", + "description": "One-shot lifecycle command that chains init → baseline → spawn → eval → merge in a single invocation.", "path": "engineering/run" }, { @@ -244,9 +244,9 @@ "path": "engineering/spawn" }, { - "name": "status", + "name": "hub-status", "description": "Show DAG state, agent progress, and branch status for an AgentHub session.", - "path": "engineering/status" + "path": "engineering/hub-status" }, { "name": "autoresearch-agent", @@ -259,9 +259,9 @@ "path": "engineering/loop" }, { - "name": "resume", + "name": "ar-resume", "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating.", - "path": "engineering/resume" + "path": "engineering/ar-resume" }, { "name": "run", @@ -273,14 +273,9 @@ "description": "Set up a new autoresearch experiment interactively. Collects domain, target file, eval command, metric, direction, and evaluator.", "path": "engineering/setup" }, - { - "name": "status", - "description": "Show experiment dashboard with results, active loops, and progress.", - "path": "engineering/status" - }, { "name": "behuman", - "description": "Use when the user wants more human-like AI responses \u2014 less robotic, less listy, more authentic. Triggers: 'behuman', 'be real', 'like a human', 'more human', 'less AI', 'talk like a person', 'mirror mode', 'stop being so AI', or when conversations are emotionally charged (grief, job loss, relationship advice, fear). NOT for technical questions, code generation, or factual lookups.", + "description": "Use when the user wants more human-like AI responses — less robotic, less listy, more authentic. Triggers: 'behuman', 'be real', 'like a human', 'more human', 'less AI', 'talk like a person', 'mirror mode', 'stop being so AI', or when conversations are emotionally charged (grief, job loss, relationship advice, fear). NOT for technical questions, code generation, or factual lookups.", "path": "engineering/behuman" }, { @@ -295,12 +290,12 @@ }, { "name": "claude-coach", - "description": "Personal coach that teaches users to become Claude power users. Use this skill the FIRST time a user asks to \"learn Claude\", \"be a power user\", \"coach me\", \"teach me Claude tricks\", \"what can Claude do\", \"make me better at prompting\", or any variation. After activation, also use it on EVERY subsequent turn to detect missed optimization opportunities (vague prompts, ignored capabilities, manual work Claude could automate) and surface a single power-user tip. Trigger generously \u2014 most users do not know what they do not know, so err on the side of coaching.", + "description": "Personal coach that teaches users to become Claude power users. Use this skill the FIRST time a user asks to \"learn Claude\", \"be a power user\", \"coach me\", \"teach me Claude tricks\", \"what can Claude do\", \"make me better at prompting\", or any variation. After activation, also use it on EVERY subsequent turn to detect missed optimization opportunities (vague prompts, ignored capabilities, manual work Claude could automate) and surface a single power-user tip. Trigger generously — most users do not know what they do not know, so err on the side of coaching.", "path": "engineering/claude-coach" }, { "name": "code-tour", - "description": "Use when the user asks to create a CodeTour .tour file \u2014 persona-targeted, step-by-step walkthroughs that link to real files and line numbers. Trigger for: create a tour, onboarding tour, architecture tour, PR review tour, explain how X works, vibe check, RCA tour, contributor guide, or any structured code walkthrough request.", + "description": "Use when the user asks to create a CodeTour .tour file — persona-targeted, step-by-step walkthroughs that link to real files and line numbers. Trigger for: create a tour, onboarding tour, architecture tour, PR review tour, explain how X works, vibe check, RCA tour, contributor guide, or any structured code walkthrough request.", "path": "engineering/code-tour" }, { @@ -330,7 +325,7 @@ }, { "name": "grill-with-docs", - "description": "Docs-anchored grilling session \u2014 challenges a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), and updates those files inline as terminology and decisions crystallise. Use when user wants to stress-test a plan against documented domain language, or mentions \"grill with docs\".", + "description": "Docs-anchored grilling session — challenges a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), and updates those files inline as terminology and decisions crystallise. Use when user wants to stress-test a plan against documented domain language, or mentions \"grill with docs\".", "path": "engineering/grill-with-docs" }, { @@ -340,17 +335,17 @@ }, { "name": "helm-chart-builder", - "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw \u2014 chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.", + "description": "Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw — chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.", "path": "engineering/helm-chart-builder" }, { "name": "karpathy-coder", - "description": "Use when writing, reviewing, or committing code to enforce Karpathy's 4 coding principles \u2014 surface assumptions before coding, keep it simple, make surgical changes, define verifiable goals. Triggers on \"review my diff\", \"check complexity\", \"am I overcomplicating this\", \"karpathy check\", \"before I commit\", or any code quality concern where the LLM might be overcoding.", + "description": "Use when writing, reviewing, or committing code to enforce Karpathy's 4 coding principles — surface assumptions before coding, keep it simple, make surgical changes, define verifiable goals. Triggers on \"review my diff\", \"check complexity\", \"am I overcomplicating this\", \"karpathy check\", \"before I commit\", or any code quality concern where the LLM might be overcoding.", "path": "engineering/karpathy-coder" }, { "name": "kubernetes-operator", - "description": "Use when building a Kubernetes Operator \u2014 custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill \u2014 specifically the Operator pattern.", + "description": "Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on \"build an operator\", \"CRD design\", \"reconcile loop\", \"controller-runtime\", \"kubebuilder\", \"operator-sdk\", \"metacontroller\", \"KOPF\", \"operator capability levels\", or \"custom resource\". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill — specifically the Operator pattern.", "path": "engineering/kubernetes-operator" }, { @@ -370,12 +365,12 @@ }, { "name": "security-guidance", - "description": "PreToolUse security-anti-pattern hook for Claude Code. Catches 12 common security risks (command injection, XSS, SQL injection, unsafe deserialization, GitHub Actions workflow injection, eval/new Function code injection) BEFORE the Edit/Write/MultiEdit operation completes. Session-state caching prevents duplicate warnings on the same file+rule combo. Stdlib only \u2014 no dependencies. Use when you want a safety net during Claude Code sessions that touch security-sensitive code (auth, payments, user input handling, IaC). Disable with ENABLE_SECURITY_REMINDER=0 if you need to perform a verified-safe operation that would otherwise trip a pattern. Triggers \u2014 \"add security hook\", \"block unsafe code\", \"detect command injection before write\", \"prevent SQL injection patterns\", \"security warning hook\".", + "description": "PreToolUse security-anti-pattern hook for Claude Code. Catches 12 common security risks (command injection, XSS, SQL injection, unsafe deserialization, GitHub Actions workflow injection, eval/new Function code injection) BEFORE the Edit/Write/MultiEdit operation completes. Session-state caching prevents duplicate warnings on the same file+rule combo. Stdlib only — no dependencies. Use when you want a safety net during Claude Code sessions that touch security-sensitive code (auth, payments, user input handling, IaC). Disable with ENABLE_SECURITY_REMINDER=0 if you need to perform a verified-safe operation that would otherwise trip a pattern. Triggers — \"add security hook\", \"block unsafe code\", \"detect command injection before write\", \"prevent SQL injection patterns\", \"security warning hook\".", "path": "engineering/security-guidance" }, { "name": "slo-architect", - "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill \u2014 specifically the SLO discipline.", + "description": "Use when defining, reviewing, or operating SLOs/SLIs/error budgets. Triggers on \"define an SLO\", \"what should our SLO be\", \"error budget\", \"burn rate\", \"SLI\", \"service level objective\", \"Google SRE workbook\", \"multi-window burn-rate alert\", or any reliability-target question. Ships SLO designer, error-budget calculator with multi-window burn-rate thresholds, and SLO reviewer that catches the common bugs (target too aggressive, window too short, conflicting SLOs, no SLI definition). 4 references on SLO principles + SLI design + error budget math + composition with feature-flags-architect/chaos-engineering/kubernetes-operator. NOT a generic observability skill — specifically the SLO discipline.", "path": "engineering/slo-architect" }, { @@ -397,6 +392,11 @@ "name": "write-a-skill", "description": "Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, build, or author a new skill.", "path": "engineering/write-a-skill" + }, + { + "name": "ar-status", + "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going.", + "path": "engineering/ar-status" } ], "engineering-team": [ @@ -497,7 +497,7 @@ }, { "name": "senior-data-scientist", - "description": "World-class senior data scientist skill specialising in statistical modeling, experiment design, causal inference, and predictive analytics. Covers A/B testing (sample sizing, two-proportion z-tests, Bonferroni correction), difference-in-differences, feature engineering pipelines (Scikit-learn, XGBoost), cross-validated model evaluation (AUC-ROC, AUC-PR, SHAP), and MLflow experiment tracking \u2014 using Python (NumPy, Pandas, Scikit-learn), R, and SQL. Use when designing or analysing controlled experiments, building and evaluating classification or regression models, performing causal analysis on observational data, engineering features for structured tabular datasets, or translating statistical findings into data-driven business decisions.", + "description": "World-class senior data scientist skill specialising in statistical modeling, experiment design, causal inference, and predictive analytics. Covers A/B testing (sample sizing, two-proportion z-tests, Bonferroni correction), difference-in-differences, feature engineering pipelines (Scikit-learn, XGBoost), cross-validated model evaluation (AUC-ROC, AUC-PR, SHAP), and MLflow experiment tracking — using Python (NumPy, Pandas, Scikit-learn), R, and SQL. Use when designing or analysing controlled experiments, building and evaluating classification or regression models, performing causal analysis on observational data, engineering features for structured tabular datasets, or translating statistical findings into data-driven business decisions.", "path": "engineering-team/senior-data-scientist" }, { @@ -591,9 +591,9 @@ "path": "engineering-team/generate" }, { - "name": "init", + "name": "pw-init", "description": ">-", - "path": "engineering-team/init" + "path": "engineering-team/pw-init" }, { "name": "migrate", @@ -611,9 +611,9 @@ "path": "engineering-team/report" }, { - "name": "review", + "name": "pw-review", "description": ">-", - "path": "engineering-team/review" + "path": "engineering-team/pw-review" }, { "name": "testrail", @@ -636,9 +636,9 @@ "path": "engineering-team/remember" }, { - "name": "review", + "name": "memory-review", "description": "Analyze auto-memory for promotion candidates, stale entries, consolidation opportunities, and health metrics.", - "path": "engineering-team/review" + "path": "engineering-team/memory-review" }, { "name": "self-improving-agent", @@ -646,9 +646,9 @@ "path": "engineering-team/self-improving-agent" }, { - "name": "status", + "name": "memory-status", "description": "Memory health dashboard showing line counts, topic files, capacity, stale entries, and recommendations.", - "path": "engineering-team/status" + "path": "engineering-team/memory-status" }, { "name": "snowflake-development", @@ -669,7 +669,7 @@ }, { "name": "landing-page-generator", - "description": "Generates high-converting landing pages as complete Next.js/React (TSX) components with Tailwind CSS. Creates hero sections, feature grids, pricing tables, FAQ accordions, testimonial blocks, and CTA sections using proven copy frameworks (PAS, AIDA, BAB). Outputs SEO meta tags, structured data, and performance-optimised code targeting Core Web Vitals (LCP < 1s, CLS < 0.1). Use when the user asks to create a landing page, marketing page, homepage, single-page site, lead capture page, campaign page, promo page, or conversion-optimised web page \u2014 or when they want to A/B test landing page variants or replace a static page with one designed to convert.", + "description": "Generates high-converting landing pages as complete Next.js/React (TSX) components with Tailwind CSS. Creates hero sections, feature grids, pricing tables, FAQ accordions, testimonial blocks, and CTA sections using proven copy frameworks (PAS, AIDA, BAB). Outputs SEO meta tags, structured data, and performance-optimised code targeting Core Web Vitals (LCP < 1s, CLS < 0.1). Use when the user asks to create a landing page, marketing page, homepage, single-page site, lead capture page, campaign page, promo page, or conversion-optimised web page — or when they want to A/B test landing page variants or replace a static page with one designed to convert.", "path": "product-team/landing-page-generator" }, { @@ -751,22 +751,22 @@ }, { "name": "ad-creative", - "description": "When the user needs to generate, iterate, or scale ad creative for paid advertising. Use when they say 'write ad copy,' 'generate headlines,' 'create ad variations,' 'bulk creative,' 'iterate on ads,' 'ad copy validation,' 'RSA headlines,' 'Meta ad copy,' 'LinkedIn ad,' or 'creative testing.' This is pure creative production \u2014 distinct from paid-ads (campaign strategy). Use ad-creative when you need the copy, not the campaign plan.", + "description": "When the user needs to generate, iterate, or scale ad creative for paid advertising. Use when they say 'write ad copy,' 'generate headlines,' 'create ad variations,' 'bulk creative,' 'iterate on ads,' 'ad copy validation,' 'RSA headlines,' 'Meta ad copy,' 'LinkedIn ad,' or 'creative testing.' This is pure creative production — distinct from paid-ads (campaign strategy). Use ad-creative when you need the copy, not the campaign plan.", "path": "marketing-skill/ad-creative" }, { "name": "aeo", - "description": "Answer Engine Optimization (AEO) skill \u2014 optimize content to be cited by AI language models (ChatGPT, Perplexity, Claude, Gemini, Mistral) as authoritative sources. Distinct from SEO \u2014 AEO optimizes for citation in LLM-generated responses, not search rankings. Use when planning content for AI-first search audiences, auditing existing content for E-E-A-T signals, tracking which pages get cited by which LLMs, or building a citation-friendly content strategy. Triggers \u2014 'AEO audit', 'optimize for ChatGPT', 'get cited by Perplexity', 'LLM citation strategy', 'answer engine optimization', 'content for AI search', 'E-E-A-T audit'. Output is a markdown audit report (default) or JSON for pipeline integration. Stdlib-only Python tools.", + "description": "Answer Engine Optimization (AEO) skill — optimize content to be cited by AI language models (ChatGPT, Perplexity, Claude, Gemini, Mistral) as authoritative sources. Distinct from SEO — AEO optimizes for citation in LLM-generated responses, not search rankings. Use when planning content for AI-first search audiences, auditing existing content for E-E-A-T signals, tracking which pages get cited by which LLMs, or building a citation-friendly content strategy. Triggers — 'AEO audit', 'optimize for ChatGPT', 'get cited by Perplexity', 'LLM citation strategy', 'answer engine optimization', 'content for AI search', 'E-E-A-T audit'. Output is a markdown audit report (default) or JSON for pipeline integration. Stdlib-only Python tools.", "path": "marketing-skill/aeo" }, { "name": "ai-seo", - "description": "Optimize content to get cited by AI search engines \u2014 ChatGPT, Perplexity, Google AI Overviews, Claude, Gemini, Copilot. Use when you want your content to appear in AI-generated answers, not just ranked in blue links. Triggers: 'optimize for AI search', 'get cited by ChatGPT', 'AI Overviews', 'Perplexity citations', 'AI SEO', 'generative search', 'LLM visibility', 'GEO' (generative engine optimization). NOT for traditional SEO ranking (use seo-audit). NOT for content creation (use content-production).", + "description": "Optimize content to get cited by AI search engines — ChatGPT, Perplexity, Google AI Overviews, Claude, Gemini, Copilot. Use when you want your content to appear in AI-generated answers, not just ranked in blue links. Triggers: 'optimize for AI search', 'get cited by ChatGPT', 'AI Overviews', 'Perplexity citations', 'AI SEO', 'generative search', 'LLM visibility', 'GEO' (generative engine optimization). NOT for traditional SEO ranking (use seo-audit). NOT for content creation (use content-production).", "path": "marketing-skill/ai-seo" }, { "name": "analytics-tracking", - "description": "Set up, audit, and debug analytics tracking implementation \u2014 GA4, Google Tag Manager, event taxonomy, conversion tracking, and data quality. Use when building a tracking plan from scratch, auditing existing analytics for gaps or errors, debugging missing events, or setting up GTM. Trigger keywords: GA4 setup, Google Tag Manager, GTM, event tracking, analytics implementation, conversion tracking, tracking plan, event taxonomy, custom dimensions, UTM tracking, analytics audit, missing events, tracking broken. NOT for analyzing marketing campaign data \u2014 use campaign-analytics for that. NOT for BI dashboards \u2014 use product-analytics for in-product event analysis.", + "description": "Set up, audit, and debug analytics tracking implementation — GA4, Google Tag Manager, event taxonomy, conversion tracking, and data quality. Use when building a tracking plan from scratch, auditing existing analytics for gaps or errors, debugging missing events, or setting up GTM. Trigger keywords: GA4 setup, Google Tag Manager, GTM, event tracking, analytics implementation, conversion tracking, tracking plan, event taxonomy, custom dimensions, UTM tracking, analytics audit, missing events, tracking broken. NOT for analyzing marketing campaign data — use campaign-analytics for that. NOT for BI dashboards — use product-analytics for in-product event analysis.", "path": "marketing-skill/analytics-tracking" }, { @@ -776,7 +776,7 @@ }, { "name": "brand-guidelines", - "description": "When the user wants to apply, document, or enforce brand guidelines for any product or company. Also use when the user mentions 'brand guidelines,' 'brand colors,' 'typography,' 'logo usage,' 'brand voice,' 'visual identity,' 'tone of voice,' 'brand standards,' 'style guide,' 'brand consistency,' or 'company design standards.' Covers color systems, typography, logo rules, imagery guidelines, and tone matrix for any brand \u2014 including Anthropic's official identity.", + "description": "When the user wants to apply, document, or enforce brand guidelines for any product or company. Also use when the user mentions 'brand guidelines,' 'brand colors,' 'typography,' 'logo usage,' 'brand voice,' 'visual identity,' 'tone of voice,' 'brand standards,' 'style guide,' 'brand consistency,' or 'company design standards.' Covers color systems, typography, logo rules, imagery guidelines, and tone matrix for any brand — including Anthropic's official identity.", "path": "marketing-skill/brand-guidelines" }, { @@ -786,12 +786,12 @@ }, { "name": "churn-prevention", - "description": "Reduce voluntary and involuntary churn through cancel flow design, save offers, exit surveys, and dunning sequences. Use when designing or optimizing a cancel flow, building save offers, setting up dunning emails, or reducing failed-payment churn. Trigger keywords: cancel flow, churn reduction, save offers, dunning, exit survey, payment recovery, win-back, involuntary churn, failed payments, cancel page. NOT for customer health scoring or expansion revenue \u2014 use customer-success-manager for that.", + "description": "Reduce voluntary and involuntary churn through cancel flow design, save offers, exit surveys, and dunning sequences. Use when designing or optimizing a cancel flow, building save offers, setting up dunning emails, or reducing failed-payment churn. Trigger keywords: cancel flow, churn reduction, save offers, dunning, exit survey, payment recovery, win-back, involuntary churn, failed payments, cancel page. NOT for customer health scoring or expansion revenue — use customer-success-manager for that.", "path": "marketing-skill/churn-prevention" }, { "name": "cold-email", - "description": "When the user wants to write, improve, or build a sequence of B2B cold outreach emails to prospects who haven't asked to hear from them. Use when the user mentions 'cold email,' 'cold outreach,' 'prospecting emails,' 'SDR emails,' 'sales emails,' 'first touch email,' 'follow-up sequence,' or 'email prospecting.' Also use when they share an email draft that sounds too sales-y and needs to be humanized. Distinct from email-sequence (lifecycle/nurture to opted-in subscribers) \u2014 this is unsolicited outreach to new prospects. NOT for lifecycle emails, newsletters, or drip campaigns (use email-sequence).", + "description": "When the user wants to write, improve, or build a sequence of B2B cold outreach emails to prospects who haven't asked to hear from them. Use when the user mentions 'cold email,' 'cold outreach,' 'prospecting emails,' 'SDR emails,' 'sales emails,' 'first touch email,' 'follow-up sequence,' or 'email prospecting.' Also use when they share an email draft that sounds too sales-y and needs to be humanized. Distinct from email-sequence (lifecycle/nurture to opted-in subscribers) — this is unsolicited outreach to new prospects. NOT for lifecycle emails, newsletters, or drip campaigns (use email-sequence).", "path": "marketing-skill/cold-email" }, { @@ -801,17 +801,17 @@ }, { "name": "content-creator", - "description": "Deprecated redirect skill that routes legacy 'content creator' requests to the correct specialist. Use when a user invokes 'content creator', asks to write a blog post, article, guide, or brand voice analysis (routes to content-production), or asks to plan content, build a topic cluster, or create a content calendar (routes to content-strategy). Does not handle requests directly \u2014 identifies user intent and redirects to content-production for writing/SEO/brand-voice tasks or content-strategy for planning tasks.", + "description": "Deprecated redirect skill that routes legacy 'content creator' requests to the correct specialist. Use when a user invokes 'content creator', asks to write a blog post, article, guide, or brand voice analysis (routes to content-production), or asks to plan content, build a topic cluster, or create a content calendar (routes to content-strategy). Does not handle requests directly — identifies user intent and redirects to content-production for writing/SEO/brand-voice tasks or content-strategy for planning tasks.", "path": "marketing-skill/content-creator" }, { "name": "content-humanizer", - "description": "Makes AI-generated content sound genuinely human \u2014 not just cleaned up, but alive. Use when content feels robotic, uses too many AI clich\u00e9s, lacks personality, or reads like it was written by committee. Triggers: 'this sounds like AI', 'make it more human', 'add personality', 'it feels generic', 'sounds robotic', 'fix AI writing', 'inject our voice'. NOT for initial content creation (use content-production). NOT for SEO optimization (use content-production Mode 3).", + "description": "Makes AI-generated content sound genuinely human — not just cleaned up, but alive. Use when content feels robotic, uses too many AI clichés, lacks personality, or reads like it was written by committee. Triggers: 'this sounds like AI', 'make it more human', 'add personality', 'it feels generic', 'sounds robotic', 'fix AI writing', 'inject our voice'. NOT for initial content creation (use content-production). NOT for SEO optimization (use content-production Mode 3).", "path": "marketing-skill/content-humanizer" }, { "name": "content-production", - "description": "Full content production pipeline \u2014 takes a topic from blank page to published-ready piece. Use when you need to execute content: write a blog post, article, or guide end-to-end. Triggers: 'write a post about', 'draft an article', 'create content for', 'help me write', 'I need a blog post'. NOT for content strategy or calendar planning (use content-strategy). NOT for repurposing existing content (use content-repurposing). NOT for social captions only.", + "description": "Full content production pipeline — takes a topic from blank page to published-ready piece. Use when you need to execute content: write a blog post, article, or guide end-to-end. Triggers: 'write a post about', 'draft an article', 'create content for', 'help me write', 'I need a blog post'. NOT for content strategy or calendar planning (use content-strategy). NOT for repurposing existing content (use content-repurposing). NOT for social captions only.", "path": "marketing-skill/content-production" }, { @@ -826,7 +826,7 @@ }, { "name": "copywriting", - "description": "When the user wants to write, rewrite, or improve marketing copy for any page \u2014 including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says \\\"write copy for,\\\" \\\"improve this copy,\\\" \\\"rewrite this page,\\\" \\\"marketing copy,\\\" \\\"headline help,\\\" or \\\"CTA copy.\\\" For email copy, see email-sequence. For popup copy, see popup-cro.", + "description": "When the user wants to write, rewrite, or improve marketing copy for any page — including homepage, landing pages, pricing pages, feature pages, about pages, or product pages. Also use when the user says \\\"write copy for,\\\" \\\"improve this copy,\\\" \\\"rewrite this page,\\\" \\\"marketing copy,\\\" \\\"headline help,\\\" or \\\"CTA copy.\\\" For email copy, see email-sequence. For popup copy, see popup-cro.", "path": "marketing-skill/copywriting" }, { @@ -836,12 +836,12 @@ }, { "name": "form-cro", - "description": "When the user wants to optimize any form that is NOT signup/registration \u2014 including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions \"form optimization,\" \"lead form conversions,\" \"form friction,\" \"form fields,\" \"form completion rate,\" or \"contact form.\" For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro.", + "description": "When the user wants to optimize any form that is NOT signup/registration — including lead capture forms, contact forms, demo request forms, application forms, survey forms, or checkout forms. Also use when the user mentions \"form optimization,\" \"lead form conversions,\" \"form friction,\" \"form fields,\" \"form completion rate,\" or \"contact form.\" For signup/registration forms, see signup-flow-cro. For popups containing forms, see popup-cro.", "path": "marketing-skill/form-cro" }, { "name": "free-tool-strategy", - "description": "When the user wants to build a free tool for marketing \u2014 lead generation, SEO value, or brand awareness. Use when they mention 'engineering as marketing,' 'free tool,' 'calculator,' 'generator,' 'checker,' 'grader,' 'marketing tool,' 'lead gen tool,' 'build something for traffic,' 'interactive tool,' or 'free resource.' Covers idea evaluation, tool design, and launch strategy. For pure SEO content strategy (no tool), use seo-audit or content-strategy instead.", + "description": "When the user wants to build a free tool for marketing — lead generation, SEO value, or brand awareness. Use when they mention 'engineering as marketing,' 'free tool,' 'calculator,' 'generator,' 'checker,' 'grader,' 'marketing tool,' 'lead gen tool,' 'build something for traffic,' 'interactive tool,' or 'free resource.' Covers idea evaluation, tool design, and launch strategy. For pure SEO content strategy (no tool), use seo-audit or content-strategy instead.", "path": "marketing-skill/free-tool-strategy" }, { @@ -891,7 +891,7 @@ }, { "name": "page-cro", - "description": "When the user wants to optimize, improve, or increase conversions on any marketing page \u2014 including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says \"CRO,\" \"conversion rate optimization,\" \"this page isn't converting,\" \"improve conversions,\" or \"why isn't this page working.\" For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro.", + "description": "When the user wants to optimize, improve, or increase conversions on any marketing page — including homepage, landing pages, pricing pages, feature pages, or blog posts. Also use when the user says \"CRO,\" \"conversion rate optimization,\" \"this page isn't converting,\" \"improve conversions,\" or \"why isn't this page working.\" For signup/registration flows, see signup-flow-cro. For post-signup activation, see onboarding-cro. For forms outside of signup, see form-cro. For popups/modals, see popup-cro.", "path": "marketing-skill/page-cro" }, { @@ -901,7 +901,7 @@ }, { "name": "paywall-upgrade-cro", - "description": "When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions \"paywall,\" \"upgrade screen,\" \"upgrade modal,\" \"upsell,\" \"feature gate,\" \"convert free to paid,\" \"freemium conversion,\" \"trial expiration screen,\" \"limit reached screen,\" \"plan upgrade prompt,\" or \"in-app pricing.\" Distinct from public pricing pages (see page-cro) \u2014 this skill focuses on in-product upgrade moments where the user has already experienced value.", + "description": "When the user wants to create or optimize in-app paywalls, upgrade screens, upsell modals, or feature gates. Also use when the user mentions \"paywall,\" \"upgrade screen,\" \"upgrade modal,\" \"upsell,\" \"feature gate,\" \"convert free to paid,\" \"freemium conversion,\" \"trial expiration screen,\" \"limit reached screen,\" \"plan upgrade prompt,\" or \"in-app pricing.\" Distinct from public pricing pages (see page-cro) — this skill focuses on in-product upgrade moments where the user has already experienced value.", "path": "marketing-skill/paywall-upgrade-cro" }, { @@ -911,7 +911,7 @@ }, { "name": "pricing-strategy", - "description": "Design, optimize, and communicate SaaS pricing \u2014 tier structure, value metrics, pricing pages, and price increase strategy. Use when building a pricing model from scratch, redesigning existing pricing, planning a price increase, or improving a pricing page. Trigger keywords: pricing tiers, pricing page, price increase, packaging, value metric, per seat pricing, usage-based pricing, freemium, good-better-best, pricing strategy, monetization, pricing page conversion, Van Westendorp. NOT for broader product strategy \u2014 use product-strategist for that. NOT for customer success or renewals \u2014 use customer-success-manager for expansion revenue.", + "description": "Design, optimize, and communicate SaaS pricing — tier structure, value metrics, pricing pages, and price increase strategy. Use when building a pricing model from scratch, redesigning existing pricing, planning a price increase, or improving a pricing page. Trigger keywords: pricing tiers, pricing page, price increase, packaging, value metric, per seat pricing, usage-based pricing, freemium, good-better-best, pricing strategy, monetization, pricing page conversion, Van Westendorp. NOT for broader product strategy — use product-strategist for that. NOT for customer success or renewals — use customer-success-manager for expansion revenue.", "path": "marketing-skill/pricing-strategy" }, { @@ -926,7 +926,7 @@ }, { "name": "referral-program", - "description": "When the user wants to design, launch, or optimize a referral or affiliate program. Use when they mention 'referral program,' 'affiliate program,' 'word of mouth,' 'refer a friend,' 'incentive program,' 'customer referrals,' 'brand ambassador,' 'partner program,' 'referral link,' or 'growth through referrals.' Covers program mechanics, incentive design, and optimization \u2014 not just the idea of referrals but the actual system.", + "description": "When the user wants to design, launch, or optimize a referral or affiliate program. Use when they mention 'referral program,' 'affiliate program,' 'word of mouth,' 'refer a friend,' 'incentive program,' 'customer referrals,' 'brand ambassador,' 'partner program,' 'referral link,' or 'growth through referrals.' Covers program mechanics, incentive design, and optimization — not just the idea of referrals but the actual system.", "path": "marketing-skill/referral-program" }, { @@ -1013,17 +1013,17 @@ }, { "name": "chief-ai-officer-advisor", - "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only \u2014 does not duplicate engineering AI/ML skills.", + "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only — does not duplicate engineering AI/ML skills.", "path": "c-level-advisor/chief-ai-officer-advisor" }, { "name": "chief-customer-officer-advisor", - "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only \u2014 does not duplicate engineering/business-growth tactical skills.", + "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only — does not duplicate engineering/business-growth tactical skills.", "path": "c-level-advisor/chief-customer-officer-advisor" }, { "name": "chief-data-officer-advisor", - "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill \u2014 strategic decisions only.", + "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill — strategic decisions only.", "path": "c-level-advisor/chief-data-officer-advisor" }, { @@ -1048,7 +1048,7 @@ }, { "name": "company-os", - "description": "The meta-framework for how a company runs \u2014 the connective tissue between all C-suite roles. Covers operating system selection (EOS, Scaling Up, OKR-native, hybrid), accountability charts, scorecards, meeting pulse, issue resolution, and 90-day rocks. Use when setting up company operations, selecting a management framework, designing meeting rhythms, building accountability systems, implementing OKRs, or when user mentions EOS, Scaling Up, operating system, L10 meetings, rocks, scorecard, accountability chart, or quarterly planning.", + "description": "The meta-framework for how a company runs — the connective tissue between all C-suite roles. Covers operating system selection (EOS, Scaling Up, OKR-native, hybrid), accountability charts, scorecards, meeting pulse, issue resolution, and 90-day rocks. Use when setting up company operations, selecting a management framework, designing meeting rhythms, building accountability systems, implementing OKRs, or when user mentions EOS, Scaling Up, operating system, L10 meetings, rocks, scorecard, accountability chart, or quarterly planning.", "path": "c-level-advisor/company-os" }, { @@ -1088,7 +1088,7 @@ }, { "name": "culture-architect", - "description": "Build, measure, and evolve company culture as operational behavior \u2014 not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code.", + "description": "Build, measure, and evolve company culture as operational behavior — not wall posters. Covers mission/vision/values workshops, values-to-behaviors translation, culture code creation, culture health assessment, and cultural rituals by stage. Use when building company values, assessing culture health, designing cultural rituals, creating culture codes, handling culture clashes, or when user mentions culture, values, culture debt, founder culture, or culture code.", "path": "c-level-advisor/culture-architect" }, { @@ -1103,12 +1103,12 @@ }, { "name": "general-counsel-advisor", - "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel \u2014 surfaces questions to bring to qualified attorneys.", + "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel — surfaces questions to bring to qualified attorneys.", "path": "c-level-advisor/general-counsel-advisor" }, { "name": "internal-narrative", - "description": "Build and maintain one coherent company story across all audiences \u2014 employees, investors, customers, candidates, and partners. Detects narrative contradictions and ensures the same truth is framed for each audience's needs. Use when preparing investor updates, all-hands presentations, board communications, recruiting narratives, crisis communications, or when user mentions company narrative, messaging consistency, storytelling, all-hands, investor update, or crisis communication.", + "description": "Build and maintain one coherent company story across all audiences — employees, investors, customers, candidates, and partners. Detects narrative contradictions and ensures the same truth is framed for each audience's needs. Use when preparing investor updates, all-hands presentations, board communications, recruiting narratives, crisis communications, or when user mentions company narrative, messaging consistency, storytelling, all-hands, investor update, or crisis communication.", "path": "c-level-advisor/internal-narrative" }, { @@ -1138,132 +1138,132 @@ }, { "name": "vpe-advisor", - "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships.", + "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing → screen → onsite → offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) — VPE owns delivery operations and how the team ships.", "path": "c-level-advisor/vpe-advisor" }, { "name": "boardroom", - "description": "/cs:boardroom \u2014 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo.", + "description": "/cs:boardroom — 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo.", "path": "c-level-advisor/boardroom" }, { "name": "brief", - "description": "/cs:brief \u2014 Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline.", + "description": "/cs:brief — Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline.", "path": "c-level-advisor/brief" }, { "name": "c-level-agents", "description": "Founder-mode executive team. 8 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, Chief of Staff) and 17 /cs:* slash commands for forcing-question office hours, multi-role boardroom deliberation, strategic sprint pipeline, and meta routing. Use when the founder needs a virtual executive team, when invoking /cs:* commands, or when orchestrating multi-role decisions.", - "path": "c-level-advisor/c-level-agents" + "path": "c-level-agents" }, { "name": "caio-review", - "description": "/cs:caio-review \u2014 Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring.", + "description": "/cs:caio-review — Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring.", "path": "c-level-advisor/caio-review" }, { "name": "cco-review", - "description": "/cs:cco-review \u2014 Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring.", + "description": "/cs:cco-review — Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring.", "path": "c-level-advisor/cco-review" }, { "name": "cdo-review", - "description": "/cs:cdo-review \u2014 Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring.", + "description": "/cs:cdo-review — Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring.", "path": "c-level-advisor/cdo-review" }, { "name": "cfo-review", - "description": "/cs:cfo-review \u2014 Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation.", + "description": "/cs:cfo-review — Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation.", "path": "c-level-advisor/cfo-review" }, { "name": "ciso-review", - "description": "/cs:ciso-review \u2014 Risk-paranoid interrogation of any plan that touches data, compliance, or production access.", + "description": "/cs:ciso-review — Risk-paranoid interrogation of any plan that touches data, compliance, or production access.", "path": "c-level-advisor/ciso-review" }, { "name": "cmo-review", - "description": "/cs:cmo-review \u2014 Narrative-first interrogation of positioning, ICP, message house, and channel mix.", + "description": "/cs:cmo-review — Narrative-first interrogation of positioning, ICP, message house, and channel mix.", "path": "c-level-advisor/cmo-review" }, { "name": "cpo-review", - "description": "/cs:cpo-review \u2014 JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus.", + "description": "/cs:cpo-review — JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus.", "path": "c-level-advisor/cpo-review" }, { "name": "cro-review", - "description": "/cs:cro-review \u2014 Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time.", + "description": "/cs:cro-review — Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time.", "path": "c-level-advisor/cro-review" }, { "name": "cross-eval", - "description": "/cs:cross-eval \u2014 Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation.", + "description": "/cs:cross-eval — Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation.", "path": "c-level-advisor/cross-eval" }, { "name": "cto-review", - "description": "/cs:cto-review \u2014 Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy.", + "description": "/cs:cto-review — Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy.", "path": "c-level-advisor/cto-review" }, { "name": "decide", - "description": "/cs:decide \u2014 Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference.", + "description": "/cs:decide — Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference.", "path": "c-level-advisor/decide" }, { "name": "execute", - "description": "/cs:execute \u2014 Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision.", + "description": "/cs:execute — Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision.", "path": "c-level-advisor/execute" }, { "name": "founder-mode", - "description": "/cs:founder-mode \u2014 Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point.", + "description": "/cs:founder-mode — Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point.", "path": "c-level-advisor/founder-mode" }, { "name": "freeze", - "description": "/cs:freeze \u2014 Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer.", + "description": "/cs:freeze — Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer.", "path": "c-level-advisor/freeze" }, { "name": "gc-review", - "description": "/cs:gc-review \u2014 General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface.", + "description": "/cs:gc-review — General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface.", "path": "c-level-advisor/gc-review" }, { "name": "office-hours", - "description": "/cs:office-hours \u2014 YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit.", + "description": "/cs:office-hours — YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit.", "path": "c-level-advisor/office-hours" }, { "name": "onboard", - "description": "/cs:onboard \u2014 Founder interview that populates ~/.claude/company-context.md. The first command to run when starting with c-level-agents.", + "description": "/cs:onboard — Founder interview that populates ~/.claude/company-context.md. The first command to run when starting with c-level-agents.", "path": "c-level-advisor/onboard" }, { "name": "post-mortem", - "description": "/cs:post-mortem \u2014 Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop.", + "description": "/cs:post-mortem — Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop.", "path": "c-level-advisor/post-mortem" }, { "name": "vpe-review", - "description": "/cs:vpe-review \u2014 Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline.", + "description": "/cs:vpe-review — Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline.", "path": "c-level-advisor/vpe-review" }, { "name": "chief-ai-officer-advisor", - "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only \u2014 does not duplicate engineering AI/ML skills.", + "description": "Chief AI Officer advisory for startups: model build-vs-buy decisions (API vs fine-tune vs in-house), AI risk classification under EU AI Act + US state patchwork, AI cost economics (API-to-self-hosted breakeven), and AI team org evolution. Use when deciding whether to call an API or fine-tune, classifying AI use cases for regulatory risk, calculating when self-hosting pays off, sequencing AI hires, or when user mentions CAIO, AI strategy, model selection, foundation model, fine-tuning, EU AI Act, NIST AI RMF, AI governance, model risk, or AI economics. Strategic only — does not duplicate engineering AI/ML skills.", "path": "c-level-advisor/chief-ai-officer-advisor" }, { "name": "chief-customer-officer-advisor", - "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only \u2014 does not duplicate engineering/business-growth tactical skills.", + "description": "Chief Customer Officer advisory for startups: retention decomposition (gross retention vs NRR honesty, churn root-cause taxonomy), customer segmentation strategy (differential investment across tiers + ICP fit scoring), CS team coverage model (pooled vs named CSM thresholds + ratio math), and CS team org evolution (CS vs Support vs AM distinctions). Use when designing retention strategy, segmenting customers for differential investment, sizing CS team, or sequencing CS hires. Strategic only — does not duplicate engineering/business-growth tactical skills.", "path": "c-level-advisor/chief-customer-officer-advisor" }, { "name": "chief-data-officer-advisor", - "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill \u2014 strategic decisions only.", + "description": "Chief Data Officer advisory for startups: AI training data rights and consent provenance, data product strategy (warehouse vs lakehouse vs mesh, build-vs-buy), B2B customer-data-as-asset valuation and M&A readiness, data team org evolution. Use when deciding whether to train models on customer data, choosing data architecture, valuing data for fundraising or M&A, sequencing data hires, or when user mentions CDO, chief data officer, data strategy, data mesh, lakehouse, training data, data product, data monetization, or customer data asset. NOT a tactical data engineering skill — strategic decisions only.", "path": "c-level-advisor/chief-data-officer-advisor" }, { @@ -1283,27 +1283,27 @@ }, { "name": "hard-call", - "description": "/em -hard-call \u2014 Framework for Decisions With No Good Options", + "description": "/em -hard-call — Framework for Decisions With No Good Options", "path": "c-level-advisor/hard-call" }, { "name": "postmortem", - "description": "/em -postmortem \u2014 Honest Analysis of What Went Wrong", + "description": "/em -postmortem — Honest Analysis of What Went Wrong", "path": "c-level-advisor/postmortem" }, { "name": "stress-test", - "description": "/em -stress-test \u2014 Business Assumption Stress Testing", + "description": "/em -stress-test — Business Assumption Stress Testing", "path": "c-level-advisor/stress-test" }, { "name": "general-counsel-advisor", - "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel \u2014 surfaces questions to bring to qualified attorneys.", + "description": "General Counsel advisory for startups: contract review (MSA, SaaS, NDA, DPA, employment), IP strategy, term sheet decoding, and regulatory landscape mapping. Use when reviewing any contract or term sheet, deciding when to engage outside counsel, defining IP strategy, evaluating regulatory exposure (HIPAA, GDPR, FDA, fintech), or when user mentions general counsel, GC, legal review, contract risk, term sheet, IP assignment, or regulatory exposure. NOT a substitute for licensed counsel — surfaces questions to bring to qualified attorneys.", "path": "c-level-advisor/general-counsel-advisor" }, { "name": "vpe-advisor", - "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing \u2192 screen \u2192 onsite \u2192 offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) \u2014 VPE owns delivery operations and how the team ships.", + "description": "VP of Engineering advisory for startups: delivery throughput (DORA 4 metrics + bottleneck identification), engineering hiring funnel (sourcing → screen → onsite → offer conversion + time-to-fill + pipeline gap), engineering team structure (squad/tribe/chapter design + tech-lead manager-trigger thresholds), and production discipline (on-call, deployment cadence, postmortem culture). Use when sprint velocity is dropping, eng hiring is broken, team structure is unclear, or deciding when to add a tech-lead manager. NOT a CTO skill (which owns architecture) — VPE owns delivery operations and how the team ships.", "path": "c-level-advisor/vpe-advisor" } ], @@ -1330,7 +1330,7 @@ }, { "name": "meeting-analyzer", - "description": "Analyzes meeting transcripts and recordings to surface behavioral patterns, communication anti-patterns, and actionable coaching feedback. Use this skill whenever the user uploads or points to meeting transcripts (.txt, .md, .vtt, .srt, .docx), asks about their communication habits, wants feedback on how they run meetings, requests speaking ratio analysis, mentions filler words or conflict avoidance, or wants to compare their communication across time periods. Also trigger when users mention tools like Granola, Otter, Fireflies, or Zoom transcripts. Even if the user just says \"look at my meetings\" or \"how do I come across in meetings\" \u2014 use this skill.", + "description": "Analyzes meeting transcripts and recordings to surface behavioral patterns, communication anti-patterns, and actionable coaching feedback. Use this skill whenever the user uploads or points to meeting transcripts (.txt, .md, .vtt, .srt, .docx), asks about their communication habits, wants feedback on how they run meetings, requests speaking ratio analysis, mentions filler words or conflict avoidance, or wants to compare their communication across time periods. Also trigger when users mention tools like Granola, Otter, Fireflies, or Zoom transcripts. Even if the user just says \"look at my meetings\" or \"how do I come across in meetings\" — use this skill.", "path": "project-management/meeting-analyzer" }, { @@ -1345,12 +1345,12 @@ }, { "name": "senior-pm", - "description": "Senior Project Manager for enterprise software, SaaS, and digital transformation projects. Specializes in portfolio management, quantitative risk analysis, resource optimization, stakeholder alignment, and executive reporting. Uses advanced methodologies including EMV analysis, Monte Carlo simulation, WSJF prioritization, and multi-dimensional health scoring. Use when a user needs help with project plans, project status reports, risk assessments, resource allocation, project roadmaps, milestone tracking, team capacity planning, portfolio health reviews, program management, or executive-level project reporting \u2014 especially for enterprise-scale initiatives with multiple workstreams, complex dependencies, or multi-million dollar budgets.", + "description": "Senior Project Manager for enterprise software, SaaS, and digital transformation projects. Specializes in portfolio management, quantitative risk analysis, resource optimization, stakeholder alignment, and executive reporting. Uses advanced methodologies including EMV analysis, Monte Carlo simulation, WSJF prioritization, and multi-dimensional health scoring. Use when a user needs help with project plans, project status reports, risk assessments, resource allocation, project roadmaps, milestone tracking, team capacity planning, portfolio health reviews, program management, or executive-level project reporting — especially for enterprise-scale initiatives with multiple workstreams, complex dependencies, or multi-million dollar budgets.", "path": "project-management/senior-pm" }, { "name": "team-communications", - "description": "Write internal company communications \u2014 3P updates (Progress/Plans/Problems), company-wide newsletters, FAQ roundups, incident reports, leadership updates, status reports, project updates, and general internal comms. Use this skill any time the user asks to draft, edit, or format something meant for internal audiences. Trigger on keywords like \"3P\", \"weekly update\", \"newsletter\", \"FAQ\", \"internal comms\", \"status report\", \"company update\", \"team update\", \"incident report\", or any request to summarize work for leadership, teammates, or the broader company. Even casual requests like \"write my update\" or \"summarize what my team did this week\" should trigger this skill.", + "description": "Write internal company communications — 3P updates (Progress/Plans/Problems), company-wide newsletters, FAQ roundups, incident reports, leadership updates, status reports, project updates, and general internal comms. Use this skill any time the user asks to draft, edit, or format something meant for internal audiences. Trigger on keywords like \"3P\", \"weekly update\", \"newsletter\", \"FAQ\", \"internal comms\", \"status report\", \"company update\", \"team update\", \"incident report\", or any request to summarize work for leadership, teammates, or the broader company. Even casual requests like \"write my update\" or \"summarize what my team did this week\" should trigger this skill.", "path": "project-management/team-communications" } ], @@ -1362,7 +1362,7 @@ }, { "name": "eu-ai-act-specialist", - "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system \u2014 prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", + "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system — prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", "path": "ra-qm-team/eu-ai-act-specialist" }, { @@ -1437,7 +1437,7 @@ }, { "name": "eu-ai-act-specialist", - "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system \u2014 prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", + "description": "EU AI Act (Regulation (EU) 2024/1689) operational compliance for compliance teams. Three Article-level decisions: (1) What's the risk tier of this AI system — prohibited (Art. 5), high-risk (Art. 6 + Annex III), limited-risk (Art. 50), or minimal-risk? (2) For high-risk systems, what's the Article 43 conformity assessment route (Module A internal control vs Module H full QMS + notified body) and what goes in the Annex IV technical documentation? (3) Per organizational role (provider / deployer / importer / distributor / authorized representative), what are the active obligations and deadlines? Use during AI system intake review, when planning conformity assessment, or when scoping deployer obligations. Cites Articles + Annexes for every output. NOT executive AI strategy (see chief-ai-officer-advisor). NOT a legal substitute.", "path": "ra-qm-team/eu-ai-act-specialist" }, { @@ -1454,7 +1454,7 @@ }, { "name": "contract-and-proposal-writer", - "description": "Generate professional, jurisdiction-aware business documents: freelance contracts, project proposals, SOWs, NDAs, and MSAs. Structured Markdown output with docx conversion instructions. Covers US (Delaware), EU (GDPR), UK, and DACH (German law) jurisdictions. Not a substitute for legal counsel \u2014 use as strong starting points. Use when drafting a freelance contract, preparing a client proposal, writing an SOW for a new engagement, or producing an NDA before sharing sensitive material.", + "description": "Generate professional, jurisdiction-aware business documents: freelance contracts, project proposals, SOWs, NDAs, and MSAs. Structured Markdown output with docx conversion instructions. Covers US (Delaware), EU (GDPR), UK, and DACH (German law) jurisdictions. Not a substitute for legal counsel — use as strong starting points. Use when drafting a freelance contract, preparing a client proposal, writing an SOW for a new engagement, or producing an NDA before sharing sensitive material.", "path": "business-growth/contract-and-proposal-writer" }, { @@ -1498,12 +1498,12 @@ "productivity": [ { "name": "andreessen", - "description": "Marc Andreessen-mode decision and productivity skill. A blunt, market-first operator that pressure-tests ideas, ventures, features, and career bets through Andreessen's actual frameworks \u2014 market dominates team and product; the only milestone that matters is product/market fit; bias to build over deliberate. Use when the user says 'andreessen', 'pmarca mode', 'should I build this', 'is there a market', 'are we at product/market fit', 'pmf check', 'pressure-test this idea', 'be brutal about this venture', 'market-first take', or wants a no-disclaimers, no-hedging, confidence-leveled verdict on whether something is worth pursuing. Also provides the 3x5-card + Anti-Todo personal productivity routine. Runs on a fixed anti-sycophancy operating prompt: leads with the strongest counterargument, never validates premises, uses explicit confidence levels, never apologizes for disagreeing. Not for polite brainstorming \u2014 this skill exists to tell you the market is dead when it is.", + "description": "Marc Andreessen-mode decision and productivity skill. A blunt, market-first operator that pressure-tests ideas, ventures, features, and career bets through Andreessen's actual frameworks — market dominates team and product; the only milestone that matters is product/market fit; bias to build over deliberate. Use when the user says 'andreessen', 'pmarca mode', 'should I build this', 'is there a market', 'are we at product/market fit', 'pmf check', 'pressure-test this idea', 'be brutal about this venture', 'market-first take', or wants a no-disclaimers, no-hedging, confidence-leveled verdict on whether something is worth pursuing. Also provides the 3x5-card + Anti-Todo personal productivity routine. Runs on a fixed anti-sycophancy operating prompt: leads with the strongest counterargument, never validates premises, uses explicit confidence levels, never apologizes for disagreeing. Not for polite brainstorming — this skill exists to tell you the market is dead when it is.", "path": "productivity/andreessen" }, { "name": "capture", - "description": "Captures and organizes chaotic brain dumps into a structured, actionable system with zero information loss. Use this skill whenever the user says 'capture this', 'brain dump', 'let me dump some ideas', 'I've got a bunch of thoughts', 'here's everything on my mind', 'idea dump', 'let me get this out of my head', 'I need to organize my thoughts', 'here's what I'm thinking', or any variation where someone is unloading a messy stream of ideas, tasks, thoughts, and plans wanting them turned into something coherent. Also trigger when the user pastes or dictates a long, unstructured block of mixed ideas \u2014 even without the exact phrase \u2014 the intent is the same. Fast-to-action by design: no upfront intake. Output is four sections (Projects/Ideas, Tasks, Connections, How I Can Help) ending with a directive question. Asks at most one mid-organization clarifying question when a single item is genuinely ambiguous between task and project.", + "description": "Captures and organizes chaotic brain dumps into a structured, actionable system with zero information loss. Use this skill whenever the user says 'capture this', 'brain dump', 'let me dump some ideas', 'I've got a bunch of thoughts', 'here's everything on my mind', 'idea dump', 'let me get this out of my head', 'I need to organize my thoughts', 'here's what I'm thinking', or any variation where someone is unloading a messy stream of ideas, tasks, thoughts, and plans wanting them turned into something coherent. Also trigger when the user pastes or dictates a long, unstructured block of mixed ideas — even without the exact phrase — the intent is the same. Fast-to-action by design: no upfront intake. Output is four sections (Projects/Ideas, Tasks, Connections, How I Can Help) ending with a directive question. Asks at most one mid-organization clarifying question when a single item is genuinely ambiguous between task and project.", "path": "productivity/capture" }, { @@ -1523,7 +1523,7 @@ }, { "name": "reflect", - "description": "Mid-conversation reflection skill that pauses execution and zooms out from detail-mode to honestly reassess direction, assumptions, and bias. Use when the user says 'reflect', 'take a step back', 'step back', 'zoom out', 'are we missing something', 'bigger picture', 'sanity check this', 'are we on track', 'are we overthinking this', 'forest for the trees', or any variation signaling intent to break out of detail-mode and reassess. Also trigger when the conversation has gone deep on implementation details without strategic check-in, or when the user shows signs of being stuck \u2014 that's often a signal the framing needs a reset, not more detail work. Intentionally low-intake: runs the 5-dimension analysis immediately when prior context is rich enough; asks one forcing clarifier only when invocation context is too thin to reassess from.", + "description": "Mid-conversation reflection skill that pauses execution and zooms out from detail-mode to honestly reassess direction, assumptions, and bias. Use when the user says 'reflect', 'take a step back', 'step back', 'zoom out', 'are we missing something', 'bigger picture', 'sanity check this', 'are we on track', 'are we overthinking this', 'forest for the trees', or any variation signaling intent to break out of detail-mode and reassess. Also trigger when the conversation has gone deep on implementation details without strategic check-in, or when the user shows signs of being stuck — that's often a signal the framing needs a reset, not more detail work. Intentionally low-intake: runs the 5-dimension analysis immediately when prior context is rich enough; asks one forcing clarifier only when invocation context is too thin to reassess from.", "path": "productivity/reflect" } ], @@ -1537,27 +1537,27 @@ "research": [ { "name": "dossier", - "description": "Decision-grade entity research skill \u2014 produces a hypothesis-tested dossier on a specific company, person, nonprofit, or government org, not a generic profile. Forcing intake makes the user state their hypothesis upfront (what they already believe and want to verify or disprove) so the dossier tests it rather than confirms it. Output is an editable Word document (.docx) with verdict on the hypothesis, identity facts, 12-month activity timeline, network signals, reputation signals, red flags, 3-5 conversation hooks tied to specific findings, and source-provenance audit log. Uses WebSearch + WebFetch + free APIs (SEC EDGAR, GitHub, ProPublica Nonprofit Explorer) as workhorses; optional BYOK MCPs (LinkedIn, Crunchbase, Apollo, Pitchbook, SimilarWeb) enhance coverage. Triggers: 'research [company]', 'dossier on [person/company]', 'background check on [entity]', 'prep me for a meeting with [person/company]', 'due diligence on [company]', 'what should I know about [entity]', 'research [person] before I [meet/hire/invest]', 'competitor research on [company]', 'investor diligence [company]', 'interview prep for [company]'. Honors sensitivity exclusions for journalism + personal-vetting contexts.", + "description": "Decision-grade entity research skill — produces a hypothesis-tested dossier on a specific company, person, nonprofit, or government org, not a generic profile. Forcing intake makes the user state their hypothesis upfront (what they already believe and want to verify or disprove) so the dossier tests it rather than confirms it. Output is an editable Word document (.docx) with verdict on the hypothesis, identity facts, 12-month activity timeline, network signals, reputation signals, red flags, 3-5 conversation hooks tied to specific findings, and source-provenance audit log. Uses WebSearch + WebFetch + free APIs (SEC EDGAR, GitHub, ProPublica Nonprofit Explorer) as workhorses; optional BYOK MCPs (LinkedIn, Crunchbase, Apollo, Pitchbook, SimilarWeb) enhance coverage. Triggers: 'research [company]', 'dossier on [person/company]', 'background check on [entity]', 'prep me for a meeting with [person/company]', 'due diligence on [company]', 'what should I know about [entity]', 'research [person] before I [meet/hire/invest]', 'competitor research on [company]', 'investor diligence [company]', 'interview prep for [company]'. Honors sensitivity exclusions for journalism + personal-vetting contexts.", "path": "research/dossier" }, { "name": "grants", - "description": "NIH grant research skill for clinical researchers. Grill-me intake (research idea + career stage + preliminary data + environment + submission posture + known institute targets) locks down the funding strategy before any search runs. Runs a 5-facet Consensus positioning analysis (with draft Significance/Innovation language), maps the research to the right NIH institutes and study sections via RePORTER, finds NOSIs and funded overlap, and produces an editable Word document (.docx) with budget/scope-aware mechanism recommendations, submission timelines, and a mandatory program officer recommendation. Triggers: 'grants for [topic]', 'find grants for my research idea', 'what grants match my research', 'help me find NIH funding', 'grant opportunities for my research', or any grant-related request. NIH-only scope \u2014 non-NIH funders (PCORI, DOD CDMRP, VA, foundations) are out of scope and flagged at intake.", + "description": "NIH grant research skill for clinical researchers. Grill-me intake (research idea + career stage + preliminary data + environment + submission posture + known institute targets) locks down the funding strategy before any search runs. Runs a 5-facet Consensus positioning analysis (with draft Significance/Innovation language), maps the research to the right NIH institutes and study sections via RePORTER, finds NOSIs and funded overlap, and produces an editable Word document (.docx) with budget/scope-aware mechanism recommendations, submission timelines, and a mandatory program officer recommendation. Triggers: 'grants for [topic]', 'find grants for my research idea', 'what grants match my research', 'help me find NIH funding', 'grant opportunities for my research', or any grant-related request. NIH-only scope — non-NIH funders (PCORI, DOD CDMRP, VA, foundations) are out of scope and flagged at intake.", "path": "research/grants" }, { "name": "litreview", - "description": "Academic literature orientation skill that searches papers via Consensus, builds a strategic search plan using PICO (default) or SPIDER / Decomposition / hybrid as fallbacks, and synthesizes findings into a professionally formatted Word document (.docx) research guide. Grill-me intake (research question specificity + framework hint + tentative depth) before the recon search; a second forcing checkpoint after Phase 2 confirms framework + sub-areas + depth before searches consume budget. Configurable depth (5/10/20 queries) controls coverage vs. speed. Output is a 'launching pad' \u2014 not a finished review, but an orientation guide that lets a researcher dive in confidently. Triggers: 'litreview on [topic]', 'literature review on [topic]', 'I'm starting a literature review on X', 'I'm writing a paper on X', 'help me research X', 'I'm doing research on X', 'can you help me research X'. Do NOT trigger for single one-off paper searches where the user just wants a quick list \u2014 that's a plain Consensus search.", + "description": "Academic literature orientation skill that searches papers via Consensus, builds a strategic search plan using PICO (default) or SPIDER / Decomposition / hybrid as fallbacks, and synthesizes findings into a professionally formatted Word document (.docx) research guide. Grill-me intake (research question specificity + framework hint + tentative depth) before the recon search; a second forcing checkpoint after Phase 2 confirms framework + sub-areas + depth before searches consume budget. Configurable depth (5/10/20 queries) controls coverage vs. speed. Output is a 'launching pad' — not a finished review, but an orientation guide that lets a researcher dive in confidently. Triggers: 'litreview on [topic]', 'literature review on [topic]', 'I'm starting a literature review on X', 'I'm writing a paper on X', 'help me research X', 'I'm doing research on X', 'can you help me research X'. Do NOT trigger for single one-off paper searches where the user just wants a quick list — that's a plain Consensus search.", "path": "research/litreview" }, { "name": "notebooklm", - "description": "Browser automation skill for controlling Google's NotebookLM. Handles reading and querying notebooks, adding sources (URLs, text, files, YouTube links, synthesized content), generating Studio outputs (Audio Overview, infographics, slide decks, study guides, briefing docs, mind maps, timelines, FAQs), and creating new notebooks. Triggers on any phrase involving NotebookLM \u2014 'open NotebookLM', 'check my [name] notebook', 'pull info from NotebookLM', 'ask my notebook about X', 'add [source] to NotebookLM', 'create an infographic in NotebookLM', 'use NotebookLM Studio', 'generate a slide deck from my notebook', or any variation where the goal involves NotebookLM. Requires browser automation environment \u2014 fails gracefully when unavailable.", + "description": "Browser automation skill for controlling Google's NotebookLM. Handles reading and querying notebooks, adding sources (URLs, text, files, YouTube links, synthesized content), generating Studio outputs (Audio Overview, infographics, slide decks, study guides, briefing docs, mind maps, timelines, FAQs), and creating new notebooks. Triggers on any phrase involving NotebookLM — 'open NotebookLM', 'check my [name] notebook', 'pull info from NotebookLM', 'ask my notebook about X', 'add [source] to NotebookLM', 'create an infographic in NotebookLM', 'use NotebookLM Studio', 'generate a slide deck from my notebook', or any variation where the goal involves NotebookLM. Requires browser automation environment — fails gracefully when unavailable.", "path": "research/notebooklm" }, { "name": "patent", - "description": "Patent prior-art and landscape intelligence skill \u2014 not generic patent help. Commits to one of five sub-use-cases via forcing intake (novelty search / freedom-to-operate / competitive landscape / acquisition diligence / litigation prior-art) before any search runs. Searches Google Patents, Espacenet, USPTO, and optionally Lens.org for citation-graph signals. Output is an editable Word document (.docx) with verdict, ranked closest art (claim-text extracted), CPC-class-aware landscape, family-resolved hits, geographic coverage, FTO flags where applicable, strategy recommendations, and full audit log. Triggers: 'prior art search for [invention]', 'patent search on [topic]', 'freedom to operate analysis', 'FTO for [product]', 'patent landscape for [field]', 'is [invention] novel', 'patents on [topic]', 'competitive patent analysis', 'prior art for litigation', 'patent diligence on [company]'. Produces search signal, not legal advice \u2014 always recommends consulting a patent attorney before filing or licensing decisions. Trademark, copyright, and trade-secret questions are out of scope.", + "description": "Patent prior-art and landscape intelligence skill — not generic patent help. Commits to one of five sub-use-cases via forcing intake (novelty search / freedom-to-operate / competitive landscape / acquisition diligence / litigation prior-art) before any search runs. Searches Google Patents, Espacenet, USPTO, and optionally Lens.org for citation-graph signals. Output is an editable Word document (.docx) with verdict, ranked closest art (claim-text extracted), CPC-class-aware landscape, family-resolved hits, geographic coverage, FTO flags where applicable, strategy recommendations, and full audit log. Triggers: 'prior art search for [invention]', 'patent search on [topic]', 'freedom to operate analysis', 'FTO for [product]', 'patent landscape for [field]', 'is [invention] novel', 'patents on [topic]', 'competitive patent analysis', 'prior art for litigation', 'patent diligence on [company]'. Produces search signal, not legal advice — always recommends consulting a patent attorney before filing or licensing decisions. Trademark, copyright, and trade-secret questions are out of scope.", "path": "research/patent" }, { @@ -1567,167 +1567,167 @@ }, { "name": "research", - "description": "Default entry point for any research request \u2014 a hybrid router that classifies the question deterministically and either delegates to a specialist research skill (pulse for trends/sentiment, grants for NIH funding, litreview for academic literature, syllabus for course reading, patent for prior-art + IP landscape, dossier for entity research) or runs its own plan-decompose-multi-source-search-synthesize-cite fallback workflow when no specialist matches. Always surfaces the routing decision so users can override. Triggers \u2014 \"research [topic]\", \"look into [topic]\", \"what do we know about [topic]\", \"investigate [topic]\", \"find me information on [topic]\", \"do some research on [topic]\", \"I need to understand [topic]\", or any research request that doesn't obviously match a more-specific specialist skill. Output is a markdown briefing (default) or .docx document (on request) with full citations and an audit log.", + "description": "Default entry point for any research request — a hybrid router that classifies the question deterministically and either delegates to a specialist research skill (pulse for trends/sentiment, grants for NIH funding, litreview for academic literature, syllabus for course reading, patent for prior-art + IP landscape, dossier for entity research) or runs its own plan-decompose-multi-source-search-synthesize-cite fallback workflow when no specialist matches. Always surfaces the routing decision so users can override. Triggers — \"research [topic]\", \"look into [topic]\", \"what do we know about [topic]\", \"investigate [topic]\", \"find me information on [topic]\", \"do some research on [topic]\", \"I need to understand [topic]\", or any research request that doesn't obviously match a more-specific specialist skill. Output is a markdown briefing (default) or .docx document (on request) with full citations and an audit log.", "path": "research/research" }, { "name": "syllabus", - "description": "Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs \u2014 so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Triggers whenever a user uploads a syllabus, course outline, or curriculum document and wants supplementary readings. Also triggers on: 'syllabus reading list', 'find papers for my course', 'create a reading list from this syllabus', 'recent research for my class', 'supplementary readings', 'find journal articles for these topics', 'what recent papers cover this material', 'any new research on these course topics', 'update my syllabus with recent papers'. Even casual mentions when a syllabus is attached should trigger this skill.", + "description": "Generates a curated supplementary reading list from any course syllabus using Consensus academic search. Grill-me intake (syllabus input format + course audience + year range) plus a grouping forcing-options checkpoint before any search runs — so the reading list matches the course's level and recency need. Parses the syllabus to extract topics and learning outcomes, searches Consensus for recent peer-reviewed papers per topic, and produces a professionally formatted .docx with clickable Consensus links, plain-language summaries calibrated to audience level, and Bloom-higher-order discussion questions tied to course learning goals. Triggers whenever a user uploads a syllabus, course outline, or curriculum document and wants supplementary readings. Also triggers on: 'syllabus reading list', 'find papers for my course', 'create a reading list from this syllabus', 'recent research for my class', 'supplementary readings', 'find journal articles for these topics', 'what recent papers cover this material', 'any new research on these course topics', 'update my syllabus with recent papers'. Even casual mentions when a syllabus is attached should trigger this skill.", "path": "research/syllabus" } ], "business-operations": [ { "name": "business-operations-skills", - "description": "Use when running, diagnosing, or designing internal business operations \u2014 process documentation, vendor SLAs, capacity planning, internal comms, SOP/runbook authoring, procurement spend. Triggers on \"BizOps review\", \"where's the bottleneck\", \"vendor health\", \"internal SOP\", \"all-hands deck\", \"spend categorization\", \"capacity for Q3\", \"process mapping\". Forks context to route to one of six BizOps sub-skills (process-mapper, vendor-management, capacity-planner, internal-comms, knowledge-ops, procurement-optimizer) and returns a digest. Distinct from business-growth (external sales motion) and c-level-advisor (strategic, not operational).", + "description": "Use when running, diagnosing, or designing internal business operations — process documentation, vendor SLAs, capacity planning, internal comms, SOP/runbook authoring, procurement spend. Triggers on \"BizOps review\", \"where's the bottleneck\", \"vendor health\", \"internal SOP\", \"all-hands deck\", \"spend categorization\", \"capacity for Q3\", \"process mapping\". Forks context to route to one of six BizOps sub-skills (process-mapper, vendor-management, capacity-planner, internal-comms, knowledge-ops, procurement-optimizer) and returns a digest. Distinct from business-growth (external sales motion) and c-level-advisor (strategic, not operational).", "path": "business-operations/business-operations-skills" }, { "name": "capacity-planner", - "description": "Use when an ops leader (Director of CX, Head of Support, VP Ops, Head of BizOps, Head of IT ops, Head of Finance ops) is sizing ops capacity, building a headcount plan, modeling utilization risk, planning Q3 capacity or annual support capacity, or designing CS coverage \u2014 and needs Erlang-C queueing math, P90 demand sizing, shrinkage-adjusted FTE, manager-trigger thresholds, and a quarterly hiring sequence with ramp + attrition. Apply when sustained team utilization is above 80% or when the team is growing >50% in 12 months. Run before committing the headcount budget. This is NOT engineering capacity (see vpe-advisor for DORA + cycle time) and NOT strategic 3-year workforce planning (see chro-advisor).", + "description": "Use when an ops leader (Director of CX, Head of Support, VP Ops, Head of BizOps, Head of IT ops, Head of Finance ops) is sizing ops capacity, building a headcount plan, modeling utilization risk, planning Q3 capacity or annual support capacity, or designing CS coverage — and needs Erlang-C queueing math, P90 demand sizing, shrinkage-adjusted FTE, manager-trigger thresholds, and a quarterly hiring sequence with ramp + attrition. Apply when sustained team utilization is above 80% or when the team is growing >50% in 12 months. Run before committing the headcount budget. This is NOT engineering capacity (see vpe-advisor for DORA + cycle time) and NOT strategic 3-year workforce planning (see chro-advisor).", "path": "business-operations/capacity-planner" }, { "name": "internal-comms", - "description": "Use when a Head of People Ops, BizOps lead, or Internal Communications owner needs to draft and sequence an internal-only change-management communication \u2014 a re-org announcement, a tool rollout, a policy change, a benefit change, a leadership transition, a layoff, an acquisition close, or an internal product launch \u2014 and the audience is employees (not customers). Triggers on \"all-hands announcement\", \"town-hall script\", \"change comms\", \"internal newsletter\", \"rollout comms\", \"policy change announcement\", \"re-org announcement\", \"internal FAQ\", \"manager talking points\", \"Prosci ADKAR\", \"Kotter 8-step\", \"layoff comms\", \"RIF comms\", \"internal memo\". Pairs Prosci ADKAR (Awareness / Desire / Knowledge / Ability / Reinforcement) and Kotter's 8-step change model with deterministic stdlib-only Python tools to produce a sequenced touchpoint calendar, a Kotter-compliant primary announcement, an audience-segmented FAQ, and manager cascade talking points. Industry-tuned via --profile {tech-startup, scaleup, enterprise, public-company, non-profit}. Distinct from marketing-skill/* (external/customer-facing), c-level-advisor/internal-narrative (strategic framing, not tactical drafts), and c-level-advisor/change-management (executive change strategy, not the comms package itself).", + "description": "Use when a Head of People Ops, BizOps lead, or Internal Communications owner needs to draft and sequence an internal-only change-management communication — a re-org announcement, a tool rollout, a policy change, a benefit change, a leadership transition, a layoff, an acquisition close, or an internal product launch — and the audience is employees (not customers). Triggers on \"all-hands announcement\", \"town-hall script\", \"change comms\", \"internal newsletter\", \"rollout comms\", \"policy change announcement\", \"re-org announcement\", \"internal FAQ\", \"manager talking points\", \"Prosci ADKAR\", \"Kotter 8-step\", \"layoff comms\", \"RIF comms\", \"internal memo\". Pairs Prosci ADKAR (Awareness / Desire / Knowledge / Ability / Reinforcement) and Kotter's 8-step change model with deterministic stdlib-only Python tools to produce a sequenced touchpoint calendar, a Kotter-compliant primary announcement, an audience-segmented FAQ, and manager cascade talking points. Industry-tuned via --profile {tech-startup, scaleup, enterprise, public-company, non-profit}. Distinct from marketing-skill/* (external/customer-facing), c-level-advisor/internal-narrative (strategic framing, not tactical drafts), and c-level-advisor/change-management (executive change strategy, not the comms package itself).", "path": "business-operations/internal-comms" }, { "name": "knowledge-ops", - "description": "Use when a Head of Ops, Knowledge Manager, or TPM-Internal needs to author, validate, or clean up company SOPs and internal runbooks (procurement intake, vendor offboarding, incident-comms cascade, employee onboarding, expense reimbursement, system-access provisioning, customer-escalation playbook) \u2014 including 5W2H completeness checks (Who-What-When-Where-Why-How-HowMuch), cross-link and orphan-page validation across a sprawling Notion/Confluence/Obsidian wiki, KB ingestion + hygiene reporting, ops onboarding doc generation, and runbook step verification (named owner, expected duration, observable success signal, rollback path, escalation contact). Pairs Kaoru Ishikawa's 5W2H method, Atul Gawande's *The Checklist Manifesto*, ISO 9001, ITIL v4 Service Operation, FDA 21 CFR Part 211, and Google SRE Workbook runbook discipline with deterministic stdlib-only Python tools that score completeness, detect anti-patterns, and emit prioritized cleanup lists. Distinct from `engineering/llm-wiki` (Karpathy-style personal PKM second brain), `engineering-team/runbook-generator` (system-ops production debugging runbook), `project-management/*` (Jira/Confluence delivery + ticket tracking), and sibling `business-operations/process-mapper` (BPMN process *design*, while knowledge-ops is process *documentation*).", + "description": "Use when a Head of Ops, Knowledge Manager, or TPM-Internal needs to author, validate, or clean up company SOPs and internal runbooks (procurement intake, vendor offboarding, incident-comms cascade, employee onboarding, expense reimbursement, system-access provisioning, customer-escalation playbook) — including 5W2H completeness checks (Who-What-When-Where-Why-How-HowMuch), cross-link and orphan-page validation across a sprawling Notion/Confluence/Obsidian wiki, KB ingestion + hygiene reporting, ops onboarding doc generation, and runbook step verification (named owner, expected duration, observable success signal, rollback path, escalation contact). Pairs Kaoru Ishikawa's 5W2H method, Atul Gawande's *The Checklist Manifesto*, ISO 9001, ITIL v4 Service Operation, FDA 21 CFR Part 211, and Google SRE Workbook runbook discipline with deterministic stdlib-only Python tools that score completeness, detect anti-patterns, and emit prioritized cleanup lists. Distinct from `engineering/llm-wiki` (Karpathy-style personal PKM second brain), `engineering-team/runbook-generator` (system-ops production debugging runbook), `project-management/*` (Jira/Confluence delivery + ticket tracking), and sibling `business-operations/process-mapper` (BPMN process *design*, while knowledge-ops is process *documentation*).", "path": "business-operations/knowledge-ops" }, { "name": "process-mapper", - "description": "Use when a BizOps lead, COO, or process-improvement owner needs to document an end-to-end business process (procurement, employee onboarding, incident handoff, customer-onboarding, claims adjudication) in BPMN-style notation, measure cycle times by stage, surface where work spends most of its time waiting vs. being worked, and quantify the gap between processing time and total elapsed time. Pairs Lean / Six Sigma / Theory-of-Constraints canon with deterministic stdlib-only Python tools to produce a process map, a ranked bottleneck list (with severity + root-cause hypothesis), and a cycle-time analysis (P50, P90, value-add ratio, Little's-Law throughput). Distinct from sales-pipeline, system-reliability (SLO), and strategic-OKR work \u2014 this is tactical process documentation for internal operations.", + "description": "Use when a BizOps lead, COO, or process-improvement owner needs to document an end-to-end business process (procurement, employee onboarding, incident handoff, customer-onboarding, claims adjudication) in BPMN-style notation, measure cycle times by stage, surface where work spends most of its time waiting vs. being worked, and quantify the gap between processing time and total elapsed time. Pairs Lean / Six Sigma / Theory-of-Constraints canon with deterministic stdlib-only Python tools to produce a process map, a ranked bottleneck list (with severity + root-cause hypothesis), and a cycle-time analysis (P50, P90, value-add ratio, Little's-Law throughput). Distinct from sales-pipeline, system-reliability (SLO), and strategic-OKR work — this is tactical process documentation for internal operations.", "path": "business-operations/process-mapper" }, { "name": "procurement-optimizer", - "description": "Use when running an annual SaaS audit, doing category-level spend review, or rationalizing the supplier base \u2014 when the user needs to do a spend audit, spend categorization (UNSPSC-aligned), purchasing-cycle analysis, or risk-balanced supplier consolidation. Triggers on \"spend audit\", \"SaaS audit\", \"spend categorization\", \"supplier rationalization\", \"supplier consolidation\", \"purchasing cycle\", \"procurement review\", \"category strategy\", \"duplicate SaaS\", \"renewal cluster\". Ships 3 stdlib-only Python tools (UNSPSC-aligned spend categorizer with Pareto breakdown and industry profiles, purchasing-cycle analyzer that surfaces bottleneck categories per Goldratt's Theory of Constraints, supplier-consolidation planner that refuses single-source recommendations for tier-1 categories without a documented break-glass plan), 3 reference docs each citing 7+ authoritative sources (A.T. Kearney / Hackett / Spend Matters / UNSPSC / Productiv / Vendr / Tropic / IACCM / ISM / BCG), and a 20-minute spend-intake template. Distinct from sibling vendor-management (performance scoring of vendors you keep paying), finance/financial-analysis (close + report, not category strategy), and c-level-advisor/general-counsel-advisor (contract law, not category rationalization).", + "description": "Use when running an annual SaaS audit, doing category-level spend review, or rationalizing the supplier base — when the user needs to do a spend audit, spend categorization (UNSPSC-aligned), purchasing-cycle analysis, or risk-balanced supplier consolidation. Triggers on \"spend audit\", \"SaaS audit\", \"spend categorization\", \"supplier rationalization\", \"supplier consolidation\", \"purchasing cycle\", \"procurement review\", \"category strategy\", \"duplicate SaaS\", \"renewal cluster\". Ships 3 stdlib-only Python tools (UNSPSC-aligned spend categorizer with Pareto breakdown and industry profiles, purchasing-cycle analyzer that surfaces bottleneck categories per Goldratt's Theory of Constraints, supplier-consolidation planner that refuses single-source recommendations for tier-1 categories without a documented break-glass plan), 3 reference docs each citing 7+ authoritative sources (A.T. Kearney / Hackett / Spend Matters / UNSPSC / Productiv / Vendr / Tropic / IACCM / ISM / BCG), and a 20-minute spend-intake template. Distinct from sibling vendor-management (performance scoring of vendors you keep paying), finance/financial-analysis (close + report, not category strategy), and c-level-advisor/general-counsel-advisor (contract law, not category rationalization).", "path": "business-operations/procurement-optimizer" }, { "name": "vendor-management", - "description": "Use when reviewing, scoring, or auditing third-party SaaS / vendor relationships \u2014 running a vendor scorecard, tracking SLA compliance, classifying third-party risk, preparing a tier-1 vendor review, or auditing the SaaS portfolio. Triggers on \"vendor SLA\", \"vendor scorecard\", \"third-party risk\", \"TPRM\", \"vendor review\", \"SaaS audit\", \"supplier performance\", \"vendor health check\", \"renewal review\". Forks context so large vendor catalogs (50-500 line items) and SLA logs don't pollute the parent thread. Ships 3 stdlib-only Python tools (vendor scorer with industry tuning, SLA compliance tracker with credit-claim flags, vendor risk classifier across 4 risk vectors), 3 reference docs each citing 7+ authoritative sources (Gartner / Shared Assessments / NIST / ISO 27036 / breach post-mortems), and a 5-vendor catalog template. Distinct from c-level-advisor/general-counsel-advisor (contract law, not operational management), business-growth/contract-and-proposal-writer (outbound proposals, not inbound vendor scoring), and sibling procurement-optimizer (spend categorization, not vendor performance).", + "description": "Use when reviewing, scoring, or auditing third-party SaaS / vendor relationships — running a vendor scorecard, tracking SLA compliance, classifying third-party risk, preparing a tier-1 vendor review, or auditing the SaaS portfolio. Triggers on \"vendor SLA\", \"vendor scorecard\", \"third-party risk\", \"TPRM\", \"vendor review\", \"SaaS audit\", \"supplier performance\", \"vendor health check\", \"renewal review\". Forks context so large vendor catalogs (50-500 line items) and SLA logs don't pollute the parent thread. Ships 3 stdlib-only Python tools (vendor scorer with industry tuning, SLA compliance tracker with credit-claim flags, vendor risk classifier across 4 risk vectors), 3 reference docs each citing 7+ authoritative sources (Gartner / Shared Assessments / NIST / ISO 27036 / breach post-mortems), and a 5-vendor catalog template. Distinct from c-level-advisor/general-counsel-advisor (contract law, not operational management), business-growth/contract-and-proposal-writer (outbound proposals, not inbound vendor scoring), and sibling procurement-optimizer (spend categorization, not vendor performance).", "path": "business-operations/vendor-management" } ], "commercial": [ { "name": "channel-economics", - "description": "Use when reviewing or rebalancing direct vs. partner-led channel economics \u2014 computing fully-loaded cost-to-serve per channel, channel ROI with cash / LTV / marginal lenses, and optimal channel mix subject to constraints. For Head of Commercial, RevOps, and VP Sales doing quarterly channel review when pipeline is mixed (e.g., 60% direct + 40% partner-led) and nobody actually knows which channel makes money after CAC, support load, partner discount, deal-velocity differences, retention differential, and overhead allocation are all loaded in. Outputs cost to serve, channel ROI verdicts (DOUBLE-DOWN / MAINTAIN / DEFUND / EXIT), a sensitivity-tested channel-mix recommendation, and the diminishing-returns inflection. Not channel structure (that's partnerships-architect \u2014 tiers, joint GTM, revshare). Not RevOps process (that's business-growth/revenue-operations \u2014 lead routing, SDR motion). Not strategic CRO judgment (that's c-level-advisor/cro-advisor \u2014 comp plans, when-to-hire-a-VP-Sales). Not historical close-and-report (that's finance/financial-analysis). This skill answers: direct vs partner profitability, channel profitability, channel mix, channel economics.", + "description": "Use when reviewing or rebalancing direct vs. partner-led channel economics — computing fully-loaded cost-to-serve per channel, channel ROI with cash / LTV / marginal lenses, and optimal channel mix subject to constraints. For Head of Commercial, RevOps, and VP Sales doing quarterly channel review when pipeline is mixed (e.g., 60% direct + 40% partner-led) and nobody actually knows which channel makes money after CAC, support load, partner discount, deal-velocity differences, retention differential, and overhead allocation are all loaded in. Outputs cost to serve, channel ROI verdicts (DOUBLE-DOWN / MAINTAIN / DEFUND / EXIT), a sensitivity-tested channel-mix recommendation, and the diminishing-returns inflection. Not channel structure (that's partnerships-architect — tiers, joint GTM, revshare). Not RevOps process (that's business-growth/revenue-operations — lead routing, SDR motion). Not strategic CRO judgment (that's c-level-advisor/cro-advisor — comp plans, when-to-hire-a-VP-Sales). Not historical close-and-report (that's finance/financial-analysis). This skill answers: direct vs partner profitability, channel profitability, channel mix, channel economics.", "path": "commercial/channel-economics" }, { "name": "commercial-forecaster", - "description": "Use when building a quarterly bookings forecast, ARR projection, pipeline forecast, NRR projection, or commit/best-case/pipe-only board number \u2014 especially when the CRO needs to walk the board through funnel math + cohort ARR + per-stage conversion assumptions without the theatre of a single undefended number. Decomposes pipeline into commit, best-case, and pipe-only tiers; projects cohort-level NRR/GRR to surface leaky cohorts before they show up in the consolidated number; scores per-stage funnel confidence so soft-floor stages get treated differently from high-confidence ones. Every output explicitly names the conversion rate used, the data window, and the weighting choice. For Head of Commercial, RevOps, VP Sales, and CRO at quarterly forecast or board prep. NOT financial close (see finance/financial-analysis). NOT strategic CRO hiring/territory (see c-level-advisor/cro-advisor). NOT pricing (see sibling pricing-strategist).", + "description": "Use when building a quarterly bookings forecast, ARR projection, pipeline forecast, NRR projection, or commit/best-case/pipe-only board number — especially when the CRO needs to walk the board through funnel math + cohort ARR + per-stage conversion assumptions without the theatre of a single undefended number. Decomposes pipeline into commit, best-case, and pipe-only tiers; projects cohort-level NRR/GRR to surface leaky cohorts before they show up in the consolidated number; scores per-stage funnel confidence so soft-floor stages get treated differently from high-confidence ones. Every output explicitly names the conversion rate used, the data window, and the weighting choice. For Head of Commercial, RevOps, VP Sales, and CRO at quarterly forecast or board prep. NOT financial close (see finance/financial-analysis). NOT strategic CRO hiring/territory (see c-level-advisor/cro-advisor). NOT pricing (see sibling pricing-strategist).", "path": "commercial/commercial-forecaster" }, { "name": "commercial-policy", - "description": "Use when designing or revising a company's commercial policy \u2014 the rules of engagement governing discounts off list price, approver thresholds, exception flows, and the deal framework that Deal Desk and AEs operate under. Covers discount matrix design (ARR band x term length x payment terms x strategic value), commercial policy design, exception policy, discount governance, approval thresholds, deal framework structure, and policy linting (contradictions, gaps, cliff edges, gaming surfaces). For Head of Commercial, Head of Deal Desk, VP Sales, or RevOps at the policy-design moment \u2014 NOT per-deal application (that is deal-desk) and NOT pricing model selection (that is pricing-strategist).", + "description": "Use when designing or revising a company's commercial policy — the rules of engagement governing discounts off list price, approver thresholds, exception flows, and the deal framework that Deal Desk and AEs operate under. Covers discount matrix design (ARR band x term length x payment terms x strategic value), commercial policy design, exception policy, discount governance, approval thresholds, deal framework structure, and policy linting (contradictions, gaps, cliff edges, gaming surfaces). For Head of Commercial, Head of Deal Desk, VP Sales, or RevOps at the policy-design moment — NOT per-deal application (that is deal-desk) and NOT pricing model selection (that is pricing-strategist).", "path": "commercial/commercial-policy" }, { "name": "commercial-skills", - "description": "Use when reviewing, approving, or designing commercial motion \u2014 pricing models, deal review, discount approval, partnership economics, channel mix, commercial policy, RFP/RFI response, bookings forecast. Triggers on \"review this deal\", \"should we discount\", \"pricing model\", \"partner economics\", \"RFP response\", \"bookings forecast\", \"channel mix\". Forks context to route to one of seven Commercial sub-skills (pricing-strategist, deal-desk, partnerships-architect, channel-economics, commercial-policy, rfp-responder, commercial-forecaster) and returns a digest. Distinct from business-growth (sales execution) and c-level-advisor/cro-advisor (strategic CRO judgment).", + "description": "Use when reviewing, approving, or designing commercial motion — pricing models, deal review, discount approval, partnership economics, channel mix, commercial policy, RFP/RFI response, bookings forecast. Triggers on \"review this deal\", \"should we discount\", \"pricing model\", \"partner economics\", \"RFP response\", \"bookings forecast\", \"channel mix\". Forks context to route to one of seven Commercial sub-skills (pricing-strategist, deal-desk, partnerships-architect, channel-economics, commercial-policy, rfp-responder, commercial-forecaster) and returns a digest. Distinct from business-growth (sales execution) and c-level-advisor/cro-advisor (strategic CRO judgment).", "path": "commercial/commercial-skills" }, { "name": "deal-desk", - "description": "Use when reviewing a specific inbound deal before close \u2014 when sales has asked for a discount that exceeds AE authority, when the customer has redlined the MSA, when per-deal economics (margin after discount, multi-year payment shape, indemnity exposure) need to be quantified, or when discount approval needs to be routed to a named human approver (Sales Director, VP Sales, CFO, CRO, General Counsel). Covers deal review, discount approval routing, per-deal margin scoring, deal exception handling, MSA redline triage, contract landmine detection (uncapped indemnity, MFN, perpetual license-back, missing DPA), and named-approver chain assembly. NEVER auto-approves \u2014 every output is a numeric scorecard plus a routing recommendation to a named human.", + "description": "Use when reviewing a specific inbound deal before close — when sales has asked for a discount that exceeds AE authority, when the customer has redlined the MSA, when per-deal economics (margin after discount, multi-year payment shape, indemnity exposure) need to be quantified, or when discount approval needs to be routed to a named human approver (Sales Director, VP Sales, CFO, CRO, General Counsel). Covers deal review, discount approval routing, per-deal margin scoring, deal exception handling, MSA redline triage, contract landmine detection (uncapped indemnity, MFN, perpetual license-back, missing DPA), and named-approver chain assembly. NEVER auto-approves — every output is a numeric scorecard plus a routing recommendation to a named human.", "path": "commercial/deal-desk" }, { "name": "partnerships-architect", - "description": "Use when a startup is approached by a prospective partner and someone has to decide should we sign this partner, at what partner tier (referral / reseller / OEM / SI-consulting / strategic alliance), with what joint GTM commitment, and at what revshare. Classifies partner tier from independent-demand evidence vs. preferential-terms hunting, designs a 90-day joint GTM plan, models revshare against direct-sale margin, and surfaces kill criteria for unwinding under-performing partnerships. For Head of Partnerships, Head of BD, and Founder-CEOs doing reseller agreement, OEM deal, or strategic alliance review \u2014 not technical sale enablement, not channel cost economics, not M&A.", + "description": "Use when a startup is approached by a prospective partner and someone has to decide should we sign this partner, at what partner tier (referral / reseller / OEM / SI-consulting / strategic alliance), with what joint GTM commitment, and at what revshare. Classifies partner tier from independent-demand evidence vs. preferential-terms hunting, designs a 90-day joint GTM plan, models revshare against direct-sale margin, and surfaces kill criteria for unwinding under-performing partnerships. For Head of Partnerships, Head of BD, and Founder-CEOs doing reseller agreement, OEM deal, or strategic alliance review — not technical sale enablement, not channel cost economics, not M&A.", "path": "commercial/partnerships-architect" }, { "name": "pricing-strategist", - "description": "Use when designing or revisiting product pricing \u2014 selecting a pricing model (subscription seat-based, usage-based, value-based, freemium, or hybrid), running Van Westendorp Price Sensitivity Meter analysis on WTP survey data, or designing Good/Better/Best packaging tiers. Recommends a model and a price range with trade-offs, never a single number. For Commercial leads, Product Marketing, and CMOs at the pricing-design moment \u2014 not deal-by-deal discounting, not brand positioning.", + "description": "Use when designing or revisiting product pricing — selecting a pricing model (subscription seat-based, usage-based, value-based, freemium, or hybrid), running Van Westendorp Price Sensitivity Meter analysis on WTP survey data, or designing Good/Better/Best packaging tiers. Recommends a model and a price range with trade-offs, never a single number. For Commercial leads, Product Marketing, and CMOs at the pricing-design moment — not deal-by-deal discounting, not brand positioning.", "path": "commercial/pricing-strategist" }, { "name": "rfp-responder", - "description": "Use when an RFP, RFI, RFQ, security questionnaire, vendor questionnaire, or proposal request arrives and the team needs a structured response \u2014 parsing multi-section buyer-dictated requirements (MANDATORY vs WEIGHTED vs NICE-TO-HAVE), building a Shipley-method proof-point matrix mapping each requirement to a verifiable proof point, articulating 3-5 win-themes that ladder up across requirements, and producing a Shipley-derived winrate estimate that informs a bid / no-bid / partner-bid recommendation. For Bid Managers, Proposal Leads, Directors of Sales, and Sales Engineers at the response-strategy moment. Surfaces GAP requirements explicitly \u2014 never invents claims. NOT free-form proposal narrative authoring, NOT contract redline, NOT marketing collateral.", + "description": "Use when an RFP, RFI, RFQ, security questionnaire, vendor questionnaire, or proposal request arrives and the team needs a structured response — parsing multi-section buyer-dictated requirements (MANDATORY vs WEIGHTED vs NICE-TO-HAVE), building a Shipley-method proof-point matrix mapping each requirement to a verifiable proof point, articulating 3-5 win-themes that ladder up across requirements, and producing a Shipley-derived winrate estimate that informs a bid / no-bid / partner-bid recommendation. For Bid Managers, Proposal Leads, Directors of Sales, and Sales Engineers at the response-strategy moment. Surfaces GAP requirements explicitly — never invents claims. NOT free-form proposal narrative authoring, NOT contract redline, NOT marketing collateral.", "path": "commercial/rfp-responder" } ], "research-ops": [ { "name": "clinical-research", - "description": "Use when designing a prospective clinical study before submission \u2014 selecting and classifying endpoints (primary / key-secondary / exploratory, with surrogate-endpoint flagging), estimating sample size and power for two-arm designs (means / proportions / survival), or scoring a study plan for feasibility and a GO / GO-WITH-CONDITIONS / REDESIGN / NO-GO phase-gate decision. Every output is an ESTIMATE plus a named human owner (clinician / biostatistician / regulatory owner) \u2014 never clinical fact, never a finished protocol. Distinct from ra-qm-team, which handles the regulatory/QM submission (ISO 13485, EU MDR, FDA 510(k)/PMA/QSR), not the study design.", + "description": "Use when designing a prospective clinical study before submission — selecting and classifying endpoints (primary / key-secondary / exploratory, with surrogate-endpoint flagging), estimating sample size and power for two-arm designs (means / proportions / survival), or scoring a study plan for feasibility and a GO / GO-WITH-CONDITIONS / REDESIGN / NO-GO phase-gate decision. Every output is an ESTIMATE plus a named human owner (clinician / biostatistician / regulatory owner) — never clinical fact, never a finished protocol. Distinct from ra-qm-team, which handles the regulatory/QM submission (ISO 13485, EU MDR, FDA 510(k)/PMA/QSR), not the study design.", "path": "research-ops/clinical-research" }, { "name": "market-research", - "description": "Use when doing upstream market-research methodology \u2014 sizing a market as TAM/SAM/SOM computed BOTH top-down and bottoms-up (never a single unsourced number), planning a survey sample size with finite-population correction and per-segment minimums, or scoring candidate market segments against Kotler's measurable/substantial/accessible/differentiable/actionable criteria. Outputs always show the method and the assumptions. For market-research analysts and product-marketing at the sizing/survey/segmentation moment. Distinct from marketing-skill (campaign analytics, attribution, demand-gen) \u2014 this is the evidence-building methodology, not live-campaign optimization.", + "description": "Use when doing upstream market-research methodology — sizing a market as TAM/SAM/SOM computed BOTH top-down and bottoms-up (never a single unsourced number), planning a survey sample size with finite-population correction and per-segment minimums, or scoring candidate market segments against Kotler's measurable/substantial/accessible/differentiable/actionable criteria. Outputs always show the method and the assumptions. For market-research analysts and product-marketing at the sizing/survey/segmentation moment. Distinct from marketing-skill (campaign analytics, attribution, demand-gen) — this is the evidence-building methodology, not live-campaign optimization.", "path": "research-ops/market-research" }, { "name": "product-research", - "description": "Use when planning and synthesizing product/user research as a method-and-repository discipline \u2014 selecting the right method for the goal (generative interviews vs usability test vs concept test vs validation), computing method-based saturation/sample size with an explicit confidence level, or synthesizing coded observations into insights while flagging single-source anecdotes. Never fabricates user insight; an insight requires recurrence across independent participants. Distinct from product-team/ux-researcher-designer (persona/journey artifacts), product-discovery (discovery-sprint planning), and experiment-designer (live A/B) \u2014 this is the research-ops method + insight-repository layer.", + "description": "Use when planning and synthesizing product/user research as a method-and-repository discipline — selecting the right method for the goal (generative interviews vs usability test vs concept test vs validation), computing method-based saturation/sample size with an explicit confidence level, or synthesizing coded observations into insights while flagging single-source anecdotes. Never fabricates user insight; an insight requires recurrence across independent participants. Distinct from product-team/ux-researcher-designer (persona/journey artifacts), product-discovery (discovery-sprint planning), and experiment-designer (live A/B) — this is the research-ops method + insight-repository layer.", "path": "research-ops/product-research" }, { "name": "research-finance", - "description": "Use when managing the money for an internal R&D program or portfolio \u2014 building a multi-period program budget with the F&A (indirect) split, tracking burn rate and runway against value-inflection milestones, or routing R&D cost items to a capitalize-vs-expense determination. Every budget output surfaces its assumptions block; capitalize-vs-expense is decision-support only and routes to a named finance owner \u2014 it never books an entry or decides accounting treatment. Distinct from finance/financial-analysis (corporate DCF, close, valuation) and research/grants (funding discovery \u2014 this manages money already won).", + "description": "Use when managing the money for an internal R&D program or portfolio — building a multi-period program budget with the F&A (indirect) split, tracking burn rate and runway against value-inflection milestones, or routing R&D cost items to a capitalize-vs-expense determination. Every budget output surfaces its assumptions block; capitalize-vs-expense is decision-support only and routes to a named finance owner — it never books an entry or decides accounting treatment. Distinct from finance/financial-analysis (corporate DCF, close, valuation) and research/grants (funding discovery — this manages money already won).", "path": "research-ops/research-finance" }, { "name": "research-ops-skills", - "description": "Use when planning, funding, scoping, or synthesizing enterprise research across workstreams \u2014 clinical study design, R&D program finance, market sizing/surveys, or product/user research. Triggers on \"design this clinical study\", \"what sample size\", \"R&D budget\", \"burn rate\", \"capitalize or expense\", \"TAM SAM SOM\", \"market sizing\", \"survey design\", \"segment the market\", \"plan user interviews\", \"usability test\", \"synthesize research insights\". Forks context to route to one of four Research-Operations sub-skills (clinical-research, research-finance, market-research, product-research) and returns a digest. Distinct from ra-qm-team (regulatory submission), finance (corporate close/valuation), research/grants (funding discovery), product-team (persona/journey/live experiments), and marketing-skill (campaign analytics).", + "description": "Use when planning, funding, scoping, or synthesizing enterprise research across workstreams — clinical study design, R&D program finance, market sizing/surveys, or product/user research. Triggers on \"design this clinical study\", \"what sample size\", \"R&D budget\", \"burn rate\", \"capitalize or expense\", \"TAM SAM SOM\", \"market sizing\", \"survey design\", \"segment the market\", \"plan user interviews\", \"usability test\", \"synthesize research insights\". Forks context to route to one of four Research-Operations sub-skills (clinical-research, research-finance, market-research, product-research) and returns a digest. Distinct from ra-qm-team (regulatory submission), finance (corporate close/valuation), research/grants (funding discovery), product-team (persona/journey/live experiments), and marketing-skill (campaign analytics).", "path": "research-ops/research-ops-skills" } ], "compliance-os": [ { "name": "ai-act-readiness", - "description": "/cs:ai-act-readiness \u2014 EU AI Act 6-question forcing interrogation. Use during AI-system intake, before EU deployment, or during annual compliance refresh as Article 113 obligations phase in (2025-02-02 / 2025-08-02 / 2026-08-02 / 2027-08-02).", + "description": "/cs:ai-act-readiness — EU AI Act 6-question forcing interrogation. Use during AI-system intake, before EU deployment, or during annual compliance refresh as Article 113 obligations phase in (2025-02-02 / 2025-08-02 / 2026-08-02 / 2027-08-02).", "path": "compliance-os/ai-act-readiness" }, { "name": "aims-audit", - "description": "/cs:aims-audit \u2014 ISO/IEC 42001 AIMS internal-audit 6-question forcing interrogation. Use before certification stage 1, before annual internal audit cycles, or when onboarding a new AI system into an existing AIMS.", + "description": "/cs:aims-audit — ISO/IEC 42001 AIMS internal-audit 6-question forcing interrogation. Use before certification stage 1, before annual internal audit cycles, or when onboarding a new AI system into an existing AIMS.", "path": "compliance-os/aims-audit" }, { "name": "compliance-os", - "description": "Compliance OS \u2014 meta-orchestrator that lets compliance teams CONFIGURE which frameworks apply, COMPUTE cross-framework control overlap, SIMULATE internal audits, and CONSOLIDATE evidence across multiple frameworks. Four decisions: (1) Given a company profile, which of the 12 supported frameworks apply (ISO 27001/13485/42001/14971, EU AI Act, MDR 745, GDPR, SOC 2, FDA QSR, NIST CSF 2.0, NIS2, HIPAA)? (2) Across selected frameworks, which controls overlap and how much evidence reuses? (3) For a given framework + scope, what does a realistic mock audit produce \u2014 drawing from the 205-scenario library? (4) Across selected frameworks, what's the unified evidence checklist with reuse map? Use when standing up a multi-framework program, planning the annual audit calendar, or preparing for certification stage 1. Does NOT replace per-framework skills (it orchestrates them).", + "description": "Compliance OS — meta-orchestrator that lets compliance teams CONFIGURE which frameworks apply, COMPUTE cross-framework control overlap, SIMULATE internal audits, and CONSOLIDATE evidence across multiple frameworks. Four decisions: (1) Given a company profile, which of the 12 supported frameworks apply (ISO 27001/13485/42001/14971, EU AI Act, MDR 745, GDPR, SOC 2, FDA QSR, NIST CSF 2.0, NIS2, HIPAA)? (2) Across selected frameworks, which controls overlap and how much evidence reuses? (3) For a given framework + scope, what does a realistic mock audit produce — drawing from the 205-scenario library? (4) Across selected frameworks, what's the unified evidence checklist with reuse map? Use when standing up a multi-framework program, planning the annual audit calendar, or preparing for certification stage 1. Does NOT replace per-framework skills (it orchestrates them).", "path": "compliance-os/compliance-os" }, { "name": "compliance-readiness", - "description": "/cs:compliance-readiness \u2014 Multi-framework compliance officer 6-question forcing interrogation of any compliance program. Use before starting a new framework, planning the annual audit calendar, or preparing for certification stage 1.", + "description": "/cs:compliance-readiness — Multi-framework compliance officer 6-question forcing interrogation of any compliance program. Use before starting a new framework, planning the annual audit calendar, or preparing for certification stage 1.", "path": "compliance-os/compliance-readiness" }, { "name": "fda-qsr-audit-prep", - "description": "/cs:fda-qsr-audit-prep \u2014 FDA 21 CFR 820 (QSR / QMSR) audit 6-question forcing interrogation. Post-Feb 2026 substantially harmonized with ISO 13485. Use before annual internal QSR audit, pre-FDA-inspection readiness, or Form 483 response.", + "description": "/cs:fda-qsr-audit-prep — FDA 21 CFR 820 (QSR / QMSR) audit 6-question forcing interrogation. Post-Feb 2026 substantially harmonized with ISO 13485. Use before annual internal QSR audit, pre-FDA-inspection readiness, or Form 483 response.", "path": "compliance-os/fda-qsr-audit-prep" }, { "name": "gdpr-audit-prep", - "description": "/cs:gdpr-audit-prep \u2014 GDPR audit 6-question Article-cited forcing interrogation. Use before annual internal GDPR review, post-breach internal audit, DPA investigation readiness, or acquisition due diligence.", + "description": "/cs:gdpr-audit-prep — GDPR audit 6-question Article-cited forcing interrogation. Use before annual internal GDPR review, post-breach internal audit, DPA investigation readiness, or acquisition due diligence.", "path": "compliance-os/gdpr-audit-prep" }, { "name": "iso13485-audit-prep", - "description": "/cs:iso13485-audit-prep \u2014 ISO 13485 QMS audit 6-question forcing interrogation. Design controls + CAPA + post-market focused. Use before Clause 8.2.4 internal audit, MDR / FDA QSR alignment review, or product-launch DHF closure audit.", + "description": "/cs:iso13485-audit-prep — ISO 13485 QMS audit 6-question forcing interrogation. Design controls + CAPA + post-market focused. Use before Clause 8.2.4 internal audit, MDR / FDA QSR alignment review, or product-launch DHF closure audit.", "path": "compliance-os/iso13485-audit-prep" }, { "name": "iso27001-audit-prep", - "description": "/cs:iso27001-audit-prep \u2014 ISO 27001 ISMS audit readiness 6-question forcing interrogation. Use before annual Clause 9.2 internal audit, surveillance audit prep, or stage 1 certification readiness.", + "description": "/cs:iso27001-audit-prep — ISO 27001 ISMS audit readiness 6-question forcing interrogation. Use before annual Clause 9.2 internal audit, surveillance audit prep, or stage 1 certification readiness.", "path": "compliance-os/iso27001-audit-prep" }, { "name": "soc2-audit-prep", - "description": "/cs:soc2-audit-prep \u2014 SOC 2 Type II readiness 6-question forcing interrogation. Observation-period focused. Use before Type II observation begins, mid-period checkpoint, or pre-field-test month-10 readiness.", + "description": "/cs:soc2-audit-prep — SOC 2 Type II readiness 6-question forcing interrogation. Observation-period focused. Use before Type II observation begins, mid-period checkpoint, or pre-field-test month-10 readiness.", "path": "compliance-os/soc2-audit-prep" } ] } -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f87cac0..ab6acdd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1029,7 +1029,7 @@ This release establishes the pattern for deriving MIT-licensed external skills i ### Fixed -- **3 missing voice specs added to `c-level-advisor/c-level-agents/references/persona-voices.md`:** +- **3 missing voice specs added to `c-level-agents/references/persona-voices.md`:** - `cs-ceo-advisor` — The Strategic Translator (tree-of-thought reasoning; refuses to debate tactics until the strategic question is named) - `cs-cto-advisor` — The Architecture-First Pragmatist (ReAct reasoning; treats every architecture decision as a 3-year commitment) - `cs-general-counsel-advisor` — The Risk-Paranoid Lawyer (Not Your Lawyer) — carry-over from v2.5.1 @@ -1045,7 +1045,7 @@ Both gaps were carry-over items noted across multiple PRs in this session (v2.5. ### Changed -- `c-level-advisor/c-level-agents/references/persona-voices.md` — 13 → 13 voice specs cataloged (all cs-* agents in the persona-voices list now match the agents that exist) +- `c-level-agents/references/persona-voices.md` — 13 → 13 voice specs cataloged (all cs-* agents in the persona-voices list now match the agents that exist) - `agents/c-level/cs-ceo-advisor.md` — 32 path corrections - `agents/c-level/cs-cto-advisor.md` — 25 path corrections @@ -1070,8 +1070,8 @@ No skill/agent/command count changes; no manifest version bumps (this is a pure- - `engineering_hiring_funnel.md` — 7-stage funnel + healthy conversion benchmarks + leakage diagnosis per stage + pipeline volume math + sourcing channel diversification + technical interview design + cost-per-hire. Cites LinkedIn Talent Insights, Atlassian Recruiting Ops, Levels.fyi + Pave, Lou Adler "Hire With Your Head", Adler/Bock "Work Rules!", CMU/Booth interview validity research, SHRM surveys. - `eng_team_structure.md` — Conway's Law + headcount-to-structure map + span-of-control benchmarks + EM vs tech lead distinction + manager/director/VPE triggers + squad sizing + chapter discipline. Cites Kniberg "Scaling Agile @ Spotify", Kniberg 2020 retrospective, Will Larson "Elegant Puzzle", Camille Fournier "Manager's Path", Conway 1968, Schwartz "A Seat at the Table", Lencioni "Five Dysfunctions", Stripe/Shopify/GitHub/Netflix engineering blogs. - `production_discipline.md` — On-call rotation design (≥ 6 people; burnout signals) + incident response (4-tier severity, IC role, blameless postmortems) + deployment cadence (continuous vs scheduled; progressive delivery) + SLO discipline integration + 5-level maturity model. Cites Google SRE (Beyer/Jones/Petoff/Murphy), SRE Workbook, John Allspaw postmortem writings, PagerDuty Incident Response docs, Charity Majors observability, Nora Jones chaos engineering, Mikey Dickerson reliability hierarchy. -- **cs-vpe-advisor** agent (`./c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md`) — throughput-first operator. Voice: "What's your cycle time, and where does the work spend most of its time waiting?" Trusts DORA metrics over vibe. Refuses to recommend hires without naming the throughput or quality bottleneck they unblock. -- **`/cs:vpe-review`** slash command (`./c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md`) — 6-question forcing interrogation: cycle time + waits, DORA verdict, hiring funnel leakage, team structure health, production discipline maturity, VPE-vs-CTO scope decision. +- **cs-vpe-advisor** agent (`./c-level-agents/agents/cs-vpe-advisor.md`) — throughput-first operator. Voice: "What's your cycle time, and where does the work spend most of its time waiting?" Trusts DORA metrics over vibe. Refuses to recommend hires without naming the throughput or quality bottleneck they unblock. +- **`/cs:vpe-review`** slash command (`./c-level-agents/skills/vpe-review/SKILL.md`) — 6-question forcing interrogation: cycle time + waits, DORA verdict, hiring funnel leakage, team structure health, production discipline maturity, VPE-vs-CTO scope decision. - **cs-vpe-advisor voice spec** added to `persona-voices.md`. - **Dual-published from the start:** standalone plugin at `c-level-advisor/vpe-advisor/` with mirrored content (per #624 pattern). `sync_skill_bundles.py` keeps both copies aligned. @@ -1132,8 +1132,8 @@ DORA benchmarks come from cross-industry research; specific thresholds shift wit - `customer_segmentation_strategy.md` — 4-tier framework + ICP fit weighting (7 signals) + tier transition triggers + kill list criteria + the 3 paths. Cites Lincoln Murphy, Bain "Loyalty Effect", Tunguz, Skok, ChartMogul/ProfitWell, Adamson/Dixon/Toman "Challenger Customer". - `cs_coverage_model.md` — Tech-touch / pooled / named / named+exec models + ARR-per-CSM ratios by stage and segment + manager-trigger + CS comp design + ramp curves. Cites Gainsight, TSIA, Mehta/Pickens "Customer Success Economy", ChurnZero, Skok, Lincoln Murphy, Pacific Crest/KeyBanc SaaS survey. - `cs_team_org_evolution.md` — 5-stage role map + 6-role definition table (CSM ≠ Support ≠ AM ≠ IM ≠ CS Ops ≠ Customer Marketing) + AM-vs-CSM split decision + 7 anti-patterns. Cites Mehta/Steinman/Murphy, Mehta/Pickens, BVP, TSIA, Gainsight, ChurnZero, Lincoln Murphy. -- **cs-cco-advisor** agent (`./c-level-advisor/c-level-agents/agents/cs-cco-advisor.md`) — retention-obsessed pragmatist. Voice: "What's your gross retention rate, and what's the #1 reason customers leave?" Trusts gross retention over NRR. Refuses to recommend CS hires without naming the customer outcome they unblock. -- **`/cs:cco-review`** slash command (`./c-level-advisor/c-level-agents/skills/cco-review/SKILL.md`) — 6-question forcing interrogation: GRR (not NRR), top churn driver, time-to-value, kill-list candidates, ARR-per-CSM ratio + coverage model, CS comp alignment. +- **cs-cco-advisor** agent (`./c-level-agents/agents/cs-cco-advisor.md`) — retention-obsessed pragmatist. Voice: "What's your gross retention rate, and what's the #1 reason customers leave?" Trusts gross retention over NRR. Refuses to recommend CS hires without naming the customer outcome they unblock. +- **`/cs:cco-review`** slash command (`./c-level-agents/skills/cco-review/SKILL.md`) — 6-question forcing interrogation: GRR (not NRR), top churn driver, time-to-value, kill-list candidates, ARR-per-CSM ratio + coverage model, CS comp alignment. - **cs-cco-advisor voice spec** added to `persona-voices.md`. - **Dual-published from the start:** standalone plugin at `c-level-advisor/chief-customer-officer-advisor/` with mirrored content (per the same pattern as #624 for GC/CDO/CAIO). `sync_skill_bundles.py` keeps both copies aligned. @@ -1195,8 +1195,8 @@ Retention benchmarks vary significantly by ACV, segment, and industry. This skil - `ai_risk_governance.md` — Full EU AI Act tier map (prohibited Article 5, high-risk Article 6 + Annex III, limited-risk Article 50, minimal-risk) with all 8 high-risk domains + 11 obligation Articles. NIST AI RMF 1.0 (4 functions, 7 trustworthy characteristics). US state patchwork (NYC LL 144, CO AI Act, IL HB 53, CA SB 1001, CA AB 2013, CA AB 1008, IL BIPA, WA MHMD, TX biometric). Industry overlays (FDA, CFPB, Fed SR 11-7, NYDFS Reg 23, ECOA, NAIC). 10-item governance program checklist. When-to-hire-AI-counsel criteria. - `ai_cost_economics.md` — 2026 API pricing across 4 tiers, GPU rental (A100/H100/H200/B200), throughput estimates, GPU count by model size, cost-per-million-tokens calculations, utilization reality (interactive 20-40%, batch 60-80%), 6 hidden costs of self-hosted, 6 hidden costs of API, migration cost (3-6 months, 2-3 engineers), prompt caching as economics lever. Cites vLLM paper, DistServe (NSDI 2024), HELM benchmark, Artificial Analysis, Llama 3.1 paper. - `ai_team_org_evolution.md` — 5-stage role map (pre-seed → late-stage), 9-role definition table distinguishing AI engineer / ML engineer / research scientist / data scientist / AI safety / AI PM / Head of AI / CAIO. AI team vs data team contrast (8 dimensions). 7 specific anti-patterns. Hiring sequencing rule. Cites Huyen "Designing ML Systems" + "AI Engineering", State of AI Report, Karpathy's AI engineer archetype discussions. -- **cs-caio-advisor** agent (`./c-level-advisor/c-level-agents/agents/cs-caio-advisor.md`) — eval-demanding realist orchestrating the skill. Voice: "What does this AI need to be good at, and how would you measure it?" Treats every AI use case as a hiring decision; pushes back on AI hype; demands fallback behavior before scale. -- **`/cs:caio-review`** slash command (`./c-level-advisor/c-level-agents/skills/caio-review/SKILL.md`) — 6-question forcing interrogation: eval discipline, hallucination SLO, regulatory tier, model selection, cost trajectory, role-that-unblocks-this. +- **cs-caio-advisor** agent (`./c-level-agents/agents/cs-caio-advisor.md`) — eval-demanding realist orchestrating the skill. Voice: "What does this AI need to be good at, and how would you measure it?" Treats every AI use case as a hiring decision; pushes back on AI hype; demands fallback behavior before scale. +- **`/cs:caio-review`** slash command (`./c-level-agents/skills/caio-review/SKILL.md`) — 6-question forcing interrogation: eval discipline, hallucination SLO, regulatory tier, model selection, cost trajectory, role-that-unblocks-this. - **cs-caio-advisor voice spec** added to `persona-voices.md`. ### Why This Matters @@ -1254,8 +1254,8 @@ The `chief-ai-officer-advisor` skill surfaces strategic AI decisions but is **no - `data_product_strategy.md` — Decision: which architecture and what do we build? Stage-driven kill criteria per architecture + 6-layer build-vs-buy decision tree + sequencing pattern + anti-patterns. - `customer_data_as_asset.md` — Decision: what's our data worth and can we productize it? 5-component valuation framework + M&A multiplier with carve-out impact + 3 productization paths with prerequisites + 10-item M&A diligence prep checklist + quarterly contractual constraint audit pattern. - `data_team_org_evolution.md` — Decision: what role next, when to centralize vs embed? 5-stage map (seed → late-stage) with specific role definitions + centralize-vs-embed-vs-federated triggers + 6 anti-patterns ("hiring data scientist as first data hire" etc.). -- **cs-cdo-advisor** agent (`./c-level-advisor/c-level-agents/agents/cs-cdo-advisor.md`) — decision-driven realist orchestrating the skill. Voice: "What decision does this data drive?" Refuses to recommend tooling before naming the consumer. Treats AI training data as both contractual liability and strategic asset. -- **`/cs:cdo-review`** slash command (`./c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md`) — 6-question forcing interrogation pattern matching the /cs:cfo-review / /cs:gc-review etc. shape. +- **cs-cdo-advisor** agent (`./c-level-agents/agents/cs-cdo-advisor.md`) — decision-driven realist orchestrating the skill. Voice: "What decision does this data drive?" Refuses to recommend tooling before naming the consumer. Treats AI training data as both contractual liability and strategic asset. +- **`/cs:cdo-review`** slash command (`./c-level-agents/skills/cdo-review/SKILL.md`) — 6-question forcing interrogation pattern matching the /cs:cfo-review / /cs:gc-review etc. shape. - **cs-cdo-advisor voice spec** added to `persona-voices.md`. ### Why This Matters @@ -1304,7 +1304,7 @@ The `chief-data-officer-advisor` skill surfaces strategic decisions but is **not - **`references/contracts_playbook.md`** — 7 standard startup contracts (MSA, customer SaaS, NDA, DPA, employment, contractor, equity), top redlines per type, quick triage heuristics. - **`references/ip_and_regulatory.md`** — Full IP strategy (patents, copyright, trademark, trade secrets, invention assignment, OSS license compliance for permissive/weak-copyleft/strong-copyleft including AGPL) plus regulatory trigger matrix (HIPAA, PCI DSS, BSA/AML, FDA 510(k), MDR, GDPR, CCPA, COPPA, securities, ITAR, EU AI Act, telehealth, insurance) with SOC 2 → ISO 27001 → ISO 42001 sequencing and when-to-hire-a-GC criteria. - **`references/term_sheet_decoder.md`** — Full term sheet glossary, founder-friendly defaults cheat sheet, the three clauses that matter most (liquidation preference, option pool pre/post-money, anti-dilution), and negotiation strategy. -- **cs-general-counsel-advisor** agent (`./c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md`) — risk-paranoid persona orchestrating the skill via `/cs:gc-review`. Distinct voice: "Before we sign, three things need to be settled in writing." Hard rule: never gives definitive legal advice; always escalates to qualified outside counsel. +- **cs-general-counsel-advisor** agent (`./c-level-agents/agents/cs-general-counsel-advisor.md`) — risk-paranoid persona orchestrating the skill via `/cs:gc-review`. Distinct voice: "Before we sign, three things need to be settled in writing." Hard rule: never gives definitive legal advice; always escalates to qualified outside counsel. - **`/cs:gc-review`** updated to invoke the new tools and reference the skill (the command previously pointed at a planned skill with a CHANGELOG note). ### Why This Matters @@ -1328,7 +1328,7 @@ The `general-counsel-advisor` skill and `cs-general-counsel-advisor` agent are * ### Added — C-Level Advisory -- **c-level-agents** plugin (`./c-level-advisor/c-level-agents/`) — surfaces the existing 28 c-level skills through a founder-mode interface of cs-* persona agents and `/cs:*` slash commands. New marketplace entry registered separately (category: leadership). +- **c-level-agents** plugin (`./c-level-agents/`) — surfaces the existing 28 c-level skills through a founder-mode interface of cs-* persona agents and `/cs:*` slash commands. New marketplace entry registered separately (category: leadership). - **8 new cs-* persona agents** with distinct cognitive voices, completing agent coverage for every C-role: - `cs-cfo-advisor` (numerate skeptic) wraps cfo-advisor - `cs-cmo-advisor` (narrative-first) wraps cmo-advisor diff --git a/CLAUDE.md b/CLAUDE.md index cfbc716b..35248ef3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co This is a **comprehensive skills library** for Claude AI and Claude Code - reusable, production-ready skill packages that bundle domain expertise, best practices, analysis tools, and strategic frameworks. The repository provides modular skills that teams can download and use directly in their workflows. -**Current Scope:** 364 production-ready skills across 18 domains with 666 Python automation tools, 749 reference guides, 104 agents (cs-* + 7 personas), and 119 slash commands, distributed as 90 marketplace plugins. Headline counters are derived from the tree by `scripts/derive_counters.py` (run with `--check` to verify the docs still match). **v2.11.2 (current)** vendors **engineering/skillopt-sleep/** — started as a verbatim, byte-for-byte copy of `microsoft/SkillOpt`'s `skillopt_sleep` engine (stdlib-only, zero third-party deps) and its Claude Code plugin surface (`skills/`, `hooks/`, `commands/`, `scripts/`), then received 23 targeted patches after ten rounds of adversarial review (see `engineering/skillopt-sleep/README.md`'s numbered "Deviations from upstream" list, the authoritative source — re-apply all 23 on re-vendor). Gives a local agent a nightly "sleep cycle": read-only harvest of past Claude Code session transcripts → mine recurring tasks → replay offline on the user's own API budget → consolidate into `CLAUDE.md`/`SKILL.md` edits behind a held-out validation gate → stage for review; nothing live changes until an explicit `/skillopt-sleep adopt` (which backs up first). Default `mock` backend spends no API budget. The heavier `skillopt` *training* package (benchmark-driven, needs `numpy`/`openai`/`azure-*` + hand-labeled train/val/test data per task) was deliberately **not** vendored — it optimizes one narrow, scoreable task at a time, which doesn't fit this repo's broad domain-expertise skills or its no-ML-in-scripts/no-test-framework conventions; `skillopt_sleep` mines its "benchmark" from real usage instead, which does fit. Attribution preserved in `plugin.json` + `LICENSE` + `README.md` (MIT, © Microsoft Corporation / Yifan Yang), following the same verbatim-vendor pattern as `loop-library/`. **Unreleased (post-v2.11.2)** ships the **productivity coverage expansion** — public audit record `audit/productivity-2026-07/` (all 7 legacy skills scored, 24/24 scripts smoke-tested, coverage map vs the personal-productivity canon) + 3 gap-filling plugins, each with a cs-* agent, /cs:* commands, 3 stdlib scripts and 3 cited references: **weekly-review** (GTD loop; review-gate refuses COMPLETE while a mandatory GET CURRENT step is missing), **deep-work** (time-block planner refusing >4h deep demand, shallow-work budget auditor, focus-session logger), **meetings** (MEET/ASYNC/NOT-READY cost gate, outcome-required agenda builder, action-item extractor with ORPHAN/NO-DUE flags). **Unreleased (post-v2.11.1)** added **productivity/fable-goal** — converts a rambling description of a desired outcome into one polished, copy-paste `/goal` prompt for a fresh autonomous session (ported from `duncan-buildroom/freeskills`). **v2.11.1 (complete)** upgrades **product-team/** and **project-management/** into agent-harness domains: both prose routers rebuilt as `context: fork` orchestrators with deterministic goal routers (exit-code route/ask/refuse), a Jira MCP snapshot bridge (Kanban-Guide-2025 flow metrics + seeded Monte Carlo forecasts, verified end-to-end into velocity_analyzer), a delegation-governance loop gate (human owner / reviewer / machine-checkable acceptance / close refusal), a Torres continuous-discovery cadence tracker + Opportunity Solution Tree linter, cs-pm-orchestrator + cs-product-orchestrator agents, and /cs:pm|grill-pm|pm-loop + /cs:product|grill-product|product-loop commands — plus the public audit record `audit/pm-product-agentic-2026-07/` (AR-rubric scores for all 26 skills, research-backed improvement fields, executable verification criteria). **v2.9.0 (complete)** added the **research-ops/** top-level domain — enterprise Research Operations (orchestrator + clinical-research + research-finance + market-research + product-research), the managed counterpart to the academic research/ domain, with `context: fork` orchestration and a Matt Pocock "Forcing-question library" in every SKILL.md plus `/cs:grill-research-ops`. **v2.8.0 (complete)** added 2 new top-level domains — **business-operations/** (7 internal-ops skills: orchestrator + process-mapper + vendor-management + capacity-planner + internal-comms + knowledge-ops + procurement-optimizer) and **commercial/** (8 per-deal-economics skills: orchestrator + pricing-strategist + deal-desk + partnerships-architect + channel-economics + commercial-policy + rfp-responder + commercial-forecaster) — with orchestrator skills using `context: fork` for chaining, Matt Pocock docs-anchored "Forcing-question library" in every SKILL.md, plus `/cs:grill-bizops` and `/cs:grill-commercial`. **v2.8.2** adds a productivity-shaped `handoff` skill (sibling to engineering/handoff) inspired by Matt Pocock — first-run setup with configurable save location, redaction linter, SessionStart + SessionEnd hooks, fidelity self-check, `--refresh` flag. **v2.8.1** upgraded the engineering role-skills (senior-fullstack / senior-frontend / senior-backend) with karpathy-coder + Matt Pocock decision engines + per-role forcing questions. v2.7.3 ports `alirezarezvani/aeo-box` — AEO (Answer Engine Optimization) skill into marketing-skill/ + security-guidance PreToolUse hook into engineering/. v2.7.0 added 13 Path-B skills across 3 top-level domains (productivity, marketing, research). v2.6.0 added 4 Matt Pocock-derived productivity skills. +**Current Scope:** 371 production-ready skills across 19 domains with 675 Python automation tools, 812 reference guides, 105 agents (cs-* + 7 personas), and 120 slash commands, distributed as 93 marketplace plugins. Headline counters are derived from the tree by `scripts/derive_counters.py` (run with `--check` to verify the docs still match). **v2.11.2 (current)** vendors **engineering/skillopt-sleep/** — started as a verbatim, byte-for-byte copy of `microsoft/SkillOpt`'s `skillopt_sleep` engine (stdlib-only, zero third-party deps) and its Claude Code plugin surface (`skills/`, `hooks/`, `commands/`, `scripts/`), then received 23 targeted patches after ten rounds of adversarial review (see `engineering/skillopt-sleep/README.md`'s numbered "Deviations from upstream" list, the authoritative source — re-apply all 23 on re-vendor). Gives a local agent a nightly "sleep cycle": read-only harvest of past Claude Code session transcripts → mine recurring tasks → replay offline on the user's own API budget → consolidate into `CLAUDE.md`/`SKILL.md` edits behind a held-out validation gate → stage for review; nothing live changes until an explicit `/skillopt-sleep adopt` (which backs up first). Default `mock` backend spends no API budget. The heavier `skillopt` *training* package (benchmark-driven, needs `numpy`/`openai`/`azure-*` + hand-labeled train/val/test data per task) was deliberately **not** vendored — it optimizes one narrow, scoreable task at a time, which doesn't fit this repo's broad domain-expertise skills or its no-ML-in-scripts/no-test-framework conventions; `skillopt_sleep` mines its "benchmark" from real usage instead, which does fit. Attribution preserved in `.claude-plugin/authoring-notes.json` + `LICENSE` + `README.md` (MIT, © Microsoft Corporation / Yifan Yang), following the same verbatim-vendor pattern as `loop-library/`. **Unreleased (post-v2.11.2)** ships the **productivity coverage expansion** — public audit record `audit/productivity-2026-07/` (all 7 legacy skills scored, 24/24 scripts smoke-tested, coverage map vs the personal-productivity canon) + 3 gap-filling plugins, each with a cs-* agent, /cs:* commands, 3 stdlib scripts and 3 cited references: **weekly-review** (GTD loop; review-gate refuses COMPLETE while a mandatory GET CURRENT step is missing), **deep-work** (time-block planner refusing >4h deep demand, shallow-work budget auditor, focus-session logger), **meetings** (MEET/ASYNC/NOT-READY cost gate, outcome-required agenda builder, action-item extractor with ORPHAN/NO-DUE flags). **Unreleased (post-v2.11.1)** added **productivity/fable-goal** — converts a rambling description of a desired outcome into one polished, copy-paste `/goal` prompt for a fresh autonomous session (ported from `duncan-buildroom/freeskills`). **v2.11.1 (complete)** upgrades **product-team/** and **project-management/** into agent-harness domains: both prose routers rebuilt as `context: fork` orchestrators with deterministic goal routers (exit-code route/ask/refuse), a Jira MCP snapshot bridge (Kanban-Guide-2025 flow metrics + seeded Monte Carlo forecasts, verified end-to-end into velocity_analyzer), a delegation-governance loop gate (human owner / reviewer / machine-checkable acceptance / close refusal), a Torres continuous-discovery cadence tracker + Opportunity Solution Tree linter, cs-pm-orchestrator + cs-product-orchestrator agents, and /cs:pm|grill-pm|pm-loop + /cs:product|grill-product|product-loop commands — plus the public audit record `audit/pm-product-agentic-2026-07/` (AR-rubric scores for all 26 skills, research-backed improvement fields, executable verification criteria). **v2.9.0 (complete)** added the **research-ops/** top-level domain — enterprise Research Operations (orchestrator + clinical-research + research-finance + market-research + product-research), the managed counterpart to the academic research/ domain, with `context: fork` orchestration and a Matt Pocock "Forcing-question library" in every SKILL.md plus `/cs:grill-research-ops`. **v2.8.0 (complete)** added 2 new top-level domains — **business-operations/** (7 internal-ops skills: orchestrator + process-mapper + vendor-management + capacity-planner + internal-comms + knowledge-ops + procurement-optimizer) and **commercial/** (8 per-deal-economics skills: orchestrator + pricing-strategist + deal-desk + partnerships-architect + channel-economics + commercial-policy + rfp-responder + commercial-forecaster) — with orchestrator skills using `context: fork` for chaining, Matt Pocock docs-anchored "Forcing-question library" in every SKILL.md, plus `/cs:grill-bizops` and `/cs:grill-commercial`. **v2.8.2** adds a productivity-shaped `handoff` skill (sibling to engineering/handoff) inspired by Matt Pocock — first-run setup with configurable save location, redaction linter, SessionStart + SessionEnd hooks, fidelity self-check, `--refresh` flag. **v2.8.1** upgraded the engineering role-skills (senior-fullstack / senior-frontend / senior-backend) with karpathy-coder + Matt Pocock decision engines + per-role forcing questions. v2.7.3 ports `alirezarezvani/aeo-box` — AEO (Answer Engine Optimization) skill into marketing-skill/ + security-guidance PreToolUse hook into engineering/. v2.7.0 added 13 Path-B skills across 3 top-level domains (productivity, marketing, research). v2.6.0 added 4 Matt Pocock-derived productivity skills. **Key Distinction**: This is NOT a traditional application. It's a library of skill packages meant to be extracted and deployed by users into their own Claude workflows. @@ -166,7 +166,7 @@ See [standards/git/git-workflow-standards.md](standards/git/git-workflow-standar Vendors `engineering/skillopt-sleep/` — a byte-for-byte start from [microsoft/SkillOpt](https://github.com/microsoft/SkillOpt)'s `skillopt_sleep` engine (32 files, stdlib-only, zero third-party deps) and its Claude Code plugin surface (`skills/`, `hooks/`, `commands/`, `scripts/`), following the same verbatim-vendor pattern as `loop-library/`. Gives a local agent a nightly gated self-improvement cycle: read-only harvest of past Claude Code session transcripts → mine recurring tasks → replay offline on the user's own API budget → consolidate into `CLAUDE.md`/`SKILL.md` edits behind a held-out validation gate → stage for review; nothing live changes until an explicit `/skillopt-sleep adopt` (which backs up first). Default `mock` backend spends no API budget. - **Deliberately not vendored:** the heavier `skillopt` *training* package (benchmark-driven, needs `numpy`/`openai`/`azure-*` + hand-labeled train/val/test data per task) — it optimizes one narrow, scoreable task at a time, which doesn't fit this repo's broad domain-expertise skills or its no-ML-in-scripts/no-test-framework conventions; `skillopt_sleep` mines its "benchmark" from real usage instead, which does fit. -- **23 deviations from upstream (6 cosmetic, 17 safety/hardening)**, found across ten rounds of adversarial code review rather than assumed safe from the surface docs. The **numbered list in `engineering/skillopt-sleep/README.md`'s "Deviations from upstream" section is the single source of truth** — `plugin.json`'s `attribution.derivation_note` and this bullet are both summaries of it, kept in sync by hand; if any of the three ever disagree on the count again, README.md wins. Highlights: `redact_secrets()` now covers every artifact that goes live or persists — `proposed_SKILL.md`/`proposed_CLAUDE.md`, the cross-night task archive (`state.json`), `report.md`/`report.json` (previously only `diagnostics.json` was scrubbed, despite `report.md` being the file the SKILL.md's own workflow tells a human to read *first*), and — the gap that survived seven review rounds because every earlier fix was file-level — the CLI's own `cmd_run`/`cmd_harvest` console/`--json`/`--output` output, which read the same unredacted in-memory `Report`/`TaskRecord` objects and (via `scheduler.py`'s cron redirect) could leak straight into `cron.log`; the generated crontab line is fully `shlex.quote()`-d including the `extra` flags param, and `cron.log` itself is now `chmod 600` (previously uncovered by the state/staging chmod pass); `scheduler.py`'s per-project cron-line marker match is now anchored on end-of-line rather than a bare substring test, closing a real bug where scheduling/unscheduling one project could silently drop a sibling project's job whose path happened to be a prefix of it; the previously-dead `max_tokens_per_night` config key now sizes `dream_rollouts` down via the engine's own `plan_depth()` heuristic; a hardcoded internal Azure OpenAI backend (5 internal-looking endpoint hostnames + a Managed Identity client ID) was removed rather than carried forward; tool-shim names reachable via `--tasks-file` are now validated against a safe-identifier allowlist before use as a filename or shell text; `commands/skillopt-sleep.md` now tells the agent to confirm with the user before `schedule` (which installs a real crontab entry immediately, unlike every other action); every directory/file `state.py`/`staging.py` create is `chmod 0700`/`0600` rather than left at the world-readable process umask default. +- **23 deviations from upstream (6 cosmetic, 17 safety/hardening)**, found across ten rounds of adversarial code review rather than assumed safe from the surface docs. The **numbered list in `engineering/skillopt-sleep/README.md`'s "Deviations from upstream" section is the single source of truth** — the plugin's `authoring-notes.json` `attribution.derivation_note` and this bullet are both summaries of it, kept in sync by hand; if any of the three ever disagree on the count again, README.md wins. Highlights: `redact_secrets()` now covers every artifact that goes live or persists — `proposed_SKILL.md`/`proposed_CLAUDE.md`, the cross-night task archive (`state.json`), `report.md`/`report.json` (previously only `diagnostics.json` was scrubbed, despite `report.md` being the file the SKILL.md's own workflow tells a human to read *first*), and — the gap that survived seven review rounds because every earlier fix was file-level — the CLI's own `cmd_run`/`cmd_harvest` console/`--json`/`--output` output, which read the same unredacted in-memory `Report`/`TaskRecord` objects and (via `scheduler.py`'s cron redirect) could leak straight into `cron.log`; the generated crontab line is fully `shlex.quote()`-d including the `extra` flags param, and `cron.log` itself is now `chmod 600` (previously uncovered by the state/staging chmod pass); `scheduler.py`'s per-project cron-line marker match is now anchored on end-of-line rather than a bare substring test, closing a real bug where scheduling/unscheduling one project could silently drop a sibling project's job whose path happened to be a prefix of it; the previously-dead `max_tokens_per_night` config key now sizes `dream_rollouts` down via the engine's own `plan_depth()` heuristic; a hardcoded internal Azure OpenAI backend (5 internal-looking endpoint hostnames + a Managed Identity client ID) was removed rather than carried forward; tool-shim names reachable via `--tasks-file` are now validated against a safe-identifier allowlist before use as a filename or shell text; `commands/skillopt-sleep.md` now tells the agent to confirm with the user before `schedule` (which installs a real crontab entry immediately, unlike every other action); every directory/file `state.py`/`staging.py` create is `chmod 0700`/`0600` rather than left at the world-readable process umask default. - One documented, opt-in exception to CLAUDE.md's "no LLM calls in scripts" anti-pattern (see that section) — `backend.py`'s `claude`/`codex` backends shell out to those CLIs only when a non-`mock` backend is explicitly selected. - Registered as its own installable marketplace plugin; **counters:** skills 358 → 359; tools 603 → 635; refs 732 (unchanged); commands 110 → 111; plugins 84 → 85 (derived via `scripts/derive_counters.py --check`). @@ -177,13 +177,66 @@ Vendors `engineering/skillopt-sleep/` — a byte-for-byte start from [microsoft/ Derived from [virgiliojr94/book-to-skill](https://github.com/virgiliojr94/book-to-skill) (MIT). Compiles a book, documentation folder, or spec collection (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW) into an agent skill: a resident master `SKILL.md` (core frameworks + chapter index + topic index, capped at 4k tokens) plus on-demand `chapters/chNN-*.md`, `glossary.md`, `patterns.md`, and a decision `cheatsheet.md`. The agent reads the core, then one chapter — never the whole source again. - **Vendored close to verbatim:** the extraction library (`scripts/book_to_skill/` — config, exceptions, sanitize, dependencies, utils + 7 per-format parsers) keeps upstream's format chains, chapter detection across Latin/Roman/Chinese/Thai/Korean heading styles, invisible-Unicode (Trojan Source) sanitization and DOCX entity-expansion guard. -- **25 numbered deviations from upstream** — the list in `engineering/book-to-skill/README.md` is authoritative; `plugin.json`'s `attribution.derivation_note` summarizes it. Highlights: (5) `--install-missing` now defaults to `report` — it prints the pip command and uses the stdlib fallback instead of upstream's TTY prompt that runs `pip install` into the caller's environment; (6) a **rights gate** — `skill_plugin_emitter.py --distribution shareable` refuses without `--rights` from `public-domain|open-license|internal-docs|author-permission`, with `fair-use` deliberately excluded (a defence, not a licence); (10) the two upstream validators merged into one four-family gate, adding **budget** and **index** families — dead chapter links, unindexed chapter files and dangling topic refs are the failure that silently breaks navigation while the skill still looks complete, and upstream had no check for it; (11) folded YAML scalars now parse, so a wrapped description no longer under-reports its length past the 1024-char cap; (12) `discovery_tax.py` → `token_budget_estimator.py` with the optional `tiktoken` path dropped, a post-flight budget audit added, and an explicit **worth-converting verdict** that says "just read it" when the source is under ~3× the compiled skill. +- **25 numbered deviations from upstream** — the list in `engineering/book-to-skill/README.md` is authoritative; the plugin's `authoring-notes.json` `attribution.derivation_note` summarizes it. Highlights: (5) `--install-missing` now defaults to `report` — it prints the pip command and uses the stdlib fallback instead of upstream's TTY prompt that runs `pip install` into the caller's environment; (6) a **rights gate** — `skill_plugin_emitter.py --distribution shareable` refuses without `--rights` from `public-domain|open-license|internal-docs|author-permission`, with `fair-use` deliberately excluded (a defence, not a licence); (10) the two upstream validators merged into one four-family gate, adding **budget** and **index** families — dead chapter links, unindexed chapter files and dangling topic refs are the failure that silently breaks navigation while the skill still looks complete, and upstream had no check for it; (11) folded YAML scalars now parse, so a wrapped description no longer under-reports its length past the 1024-char cap; (12) `discovery_tax.py` → `token_budget_estimator.py` with the optional `tiktoken` path dropped, a post-flight budget audit added, and an explicit **worth-converting verdict** that says "just read it" when the source is under ~3× the compiled skill. - **Repo-native addition with no upstream counterpart — Step 11 / `/cs:book-to-plugin`:** upstream stops at a bare folder in `~/.claude/skills/`, which this library cannot route to. `skill_plugin_emitter.py` wraps a compiled skill as a full plugin package (manifest + `cs-` agent + `/cs:` command + README) and prints the marketplace entry; it never edits `marketplace.json` itself, and refuses to wrap a skill carrying validation errors. - **Cross-linked into `engineering/write-a-skill`** ("author first, compile second" — that skill authors from expertise in your head, this one compiles from a document on disk). - 4 stdlib-only tools (all `--help` / `--sample` / `--output json`), 5 references citing 7–8 sources each, 3 assets, `cs-book-to-skill` agent, 2 commands. **Counters:** skills 362 → 363; tools 644 → 663; refs 741 → 746; agents 102 → 103; commands 116 → 118; plugins 88 → 89 (derived via `scripts/derive_counters.py --check`). --- +**Unreleased (post-v2.11.2) — engineering/memory-engineering (engineer the forgetting, not the remembering):** + +New `engineering/memory-engineering/` plugin. Fills a real gap: the repo had no +skill for designing, pricing, or auditing an **agent memory system** (nearest +neighbours `llm-wiki`, `skillopt-sleep`, `agent-harness` all bound something +else — a vault, a loop, a task plan). Framing synthesized from *"How to be a +Memory Engineer, from the perspective of Stanford, Microsoft, Anthropic and +Nvidia"* by [@N01ennn](https://x.com/N01ennn/status/2083971749079581120), with +every quantitative claim re-cited to the primary source. + +- **4 stdlib scripts, one per lens.** `memory_cost_profiler.py` (construction vs + query split, **cost per correct answer**, amortization, co-location warning → + WRITE-PATH-DOMINANT / UNDER-AMORTIZED / NEEDS-SCHEDULING-FIX); + `memory_architecture_picker.py` (scores the paper's four paradigm families, + disqualifies on hard constraints, **names the cost the choice makes you pay**, + and exits 2 refusing to pick when the top two are within 0.06 — printing the + tie-breaking question instead); `memory_density_auditor.py` (classifies every + record **FACT / SKILL / LOG / PROSE**, near-duplicates via word-shingle + Jaccard, staleness + volatile-wording flags, knowledge density per 1k tokens; + runs on a real `--dir` **or** `--jsonl`); `forgetting_policy_linter.py` — **the + gate**: 8 checks with **F1** (explicit forgetting rule) and **F4** + (contradictions surfaced, never auto-merged) blocking at exit 4. +- **Evidence discipline — two of the source article's paraphrases are corrected + in the references rather than propagated.** (1) The 47× energy figure is the + *spread across ten evaluated systems* (BM25 at 4,145 J/correct answer vs + A-Mem/MIRIX at 115–197 kJ, a "28–47× premium"), **not** "two systems with + identical accuracy." (2) The 97% first-pass-error reduction is **Rakuten's + named vendor-published customer testimonial** (Yusuke Kaji, at 27% lower cost + / 34% lower latency), not a controlled study or a general property of the + approach. Every reference carries per-claim confidence levels, per the + `andreessen` precedent. +- **Two classifier defects found and fixed during the build**, both of which + would have produced garbage on any real repo: markdown headings *inside* + fenced code blocks were splitting records (fixed by masking fences before + heading detection — dropped 258 phantom records to 107 on a real directory), + and short fragments trivially matched at 1.00 Jaccard (fixed with a + 20-word floor for duplicate candidacy, eliminating 41 false-positive + "duplicates"). A third fix added the **PROSE** class: an earlier version + labeled every signal-less block LOG, firing LOG_HEAVY at 74% on a prose + documentation folder. +- 4 references citing 7 sources each (arXiv:2606.06448 Stanford characterization; + MSR PlugMem; arXiv:2604.09852 MEMENTO + OpenMementos; Anthropic managed-agents + memory), 3 assets (seven-question forcing worksheet, combined example spec + consumed by all three spec-taking scripts, fillable F1–F8 policy template), + `cs-memory-engineer` agent, `/cs:memory-engineering` + `/cs:forgetting-audit`. +- **SKILL.md is a full 6/6 PASS** on the write-a-skill checklist (binding for + post-v2.6.0 skills). **Counters** (this branch merged `dev` after + `book-to-skill` landed, so these deltas sit on top of it): skills 363 → 364; + tools 663 → 667; refs 746 → 750; agents 103 → 104; commands 118 → 120; + plugins 89 → 90 (verified via `scripts/derive_counters.py --check`). + +--- + **Unreleased (post-v2.11.1) — productivity/fable-goal (ramble → autonomous /goal prompt):** Improved port of `duncan-buildroom/freeskills` `fable-goal` (informal "free to use and modify" grant — quoted, not relicensed; see the `attribution` block). Converts a rambling description of a desired outcome into one polished, copy-paste /goal prompt for a fresh autonomous session — the prompt is the deliverable, never the build. Adds over upstream: wrong-tool check, observable-done principle, six-slot extraction (deliverable/quantity/stakes/tools/quality/destination), per-medium verification defaults, six-point pre-delivery self-check, anti-pattern list + failure-mode catalog reference, second worked example in a non-web medium. Ships `goal_prompt_self_check.py` (stdlib runner for the mechanically checkable self-check subset — word count 150–350, goal line, autonomy directive, verification/freedom/destination language; exit 0/1, `--sample`, `--output json`), `/cs:fable-goal` command. Intentionally no `agents/`/`assets/` (single reasoning pass; see plugin README design notes). SKILL.md is a full PASS on the write-a-skill 6-item checklist. Counters: skills 357 → 358 (this PR also trues up pre-existing engineering-row drift 355 → 357); tools 602 → 603; refs 731 → 732; commands 109 → 110; plugins 83 → 84. @@ -207,7 +260,7 @@ Extends the v2.11.0 agent-harness layer to the two people-process domains. Publi **v2.11.0 highlights — agent-harness skill + AR audit of both engineering folders:** -New `engineering/agent-harness/` skill — the thin unifying layer that lets an agent or subagent pick up a goal for any of the repo's 18 domains, decompose it into verifiable tasks, execute them with the domain's own tools, verify each with machine-run checks, retry within caps, escalate to a human on exhausted budgets, and refuse to close until every task is verified or explicitly waived. +New `engineering/agent-harness/` skill — the thin unifying layer that lets an agent or subagent pick up a goal for any of the repo's 18 (now 19) domains, decompose it into verifiable tasks, execute them with the domain's own tools, verify each with machine-run checks, retry within caps, escalate to a human on exhausted budgets, and refuse to close until every task is verified or explicitly waived. - **3 stdlib tools:** `harness_manifest_builder.py` (scans a domain folder → `manifest.v1` JSON: skills, tools, exact `--help`/`--sample` checks, static agentic signals), `goal_compiler.py` (goal + manifest → `plan.v1` task plan via deterministic keyword scoring; refuses vague goals exit 3 with forcing questions, no-match exit 4 with nearest candidates), `loop_controller.py` (JSON-backed `init/next/record/verify/close/status` state machine — runs verification checks itself via subprocess to prevent verification theater, caps attempts + iterations with escalation, refuses close while any task is unverified; atomic state writes via `os.replace`). - **18 committed per-domain manifests** under `assets/harnesses/` (the whole repo, machine-readable), a JSON schema, `harness-runner` agent, `/cs:harness ` command, and 3 references citing the 2024–2026 harness canon (Anthropic long-running-agents harness, verifier's law, SWE-agent, Ralph loop, Cognition serialize-writers, plus the repo's own tc-tracker / autoresearch locked-evaluator / loop-library stop-state primitives — reuse, not reinvention). @@ -373,7 +426,7 @@ Designed and shipped under the `/goal` directive to expand BizOps + Commercial s Ported `alirezarezvani/aeo-box` after a full component audit. Distilled the valuable parts into our conventions; skipped repo-specific infra (generic agents, GH workflows, TS scripts). - **`marketing-skill/skills/aeo/`** (new, 8 files, ~3,200 LOC) — Answer Engine Optimization skill, a discipline distinct from SEO. 3 stdlib Python tools: `aeo_audit.py` (E-E-A-T + structure scoring, 0-100 composite, 8 industries with calibrated thresholds where YMYL industries hit 85+, SaaS/b2b/media 70, ecommerce 65), `aeo_optimizer.py` (conservative/balanced/aggressive rewrites + schema.org JSON-LD injection), `citation_tracker.py` (local-first citation ledger at `~/.aeo-data/citations.json` with verdict EARLY/EMERGING/STRONG). 3 references each citing 8 sources: E-E-A-T canon, per-LLM citation patterns (Perplexity / ChatGPT / Claude / Gemini / Mistral with 73% cross-LLM correlation analysis), AEO vs. SEO strategic choice. New `cs-aeo` agent + `/cs:aeo` slash command. New 8th pod ("AEO") added to marketing-skill. -- **`engineering/security-guidance/`** (new, 5 files) — PreToolUse security reminder hook ported from David Dworken @ Anthropic (MIT). Preserves 9 upstream patterns verbatim (eval, pickle, dangerouslySetInnerHTML, innerHTML, document.write, new Function, child_process.exec, os.system, GH Actions workflow injection) + adds 3 new patterns (subprocess shell=True, SQL f-string injection, yaml.unsafe_load). Session-state caching prevents nagging (warn once per file+rule combo), 30-day auto-cleanup, disable via `ENABLE_SECURITY_REMINDER=0`. `attribution` block in plugin.json credits upstream. Reference doc `pretooluse_hook_canon.md` cites 8 sources on hook design discipline. +- **`engineering/security-guidance/`** (new, 5 files) — PreToolUse security reminder hook ported from David Dworken @ Anthropic (MIT). Preserves 9 upstream patterns verbatim (eval, pickle, dangerouslySetInnerHTML, innerHTML, document.write, new Function, child_process.exec, os.system, GH Actions workflow injection) + adds 3 new patterns (subprocess shell=True, SQL f-string injection, yaml.unsafe_load). Session-state caching prevents nagging (warn once per file+rule combo), 30-day auto-cleanup, disable via `ENABLE_SECURITY_REMINDER=0`. `attribution` block in `.claude-plugin/authoring-notes.json` credits upstream. Reference doc `pretooluse_hook_canon.md` cites 8 sources on hook design discipline. - **`megaprompts/14-aeo-agentic-megaprompt.md`** — 1,579-line multi-agent AEO application spec preserved verbatim. Keeps Path-B option open for future "build the full agentic AEO app" work. - **Marketplace + Codex registry:** 55 → 57 plugins; 303 → 305 indexed skills; `marketing-skill/.claude-plugin/plugin.json` description updated from 7 → 8 pods. - **Verification:** all 4 new Python tools pass `--help` and `--sample`; security hook smoke-tested (exits 2 on detection, 0 on cached/clean); all 3 cross-platform syncs (.codex / .gemini / .hermes) re-ran clean. @@ -458,7 +511,7 @@ This release ships the complete v2 megaprompt collection (`megaprompts/01-13`) a **Version:** v2.5.0 **v2.5.0 Highlights — c-level-agents: Founder-Mode Executive Team:** -- **c-level-agents** plugin (new, `./c-level-advisor/c-level-agents/`) — 8 cs-* persona agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, Chief of Staff) with moderate voice differentiation, plus 17 /cs:* slash commands surfaced as sub-skills. +- **c-level-agents** plugin (new, `./c-level-agents/`) — 8 cs-* persona agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, Chief of Staff) with moderate voice differentiation, plus 17 /cs:* slash commands surfaced as sub-skills. - **Forcing-question office hours (8):** `/cs:office-hours` (YC-style 6-Q intake), and per-role `/cs:cfo-review`, `/cs:cmo-review`, `/cs:cpo-review`, `/cs:cro-review`, `/cs:cto-review`, `/cs:ciso-review`, `/cs:gc-review` (General Counsel — a lane gstack lacks entirely). - **Strategic sprint pipeline (5):** `/cs:brief` → `/cs:boardroom` (6-phase deliberation with Phase 2 isolation + devil's-advocate pass) → `/cs:decide` (two-layer memory + preserved dissent) → `/cs:execute` (90-day plan) → `/cs:post-mortem` (scored against pre-committed criteria). - **Meta + safety (4):** `/cs:founder-mode` (auto-router), `/cs:onboard` (12-Q founder interview), `/cs:cross-eval` (multi-model consensus with graceful Claude-only fallback), `/cs:freeze` (cooldown lock on irreversible decisions). @@ -537,11 +590,11 @@ This repository publishes skills to **ClawHub** (clawhub.com) as the distributio 2. **Never rename repo folders or local skill names** to match ClawHub slugs. The repo is the source of truth. 3. **No paid/commercial service dependencies.** Skills must not require paid third-party API keys or commercial services unless provided by the project itself. Free-tier APIs and BYOK (bring-your-own-key) patterns are acceptable. 4. **Rate limit: 5 new skills per hour** on ClawHub. Batch publishes must respect this. Use the drip timer (`clawhub-drip.timer`) for bulk operations. -5. **plugin.json schema** — Required fields: `name`, `description`, `version`, `author`, `homepage`, `repository`, `license`, `skills`. Two **approved extension fields** are permitted in the repo (stripped at ClawHub-publish time, if/when a stripping pipeline lands): +5. **plugin.json schema** — Required fields: `name`, `description`, `version`, `author`, `homepage`, `repository`, `license`, `skills`. **No extension fields of any kind** — Claude Code's manifest validator rejects the entire `plugin.json` on any unrecognized key, which made 37+ plugins uninstallable (issue #954). Authoring metadata lives in a sibling file the validator never reads: `.claude-plugin/authoring-notes.json`, holding at most two keys: - `source` (object) — provenance metadata for skills built via Path-B megaprompt conversion. Recommended shape: `{spec: "megaprompts/NN-name.md", build_pattern: "...", distinct_from: "..."}`. Used by all 13 v2 megaprompt-derived skills (productivity/, marketing/, research/). - - `attribution` (object) — credit metadata for skills derived from external MIT-licensed work. Used by `engineering/caveman`, `engineering/grill-me`, `engineering/grill-with-docs` (Matt Pocock derivatives). + - `attribution` (object) — credit metadata for skills derived from external MIT-licensed work. Used by `engineering/caveman`, `engineering/grill-me`, `engineering/grill-with-docs` (Matt Pocock derivatives), `engineering/skillopt-sleep`, `engineering/book-to-skill`, and others. Upstream credit must also remain in the plugin's `README.md`/`LICENSE` — a sidecar JSON file is not a license notice. - No other extras. The `skills` value depends on the plugin layout. Per the live Claude Code plugin spec ([plugins-reference](https://code.claude.com/docs/en/plugins-reference)), **all paths must be relative to the plugin root and start with `./`**. CC 2.1.144+ returns `Validation errors: skills: Invalid input` on a bare string without the prefix. + `scripts/check_plugin_json.py` hard-fails any `plugin.json` still carrying `source`/`attribution` (pointing to the sidecar file) and sanity-checks `authoring-notes.json` where present. Note that `source` **is** a valid key in `marketplace.json`'s `plugins[]` entries — the two schemas are not interchangeable, which is how the key originally leaked into `plugin.json`. The `skills` value depends on the plugin layout. Per the live Claude Code plugin spec ([plugins-reference](https://code.claude.com/docs/en/plugins-reference)), **all paths must be relative to the plugin root and start with `./`**. CC 2.1.144+ returns `Validation errors: skills: Invalid input` on a bare string without the prefix. **Canonical forms (CC 2.1.144+):** - Single-skill plugin (SKILL.md at root): `"skills": ["./"]` (array form required). @@ -591,4 +644,4 @@ When I correct you, or you catch yourself making a mistake: before continuing ad **Last Updated:** July 17, 2026 **Version:** v2.11.2 (+ unreleased productivity coverage expansion, fable-goal, book-to-skill) -**Status:** 364 skills deployed across 18 domains, 90 marketplace plugins, docs site live (counters derived via `scripts/derive_counters.py`) +**Status:** 371 skills deployed across 19 domains, 93 marketplace plugins, docs site live (counters derived via `scripts/derive_counters.py`) diff --git a/INSTALLATION.md b/INSTALLATION.md index 2e994bc5..e1e11c04 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -15,6 +15,7 @@ Complete installation guide for all 205+ production-ready skills across multiple - [Multi-Agent Setup](#multi-agent-setup) - [Manual Installation](#manual-installation) - [Verification & Testing](#verification--testing) +- [Windows Notes](#windows-notes) - [Troubleshooting](#troubleshooting) - [Uninstallation](#uninstallation) @@ -516,6 +517,39 @@ python3 ~/.claude/skills/content-production/scripts/seo_optimizer.py test-articl --- +## Windows Notes + +Two Windows-specific caveats to know before cloning or running skills (issues #968 and #969): + +### Symlinks: mirror trees need `core.symlinks=true` + +The cross-platform mirror trees (`.gemini/`, `.codex/`, `.vibe/`, `.hermes/`) are built from **relative symlinks** into the real skill directories. Git for Windows defaults to `core.symlinks=false`, so a default clone checks those 1,300+ links out as **1-line text files containing only the target path** — copying a skill folder from a mirror tree then silently gives you dead pointer files instead of skills. + +Before cloning on Windows: + +1. Enable **Developer Mode** (Settings → System → For developers), or run Git from an elevated prompt. +2. Clone with symlinks enabled: + + ```powershell + git clone -c core.symlinks=true https://github.com/alirezarezvani/claude-skills.git + ``` + +If you already cloned without it, either re-clone as above, or **copy skills from the real domain directories** (e.g. `engineering-team/`, `marketing-skill/`) instead of the mirror trees — the Claude Code plugin/marketplace path always uses the real directories and is unaffected. Quick sanity check after any copy: a real `SKILL.md` is more than one line long. + +### Console encoding: run Python tools with UTF-8 + +Windows consoles often default to a legacy codepage (e.g. cp1252) that cannot encode the box-drawing and comparison characters (`╔`, `≥`, `✅`) some skill tools print, which crashes the script at print time with `UnicodeEncodeError`. The most-affected tools now re-encode their own output, but as a blanket fix for every script in this library, enable Python's UTF-8 mode: + +```powershell +# Per session +$env:PYTHONUTF8 = "1" + +# Or permanently +setx PYTHONUTF8 1 +``` + +--- + ## Troubleshooting ### Universal Installer Issues diff --git a/README.md b/README.md index 1631277b..6a3bd3d7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Claude Code Skills & Plugins — Agent Skills for Every Coding Tool -**364 production-ready Claude Code skills, plugins, and agent skills for 13 AI coding tools.** +**371 production-ready Claude Code skills, plugins, and agent skills for 13 AI coding tools.** The most comprehensive open-source library of Claude Code skills and agent plugins — also works with OpenAI Codex, Gemini CLI, Cursor, and 9 more coding agents. Reusable expertise packages covering engineering, DevOps, marketing (incl. AEO — Answer Engine Optimization for LLM citation), security (PreToolUse hooks), compliance, C-level advisory (incl. founder-mode CFO/CMO/CRO/CPO/COO/CHRO/CISO/GC/CDO/CAIO/CCO/VPE personas + 21 /cs:* slash commands), productivity (capture/email/reflect/weekly-review/deep-work/meetings), an academic research stack (litreview/grants/dossier/patent/syllabus/pulse/notebooklm/deep-research + hybrid router), and enterprise Research Operations (clinical-research/research-finance/market-research/product-research, v2.9.0). @@ -10,10 +10,10 @@ The most comprehensive open-source library of Claude Code skills and agent plugi [^vibe]: Mistral Vibe is also **BYO-sync tier**: the repo ships a pre-generated `.vibe/skills/claude-skills/` tree, run `./scripts/vibe-install.sh` once locally to install into `~/.vibe/skills/`. Same agentskills.io SKILL.md standard — no format conversion. Docs: . [![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](https://opensource.org/licenses/MIT) -[![Skills](https://img.shields.io/badge/Skills-364-brightgreen?style=for-the-badge)](#skills-overview) -[![Agents](https://img.shields.io/badge/Agents-104-blue?style=for-the-badge)](#agents) +[![Skills](https://img.shields.io/badge/Skills-371-brightgreen?style=for-the-badge)](#skills-overview) +[![Agents](https://img.shields.io/badge/Agents-105-blue?style=for-the-badge)](#agents) [![Personas](https://img.shields.io/badge/Personas-7-purple?style=for-the-badge)](#personas) -[![Commands](https://img.shields.io/badge/Commands-119-orange?style=for-the-badge)](#commands) +[![Commands](https://img.shields.io/badge/Commands-121-orange?style=for-the-badge)](#commands) [![Stars](https://img.shields.io/github/stars/alirezarezvani/claude-skills?style=for-the-badge)](https://github.com/alirezarezvani/claude-skills/stargazers) [![SkillCheck Validated](https://img.shields.io/badge/SkillCheck-Validated-4c1?style=for-the-badge)](https://getskillcheck.com) @@ -26,10 +26,10 @@ The most comprehensive open-source library of Claude Code skills and agent plugi Claude Code skills (also called agent skills or coding agent plugins) are modular instruction packages that give AI coding agents domain expertise they don't have out of the box. Each skill includes: - **SKILL.md** — structured instructions, workflows, and decision frameworks -- **Python tools** — 666 CLI scripts (all stdlib-only, zero pip installs) -- **Reference docs** — 749 templates, checklists, and domain-specific knowledge files +- **Python tools** — 675 CLI scripts (all stdlib-only, zero pip installs) +- **Reference docs** — 812 templates, checklists, and domain-specific knowledge files -**One repo, thirteen platforms.** Works natively as Claude Code plugins, Codex agent skills, Gemini CLI skills, Hermes Agent skills, Mistral Vibe skills, and converts to more tools via `scripts/convert.sh`. All 666 Python tools run anywhere Python runs. +**One repo, thirteen platforms.** Works natively as Claude Code plugins, Codex agent skills, Gemini CLI skills, Hermes Agent skills, Mistral Vibe skills, and converts to more tools via `scripts/convert.sh`. All 675 Python tools run anywhere Python runs. ### Skills vs Agents vs Personas @@ -46,6 +46,8 @@ All three work together. See [Orchestration](#orchestration) for how to combine ## Quick Install +> **Windows users:** clone with `git clone -c core.symlinks=true` (Developer Mode enabled) — otherwise the `.gemini/`/`.codex/`/`.vibe/`/`.hermes/` mirror trees check out as 1-line pointer text files instead of skills — and set `PYTHONUTF8=1` so tools that print Unicode don't crash on legacy-codepage consoles. Details: [INSTALLATION.md → Windows Notes](INSTALLATION.md#windows-notes). + ### Gemini CLI (New) ```bash @@ -150,26 +152,27 @@ Run `./scripts/convert.sh --tool all` to generate tool-specific outputs locally. ## Skills Overview -**364 skills across 18 domains:** +**370 skills across 19 domains:** | Domain | Skills | Highlights | Details | |--------|--------|------------|---------| -| **🔧 Engineering — Core** | 52 | Architecture, frontend, backend, fullstack, QA, DevOps, SecOps, AI/ML, data, Playwright Pro (test gen, flaky fix, migrations), self-improving agent (auto-memory curation), security suite, a11y audit, **named-persona-adversarial-review** (review via named engineering philosophies) | [engineering-team/](engineering-team/) | -| **⚡ Engineering — POWERFUL** | 86 | Agent designer, RAG architect, database designer, CI/CD builder, security auditor, MCP builder, AgentHub, Helm charts, Terraform, self-eval, llm-wiki, tc-tracker, autoresearch-agent, **reliability portfolio** (feature-flags-architect, kubernetes-operator, chaos-engineering, slo-architect), ship-gate, security-guidance PreToolUse hook, **Matt Pocock skills** (write-a-skill, caveman, grill-me, handoff, grill-with-docs), **zero-hallucination-coder** (Discuss→Map→Decompose→Execute→Verify), **agent-harness** (goal→plan→execute→verify→close loops over any domain), **skillopt-sleep** (nightly gated self-evolution from real Claude Code sessions, vendored from microsoft/SkillOpt), **book-to-skill** (compile a book, docs folder, or spec collection into a knowledge-base skill, then package it as a plugin), **human-gate** (batched human review as a structured artifact + a gate that refuses to close on open blockers) | [engineering/](engineering/) | +| **🔧 Engineering — Core** | 53 | Architecture, frontend, backend, fullstack, QA, DevOps, SecOps, AI/ML, data, Playwright Pro (test gen, flaky fix, migrations), self-improving agent (auto-memory curation), security suite, a11y audit, **named-persona-adversarial-review** (review via named engineering philosophies), **embedded-iot-mentor** (MCU/board selection, firmware-reuse-first, breadboard-MVP discipline) | [engineering-team/](engineering-team/) | +| **⚡ Engineering — POWERFUL** | 88 | Agent designer, RAG architect, database designer, CI/CD builder, security auditor, MCP builder, AgentHub, Helm charts, Terraform, self-eval, llm-wiki, tc-tracker, autoresearch-agent, **reliability portfolio** (feature-flags-architect, kubernetes-operator, chaos-engineering, slo-architect), ship-gate, security-guidance PreToolUse hook, **Matt Pocock skills** (write-a-skill, caveman, grill-me, handoff, grill-with-docs), **zero-hallucination-coder** (Discuss→Map→Decompose→Execute→Verify), **agent-harness** (goal→plan→execute→verify→close loops over any domain), **memory-engineering** (price the memory write path, pick which cost to pay, audit FACT/SKILL/LOG density, gate on a forgetting policy), **skillopt-sleep** (nightly gated self-evolution from real Claude Code sessions, vendored from microsoft/SkillOpt), **book-to-skill** (compile a book, docs folder, or spec collection into a knowledge-base skill, then package it as a plugin), **boost-asio-pro** (async C++ networking — version-gated coroutine/callback styles, strand discipline), **human-gate** (batched human review as a structured artifact + a gate that refuses to close on open blockers) | [engineering/](engineering/) | | **🎯 Product** | 17 | Product manager, agile PO, strategist, UX researcher, UI design, landing pages, SaaS scaffolder, analytics, experiment designer, discovery, roadmap communicator, code-to-prd, apple-hig-expert | [product-team/](product-team/) | -| **📣 Marketing** | 48 | 8 pods: Content, SEO + AEO (`aeo` — E-E-A-T audit, citation tracking across 5 LLMs) + local (`local-seo-manager` — GBP/NAP/Map-Pack), CRO, Channels, Growth, Intelligence, Sales + context foundation + orchestration router | [marketing-skill/](marketing-skill/) | -| **🚀 Productivity** | 11 | `capture` (brain-dump-to-action), `email` pair (inbox-setup + inbox-triage), `reflect` (journal), `handoff` (Matt Pocock-inspired), `andreessen` (market-first decision mode), `roast` (5-angle idea panel → GO/RESHAPE/KILL), `fable-goal` (ramble → autonomous /goal prompt), `weekly-review` (GTD loop with refusal gate), `deep-work` (time-blocking + shallow-work budget), `meetings` (cost gate + agenda + action items) | [productivity/](productivity/) | +| **📣 Marketing** | 49 | 8 pods: Content, SEO + AEO (`aeo` — E-E-A-T audit, citation tracking across 5 LLMs) + local (`local-seo-manager` — GBP/NAP/Map-Pack), CRO, Channels, Growth, Intelligence, Sales + `business-name-fit` (cross-cultural naming) + context foundation + orchestration router | [marketing-skill/](marketing-skill/) | +| **🚀 Productivity** | 12 | `capture` (brain-dump-to-action), `email` pair (inbox-setup + inbox-triage), `reflect` (journal), `handoff` (Matt Pocock-inspired), `andreessen` (market-first decision mode), `roast` (5-angle idea panel → GO/RESHAPE/KILL), `fable-goal` (ramble → autonomous /goal prompt), `weekly-review` (GTD loop with refusal gate), `deep-work` (time-blocking + shallow-work budget), `meetings` (cost gate + agenda + action items), `swedish-mentor` (CEFR-leveled Swedish learning paths) | [productivity/](productivity/) | | **🎨 Marketing (top-level)** | 1 | `landing` — single-file HTML landing-page generator (4 design styles, GSAP patterns, brand palette validator) | [marketing/](marketing/) | -| **🔬 Research (academic)** | 9 | `research` orchestrator (hybrid router + fallback) + 8 specialists: `pulse`, `litreview`, `grants` (NIH), `dossier`, `patent`, `syllabus`, `notebooklm`, `deep-research` (rigor-first meta-research) | [research/](research/) | +| **🔬 Research (academic)** | 10 | `research` orchestrator (hybrid router + fallback) + 8 specialists: `pulse`, `litreview`, `grants` (NIH), `dossier`, `patent`, `syllabus`, `notebooklm`, `deep-research` (rigor-first meta-research), `deepread` (evidence-first reading of supplied documents) | [research/](research/) | | **🧪 Research Operations** ✨v2.9.0 | 5 | Enterprise/cross-functional research: orchestrator + `clinical-research` (study design), `research-finance` (R&D program finance), `market-research` (sizing/survey/segmentation), `product-research` (user research) — each with onboarding + customization + opt-in autoresearch bridge | [research-ops/](research-ops/) | | **📋 Project Management** | 9 | Senior PM, scrum master, Jira, Confluence, Atlassian admin, templates + bundled Atlassian Remote MCP | [project-management/](project-management/) | | **🏥 Regulatory & QM** | 19 | ISO 13505, MDR 2017/745, FDA, ISO 27001, GDPR, SOC 2, CAPA, risk management, agent-decision-receipts (PQ-signed action receipts) | [ra-qm-team/](ra-qm-team/) | | **🛡️ Compliance OS** | 9 | Compliance operating system — controls, evidence, audit-readiness workflows | [compliance-os/](compliance-os/) | -| **💼 C-Level Advisory** | 68 | Full C-suite (CEO/CTO/CFO/CMO/CRO/CPO/COO/CHRO/CISO/GC/CDO/CAIO/CCO/VPE) + founder-mode agents + orchestration + board meetings + culture & collaboration | [c-level-advisor/](c-level-advisor/) | +| **💼 C-Level Advisory** | 46 | Full C-suite (CEO/CTO/CFO/CMO/CRO/CPO/COO/CHRO/CISO/GC/CDO/CAIO/CCO/VPE) + executive mentor + orchestration + board meetings + culture & collaboration | [c-level-advisor/](c-level-advisor/) | +| **🎩 C-Level Agents (founder mode)** | 22 | 13 cs-* persona agents + 21 /cs:* commands — office hours, boardroom, strategic sprint pipeline, cross-eval, freeze | [c-level-agents/](c-level-agents/) | | **📈 Business & Growth** | 5 | Customer success, sales engineer, revenue ops, contracts & proposals, BizDev toolkit | [business-growth/](business-growth/) | | **🏭 Business Operations** | 7 | Orchestrator + process-mapper, vendor-management, capacity-planner, internal-comms, knowledge-ops, procurement-optimizer | [business-operations/](business-operations/) | | **🤝 Commercial** | 8 | Orchestrator + pricing-strategist, deal-desk, partnerships-architect, channel-economics, commercial-policy, rfp-responder, commercial-forecaster | [commercial/](commercial/) | -| **💰 Finance** | 4 | Financial analyst (DCF, budgeting, forecasting), SaaS metrics coach, business investment advisor | [finance/](finance/) | +| **💰 Finance** | 5 | Financial analyst (DCF, budgeting, forecasting), SaaS metrics coach, business investment advisor, stock-analysis (sector-relative fundamentals, 26 sector playbooks, forensic + IPO modes) | [finance/](finance/) | | **🔄 Loop Library** | 1 | `loop-library` — discover, find, audit/repair, adapt, and design bounded AI-agent loops; reads the live catalog from signals.forwardfuture.ai at runtime (vendored verbatim from [Forward-Future/loop-library](https://github.com/Forward-Future/loop-library)) | [loop-library/](loop-library/) | | **📄 Markdown → HTML** | 5 | `markdown-html-orchestrator` (doctype router) + `design-system` (WCAG-AA brand tokens) + `md-document` (long-form) + `md-review` (2-col code review) + `md-slides` (single-file deck) — markdown-to-interactive-HTML converter | [markdown-html/](markdown-html/) | @@ -339,6 +342,7 @@ python3 product-team/landing-page-generator/scripts/landing_page_scaffolder.py c | [**Claude Code Tresor**](https://github.com/alirezarezvani/claude-code-tresor) | Productivity toolkit with 60+ prompt templates | | [**Product Manager Skills**](https://github.com/Digidai/product-manager-skills) | Senior PM agent with 6 knowledge domains, 12 templates, 30+ frameworks — discovery, strategy, delivery, SaaS metrics, career coaching, AI product craft | | [**toprank**](https://github.com/nowork-studio/toprank) | 9 SEO and Google Ads skills for Claude Code — connects Google Search Console, PageSpeed Insights, and Google Ads API; ships meta tag, schema markup, and keyword bid fixes to source or CMS. MIT, 107 stars | +| [**LinkedIn Skills**](https://github.com/sergebulaev/linkedin-skills) | 11 LinkedIn skills for Claude Code and Codex: post writer with 16 tested hook formulas, humanizer that scrubs AI tells, pre-publish audit, comment and reply drafting, hook extractor, content planner, profile optimizer, engager analytics, and thread monitoring. MIT | --- @@ -354,7 +358,7 @@ Yes. Skills work natively with 13 tools: Claude Code, OpenAI Codex, Gemini CLI, No. We follow semantic versioning and maintain backward compatibility within patch releases. Existing script arguments, plugin source paths, and SKILL.md structures are never changed in patch versions. See the [CHANGELOG](CHANGELOG.md) for details on each release. **Are the Python tools dependency-free?** -Yes. All 666 Python tools use the standard library only — zero pip installs required. Every skill's CLI entry point is verified to run with `--help` (most skills ship one script per tool; a few, like the vendored `engineering/skillopt-sleep` engine, ship a multi-module package behind a single `python -m` entry point). A few tools — `engineering/book-to-skill`'s document extractors — can *optionally* use third-party parsers for higher-fidelity output, but every format falls back to a standard-library parser and nothing is installed implicitly. +Yes. All 675 Python tools use the standard library only — zero pip installs required. Every skill's CLI entry point is verified to run with `--help` (most skills ship one script per tool; a few, like the vendored `engineering/skillopt-sleep` engine, ship a multi-module package behind a single `python -m` entry point). A few tools — `engineering/book-to-skill`'s document extractors — can *optionally* use third-party parsers for higher-fidelity output, but every format falls back to a standard-library parser and nothing is installed implicitly. **How do I create my own Claude Code skill?** Each skill is a folder with a `SKILL.md` (frontmatter + instructions), optional `scripts/`, `references/`, and `assets/`. See the [Skills & Agents Factory](https://github.com/alirezarezvani/claude-code-skills-agents-factory) for a step-by-step guide. diff --git a/SKILL-AUTHORING-STANDARD.md b/SKILL-AUTHORING-STANDARD.md index fb3fcce6..a1f2efa4 100644 --- a/SKILL-AUTHORING-STANDARD.md +++ b/SKILL-AUTHORING-STANDARD.md @@ -8,7 +8,7 @@ The DNA of every skill in this repository. Follow this standard when creating ne ```markdown --- -name: skill-name +name: skill-name # NEVER a bare Claude Code built-in command word (status, review, init, resume, config, help, ...) — it shadows the built-in for every installer (issue #885). Use a namespaced leaf like memory-status / pw-review; scripts/check_skill_names.py enforces this in CI. description: "When to use this skill. Include trigger keywords and phrases users might say. Mention related skills for disambiguation." license: MIT metadata: diff --git a/SKILL_PIPELINE.md b/SKILL_PIPELINE.md index c32e79e3..d50b2ac4 100644 --- a/SKILL_PIPELINE.md +++ b/SKILL_PIPELINE.md @@ -111,7 +111,7 @@ After skill is finalized: ```bash python -m scripts.run_loop \ --eval-set --skill-path \ - --model anthropic/claude-opus-4-6 --max-iterations 5 --verbose + --model anthropic/claude-opus-5 --max-iterations 5 --verbose ``` 4. Apply `best_description` to SKILL.md frontmatter diff --git a/agents/engineering/cs-backend-engineer.md b/agents/engineering/cs-backend-engineer.md index 5a6d6eff..7462cb1d 100644 --- a/agents/engineering/cs-backend-engineer.md +++ b/agents/engineering/cs-backend-engineer.md @@ -123,8 +123,8 @@ python ../../engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surge - [cs-frontend-engineer](cs-frontend-engineer.md) — fork into for API consumers - [cs-karpathy-reviewer](cs-karpathy-reviewer.md) — invoke before every commit - [cs-cto-advisor](../c-level/cs-cto-advisor.md) — escalate strategic build-vs-buy -- [cs-vpe-advisor](../../c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md) — escalate throughput / org / DORA -- [cs-ciso-advisor](../../c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — escalate regulated-data exposure +- [cs-vpe-advisor](../../c-level-agents/agents/cs-vpe-advisor.md) — escalate throughput / org / DORA +- [cs-ciso-advisor](../../c-level-agents/agents/cs-ciso-advisor.md) — escalate regulated-data exposure ## Invocation Contract diff --git a/agents/engineering/cs-fullstack-engineer.md b/agents/engineering/cs-fullstack-engineer.md index 69a49073..9aa08ef0 100644 --- a/agents/engineering/cs-fullstack-engineer.md +++ b/agents/engineering/cs-fullstack-engineer.md @@ -163,7 +163,7 @@ python ../../engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surge - [cs-karpathy-reviewer](cs-karpathy-reviewer.md) — invoke before every commit - [cs-senior-engineer](cs-senior-engineer.md) — cross-cutting engineering lead (use for non-stack questions like CI/CD, security review) - [cs-cto-advisor](../c-level/cs-cto-advisor.md) — escalate for strategic build-vs-buy or technical debt prioritization -- [cs-vpe-advisor](../../c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md) — escalate for org-design + throughput +- [cs-vpe-advisor](../../c-level-agents/agents/cs-vpe-advisor.md) — escalate for org-design + throughput ## Invocation Contract diff --git a/audit/newgen-2026-06/engineering-team.md b/audit/newgen-2026-06/engineering-team.md index c5f06969..d20b0c8c 100644 --- a/audit/newgen-2026-06/engineering-team.md +++ b/audit/newgen-2026-06/engineering-team.md @@ -40,9 +40,9 @@ Audited: 2026-06-10 · Skills: 51 · Agents: 5 · Commands: 0 · Plugins: 6 | google-workspace-cli/skills/google-workspace-cli | REWRITE | install coordinates almost certainly fabricated (`npm i -g @anthropic/gws`, `github.com/googleworkspace/cli`) | | snowflake-development/skills/snowflake-development | KEEP | — | | playwright-pro/skills/pw | KEEP | — | -| playwright-pro/skills/init | KEEP | — | +| playwright-pro/skills/pw-init | KEEP | — | | playwright-pro/skills/generate | KEEP | — | -| playwright-pro/skills/review | KEEP | — | +| playwright-pro/skills/pw-review | KEEP | — | | playwright-pro/skills/fix | KEEP | — | | playwright-pro/skills/migrate | KEEP | — | | playwright-pro/skills/coverage | KEEP | — | diff --git a/audit/pr-stream-2026-08/00-MASTER.md b/audit/pr-stream-2026-08/00-MASTER.md new file mode 100644 index 00000000..15b21a6a --- /dev/null +++ b/audit/pr-stream-2026-08/00-MASTER.md @@ -0,0 +1,196 @@ +# Master report — Open-PR stream audit (25 PRs) + +**Audited:** 2026-08-21 · **Branch:** `claude/pr-audit-planning-mhy82k` · +**Scope:** every open pull request against `dev` (25 PRs, #788 → #967), each read +diff-by-diff and judged against the repo's own acceptance bar (CLAUDE.md + +CONTRIBUTING/CONVENTIONS contract, plugin.json schema rules, stdlib-only script +discipline, counter governance, skill-package pattern). + +**Method:** five parallel deep-dive audits, one per PR group. Every material +claim was re-executed, not read: PR heads fetched locally +(`git fetch origin pull/N/head`), test-merged against `origin/dev` (`6972e65`), +gate scripts run (`derive_counters.py --check`, `check_plugin_json.py --all`, +`check_dual_publish.py`, skill validator + security auditor), scripts +smoke-tested (`--help`/`--sample`/`--example`), YAML parsed, external claims +verified against primary sources (AWS pricing blog, upstream GitHub repos, +issue #954's verbatim CLI error output). Baseline on `dev` is green: counters +pass, 90/90 manifests pass. + +Detail files: [fix-series-governance.md](fix-series-governance.md) (#936–#940) · +[fix-series-small.md](fix-series-small.md) (#966, #964, #932, #929, #895) · +[new-skills.md](new-skills.md) (#967, #944, #926, #965, #942, #943) · +[closures.md](closures.md) (#959, #913, #788, #955, #956, #957) · +[maintainer-drafts.md](maintainer-drafts.md) (#961, #948, #946). + +--- + +## 1. Verdict table (25 PRs) + +| PR | Title (short) | Author | Verdict | One-line rationale | +|---|---|---|---|---| +| #936 | repair 14 unloadable YAML frontmatter blocks + gate G10 | benrfairless | **MERGE** | All 14 repairs verified byte-identical text; gate reproduces 0 errors on dev+series | +| #937 | recalibrate skill-tester validator + advisory gate G7 | benrfairless | **MERGE** | Old required-frontmatter schema was fictional (verified); advisory flip is safe by construction | +| #938 | remove retired model IDs / stale pricing, flip G7 blocking | benrfairless | **MERGE** | Clears a defect the repo's own July audit logged; blocking flip proven safe on current dev (0 findings / 2,703 files) | +| #939 | agent `skills:` → `plugin:skill`, fix name collisions, resync mirrors | benrfairless | **MERGE-WITH-CHANGES** | Mechanically correct (109 refs, 0 unresolvable re-verified) but needs the preloading policy decision, a rebase + mirror resync, and the comma-separated `skills:` encoding confirmed | +| #940 | gate 3 drifted counter sites, rewrite ClawHub §5 | benrfairless | **MERGE-WITH-CHANGES** | Right design, stale payload (fails its own gate on today's dev with 12 mismatches) and its §5 rewrite collides head-on with #966 — see §3 | +| #966 | strip `source`/`attribution` from 39 plugin.json → sidecars | dylanpulver | **MERGE** | Fixes live install failure (issue #954 — 37/88 at filing, 39/90 as of this audit); every removed value preserved byte-equal in `authoring-notes.json`; policy amended in-PR | +| #964 | cap 4 marketplace descriptions at 1024 chars | automotua | **MERGE** | Exactly the 4 over-cap entries, meaning preserved; take the offered CI guard (commercial-skills sits at 1021/1024) | +| #932 | correct stale DynamoDB on-demand pricing | LeeroyHannigan | **MERGE** | Verified against the live AWS Nov-2024 50%-cut announcement; one line, exactly right | +| #929 | harden gws_recipe_runner subprocess + `--yes` gate | warnes | **MERGE** | `shell=True` removed, zero shell-metacharacter templates (all 48 scanned), refusal path executed and correct | +| #895 | add LinkedIn Skills to Related Projects | sergebulaev | **MERGE-WITH-CHANGES** | Real, active MIT repo (now 578★); matches toprank precedent; refresh the stale "10 skills / 303 stars" row first | +| #967 | boost-asio-pro (async C++ networking) | alexprivalov | **MERGE** | Best-written external skill in the stream; genuinely expert (strand semantics, version floors); security-clean | +| #944 | stock-analysis (sector-relative fundamentals) | AlenSarangSatheesh | **MERGE-WITH-CHANGES** | Highest-value contribution: 24.7k lines, 26 sector playbooks, 5 real stdlib engines all verified running; needs desc ≤1024, two section headings, one FP disposition | +| #965 | dsh-deepread (evidence-first reading) | xiehuan123 | **MERGE-WITH-CHANGES** | Solid disciplined content; rename off the personal `dsh-` prefix, add citations, register as plugin | +| #942 | embedded-iot-mentor | mh-mansouri | **MERGE-WITH-CHANGES** | Real practitioner judgment, genuine gap, auto-joins domain plugin; clear the 100-line validator floor via a references file | +| #943 | swedish-mentor | mh-mansouri | **MERGE-WITH-CHANGES** (borderline) | Thinnest of the batch; needs references + plugin.json to match productivity siblings or it lands undistributable | +| #926 | business-name-fit (cross-cultural naming) | mh-mansouri | **MERGE-WITH-CHANGES** | Genuinely expert, honest, correctly attributed port; one-word trigger fix + 2 more cited sources | +| #961 | agent-launcher domain plugin (draft) | maintainer | **FINISH-PLAN** | Construction done, integration not: rebase, re-derive counters, top up references, first CI run | +| #948 | human-gate plugin (draft) | maintainer | **FINISH-PLAN → merge** | Content complete after 7 bot-review rounds, CI green; only rebase + counter re-derive + sidecar move (see §3) remain | +| #946 | agent-memory L0–L3 spec (draft) | maintainer | **REWORK** (not superseded) | Advisory-vs-runtime distinction means memory-engineering does NOT supersede it — but §2 never mentions memory-engineering and must; settle the DESIGN-only-folder precedent | +| #959 | remon-awad persona | awadremon-ops | **CLOSE** | Self-named vanity persona; house personas are role archetypes; duplicates agent-harness by its own admission | +| #913 | Ontoly Software Graph skill | 0xsarwagya | **CLOSE** | Undisclosed promotion of author's own day-old 1-star tool; directs agents to execute an unvetted external CLI; duplicates 4 existing skills | +| #788 | collab-proof retrospective skill | dong7812 | **CLOSE (superseded)** | Already re-landed on dev byte-identical (`753adb4`) with an improved plugin.json; remaining hunk would delete youtube-full and revert counters | +| #955 | REAPER Gemini/Cursor prompts | sveinnhelgihalldorsson-ops | **CLOSE** | Off-mission per-tool prompt docs inside the machine-generated `.gemini/` sync tree | +| #956 | Ableton Gemini/Cursor prompts | sveinnhelgihalldorsson-ops | **CLOSE** | Same; ships an artifact its own sibling audit rates 6 WRONG / 8 RISKY | +| #957 | Ableton test reports | sveinnhelgihalldorsson-ops | **CLOSE** | Personal QA transcripts with local Windows paths; self-contradictory verdicts; depends on #956 | + +**Totals:** 8 MERGE · 8 MERGE-WITH-CHANGES · 6 CLOSE · 3 maintainer-draft plans. + +--- + +## 2. The three biggest findings + +1. **~43% of the marketplace is uninstallable in Claude Code today, and two open + PRs "fix" it in opposite directions.** Issue #954 documents the verbatim + failure (`Validation errors: : Unrecognized key: "source"`). #966 resolves it + by *removing* the extension keys from all 39 manifests (provenance preserved + byte-equal in `.claude-plugin/authoring-notes.json` sidecars — independently + verified, zero attribution loss) and making any extra key a hard CI FAIL. + #940's CLAUDE.md §5 rewrite goes the other way: it asserts extension fields + "need no special dispensation." Both cannot be policy. **Recommendation: + adopt #966's direction** — it is evidence-backed by a reproduced installer + error, ships the enforcement to keep the bug fixed, and updates CLAUDE.md in + the same change; #940 must drop/rework its §5 paragraphs at rebase time + (§3, decision D1). + +2. **The benrfairless series (#936–#940) is a stacked branch chain + (936 ⊂ 937 ⊂ 938 ⊂ 939 ⊂ 940) and its quality is real.** Every mechanical + claim survived independent re-execution (14/14 YAML repairs byte-identical, + G7 0-findings on dev+series, 109 agent-skill refs 0-unresolvable, dual-publish + 0-drifted). Merging any later PR lands all earlier ones — do not cherry-merge. + #936–#938 are mergeable today; #939 needs one policy decision (D2) and a + rebase; #940 must go last with regenerated numbers because its own gate + freezes the counters it writes. + +3. **The external new-skill pipeline works — when the contribution is real.** + Six of eight external skill PRs are keepers (one, #944, is arguably the + deepest single domain skill ever contributed to the repo), and the three + rejects are exactly the categories a curated library must refuse: vanity + personas (#959), undisclosed self-promotion steering agents to run an + unvetted third-party binary (#913), and personal working-notes dumps in + generated directories (#955–#957). None of the 25 PRs has ever had a CI run — + fork workflows are gated on maintainer approval, so every green claim above + is from this audit's local reproduction. **Approve workflow runs before + merging anything.** + +--- + +## 3. Decisions the maintainer must make (blocking, in order) + +| # | Decision | Affects | Recommendation | +|---|---|---|---| +| **D1** | Extension-key policy: strip-to-sidecar + strict validator (#966) vs "extras tolerated" (#940 §5) | #966, #940, #948, #961, and every future plugin | **Adopt #966.** It fixes a reproduced install failure and enforces the fix. #940 reworks §5 at rebase; #948/#961 move their `source`/`attribution` blocks into `authoring-notes.json` sidecars before undrafting (their current manifests would hard-fail #966's validator) | +| **D2** | Agent `skills:` field: keep `plugin:skill` preloading (~2.5k tokens per agent spawn) or delete the field (author offers both variants) | #939 | Keep preloading — the fixed form makes 81 agents' skill refs actually resolve; token cost is bounded and visible. Record the decision on the PR | +| **D3** | DESIGN-only folders under domain roots: sanctioned pattern or not | #946 | Not sanctioned: move the spec to `audit/agent-memory-design-2026-08/` (public-record pattern, counter-free) or park in gitignored `documentation/` until the §9.2 extraction trial justifies building | +| **D4** | Release-version framing: do #966+#964 ship as a patch (v2.11.3 "installability") and the new-skill batch as v2.12.0? | changelog, marketplace `metadata.version` | Yes — see merge order below; #940 (rebased) is the natural counter-true-up vehicle for the release that closes the batch | + +--- + +## 4. Global merge order + +Zero git-level conflicts exist between the independent PRs (verified pairwise); +the constraints are the stack (#936→#940), the D1 policy fork, and the +marketplace-tail collision between #948 and #961. + +**Phase 0 — hygiene (now).** Approve GitHub Actions runs on all fork PRs so the +gates execute on GitHub runners, not only in this audit's local reproduction. + +**Phase 1 — governance floor.** Merge **#936 → #937 → #938** (stacked; all +test-merge clean on today's dev; all verified). This lands gates G10 + G7 that +protect everything after. + +**Phase 2 — installability (D1).** Merge **#966**, then **#964**. Post-merge, +run `claude plugin install roast@claude-code-skills` as the real-world check. +Follow-up (small PR): update the 3 living docs that still tell authors to put +attribution in plugin.json (paths in [fix-series-small.md](fix-series-small.md)). + +**Phase 3 — surgical fixes.** Merge **#932**, **#929**; refresh #895's row +(11 skills / current stars) then merge **#895**. + +**Phase 4 — new skills** (each after its listed required changes; per-PR change +lists in [new-skills.md](new-skills.md)): **#967 → #944 → #926 → #965 → #942 → +#943**. Ordered by readiness; #943 last and only if the author packages it. +Counters intentionally drift during this phase — do **not** hand-patch per merge. + +**Phase 5 — the big rename + counter close-out.** After D2: rebase **#939** +(re-run all four mirror syncs; convert dev's new `cs-book-to-skill.md`; confirm +or re-encode the 9 comma-separated `skills:` values as YAML lists), merge. +Then rebase **#940** as the **final write**: regenerate every number from +`derive_counters.py`, add `agents`/`commands` patterns to `CLAIM_PATTERNS`, +rework §5 per D1, merge. `derive_counters.py --check` exits 0 → the release is +consistent by construction. + +**Phase 6 — maintainer drafts.** **#948** first (rebase, counters, sidecar move +per D1, undraft, merge — content is done). Then **#961** (rebase after #948 to +take the marketplace tail, re-derive counters, top up references, first CI run). +**#946** per D3. + +**Closures (any time, independent):** #959, #913, #788, #955, #956, #957 — +ready-to-post close comments in [closures.md](closures.md). All six are polite +and specific; #788's credits the contributor whose work already shipped. + +--- + +## 5. Improvement streams (post-merge, non-blocking) + +Recurring weaknesses this stream exposed, each worth one follow-up PR: + +1. **CI never runs on fork PRs.** Every gate the repo has was moot for all 25 + PRs. Add a `pull_request_target`-safe path or a documented + approve-runs-on-first-triage routine so external PRs get at least G1/G3/G10. +2. **Description-length regression guard.** #964 fixes 4 over-cap descriptions + but `commercial-skills` sits at 1021/1024. Fold a ≤1024 check into + `check_plugin_json.py` (the author offered it). +3. **Counter-drift-by-design for external PRs.** CONTRIBUTING correctly tells + contributors not to touch counters; the repo should have a standing + "true-up" routine (Phase 5's rebased #940 is this stream's instance). +4. **Reference-source floor is unevenly applied.** Four of the six accepted + skills need citation top-ups; the write-a-skill checklist runner should be in + the fork-PR CI path (see 1) so this is flagged at submission. +5. **Security-auditor false positives.** #944's one CRITICAL is a verified FP on + finance vocabulary (`holdco-assetmgr.md:58`); the auditor needs an + allowlist-with-reason mechanism like `check_model_freshness_allowlist.txt`. +6. **Doc drift after #966.** Three living docs still teach the old attribution + location (exact lines in [fix-series-small.md](fix-series-small.md)). +7. **Related-Projects rows rot by design** (hardcoded star counts). Either drop + star counts from the table or accept staleness as policy. + +--- + +## 6. Verification — how this audit's claims are re-checked + +Every per-PR section in the detail files ends with an executable verification +block. The stream-level invariants, runnable at any phase boundary: + +```bash +python3 scripts/derive_counters.py --check # counters consistent (must pass at Phase 5 close) +python3 scripts/check_plugin_json.py --all # all manifests valid under the current policy +python3 scripts/check_dual_publish.py # 12 pairs, 0 drifted +python3 scripts/check_frontmatter.py --all # post-#936: 0 errors +python3 scripts/check_model_freshness.py --all # post-#938: 0 findings, exit 0 +python3 scripts/smoke_scripts.py # all skill scripts --help clean +``` + +Real-world close-out after Phase 2: `claude plugin marketplace add +alirezarezvani/claude-skills && claude plugin install roast@claude-code-skills` +(the exact command that fails today per issue #954). diff --git a/audit/pr-stream-2026-08/closures.md b/audit/pr-stream-2026-08/closures.md new file mode 100644 index 00000000..9543d20a --- /dev/null +++ b/audit/pr-stream-2026-08/closures.md @@ -0,0 +1,176 @@ +# PR audit detail — recommended closures (#959, #913, #788, #955, #956, #957) + +**Audited:** 2026-08-21 — PR states below (CI, mergeability, commit counts) are a snapshot from that date; re-run each verification block before acting on a verdict. + +Back to [00-MASTER.md](00-MASTER.md). Six PRs should be closed, each for a +different, specific reason — none for "low effort." Draft close comments are +included; all are polite, name the concrete gap, and (where the contributor +could realistically resubmit) point at the path back in. + +--- + +## #959 — remon-awad persona (awadremon-ops) — **CLOSE** + +**What it is.** One file: `agents/personas/remon-awad.md` (+147). A +"cross-domain copilot for Remon" routing goals to existing agents, with fallback +to `engineering/agent-harness`'s `/cs:harness`. + +**Why close.** +- **Person-named persona is not house style**: the 7 existing personas are role + archetypes (content-strategist, devops-engineer, startup-cto, …). This one is + named after the contributor and scoped to one individual ("Cross-domain + copilot for Remon"). +- **Duplicates agent-harness by its own admission**: the file itself says to + fall back to "the repo's own generic router … against the real per-domain + manifest," and concedes its own cached routing table will rot. +- **Not registered** (personas README table, counters untouched); brand-new + `-ops` account, single-commit drive-by shape. +- Credit where due: all 23 referenced agent/asset paths were verified real — + zero hallucinations. The diligence is good; the artifact is a personal + dotfile, not a library asset. + +**Draft close comment.** +> Thanks for the care here — every one of the 23 referenced paths checks out, +> which is rare. Closing anyway for two structural reasons: (1) personas in +> `agents/personas/` are role archetypes, not person-scoped configs — a persona +> named for one individual belongs in your own `~/.claude/agents/`; (2) the +> functional core duplicates `engineering/agent-harness`'s manifest-driven +> `/cs:harness` router, which the file itself names as the fallback — a +> hand-cached dispatch table in front of it is exactly the drift the manifests +> exist to prevent. If you want to contribute in this lane, extending the +> agent-harness manifests (or proposing a *role*-named dispatcher with a clear +> delta over `/cs:harness`) would be welcome. + +**Verification.** +```bash +git fetch origin pull/959/head:pr-959 +git show pr-959:agents/personas/remon-awad.md | head -8 # self-named frontmatter +ls agents/personas/ # role archetypes only +``` + +--- + +## #913 — Ontoly Software Graph skill (0xsarwagya) — **CLOSE** + +**What it is.** 2 files, +128: a SKILL.md instructing agents to run +**`ontoly build .`** and prefer "Ontoly CLI or MCP capabilities" over reading +source, plus a 13-line, zero-citation checklist reference. + +**Why close (in order of severity).** +1. **Supply-chain risk**: directs agents to install and execute an unvetted + third-party CLI against user repositories. `ontoly` resolves to + **the PR author's own repo**, created **the day before the PR** (2026-07-13 + vs 2026-07-14), 1 star / 1 fork — authorship undisclosed in the PR body. + Its only third-party trace is the identical skill text seeded into another + curated skill repo (cross-repo promotion pattern). +2. **Hard external dependency**: `grep -ri ontoly` outside the PR → zero hits; + the skill is inert without the vendor tool. Violates the self-containment + spirit of the no-paid-dependency rule even if technically "open-source." +3. **Full lane overlap**: its own Cross-References name the incumbents — + codebase-onboarding, monorepo-navigator, dependency-auditor, + mcp-server-builder. Strip the branding and nothing new remains. +4. 13-line reference, 0 citations vs the ≥5-source bar; keyword-stuffed trigger + designed to catch broad queries ("architecture review") and route them to + the vendor tool. + +**Draft close comment.** +> Closing. Two blockers: (1) the skill's core instruction is to install and run +> the external `ontoly` CLI — which is your own project, created the day before +> this PR, and that authorship isn't disclosed here. This repo can't endorse +> executing an unvetted third-party binary against user codebases, and +> undisclosed self-promotion isn't something we can merge. (2) Coverage-wise, +> the skill's own Cross-References list the four existing skills that already +> own this lane. If you want to resubmit: disclose authorship, make it +> tool-agnostic ("graph-backed codebase evidence" covering the established +> field, with no auto-run of any vendor CLI without explicit user consent), +> cite ≥5 independent sources, and show the tool's maturity first. + +**Verification.** +```bash +git fetch origin pull/913/head:pr-913 +git show pr-913:engineering/skills/ontoly-software-graph/SKILL.md | grep "ontoly build" +grep -ri "ontoly" --include="*.md" . | grep -v pr-913 # zero in-repo provider +``` + +--- + +## #788 — collab-proof (dong7812) — **CLOSE (superseded — not rejected)** + +**What it is.** The oldest open PR (June 1): `engineering/collab-proof/` plugin, +8 files, +699/−41. Full review history: blocking review addressed June 3; owner +asked for a rebase June 15; contributor never rebased (9+ weeks idle). + +**Why close.** The content **already shipped**: dev commit `753adb4` +"feat(engineering): add collab-proof skill (clean re-land of #788)" + +`7303501` (trailing newline + attribution block). Diffed PR head vs dev: +`SKILL.md` is **byte-identical**; the only delta is plugin.json, where **dev's +version is strictly better**. What remains in the PR is actively harmful: its +stale `.claude-plugin/marketplace.json` hunk was written against v2.9.0 and +would **delete the `youtube-full` plugin entry** and revert marketplace +counters/version. There is nothing left to land; do not request a rebase. + +**Draft close comment.** +> Closing as landed, not rejected: your skill was merged to dev in `753adb4` +> (a clean re-land of this PR) with your authorship preserved in the plugin +> manifest (`"author": {"name": "dong7812"}`), plus a small manifest polish in +> `7303501`. This PR's remaining delta is only a stale marketplace.json hunk +> that would now regress newer entries, so there's nothing further to merge +> here. Thanks for the contribution and for working through the June review — +> `engineering/collab-proof/` is live because of it. + +**Verification.** +```bash +git log --oneline origin/dev -- engineering/collab-proof/ # 753adb4 + 7303501 +git fetch origin pull/788/head:pr-788 +diff <(git show pr-788:engineering/collab-proof/skills/collab-proof/SKILL.md) engineering/collab-proof/skills/collab-proof/SKILL.md # empty +git show pr-788:.claude-plugin/marketplace.json | grep -c youtube-full # 0 → destructive hunk +``` + +--- + +## #955 / #956 / #957 — Gemini/Cursor DAW prompt docs (sveinnhelgihalldorsson-ops) — **CLOSE as a set** + +**What they are.** A coupled trio (opened the same second): #955 REAPER prompts +(4 files, +378), #956 Ableton prompts (4 files, +831), #957 QA reports *about +#956's file* (5 files, +585). All land hand-authored Gemini system prompts and +**Cursor personal skills** ("copy to `~/.cursor/skills/...`") under +`.gemini/MD research/`. + +**Why close.** +1. **Off-mission**: this is a Claude skills library; multi-platform support is + delivered by `scripts/sync-*-skills.py` from canonical SKILL.md packages — + never hand-authored per-tool prompt docs. No house pattern fits. +2. **Wrong location**: `.gemini/` on dev contains only machine-generated + symlinks + `skills-index.json` (verified). Hand content there pollutes a + sync-managed tree. +3. **Personal working-notes leakage**: #957's reports embed the contributor's + local Windows paths (`C:\Users\RoG\...`); its three reports contradict each + other ("GO, 96/100" vs "not ready to ship unchanged"); #956 ships an + artifact its own sibling audit rates 6 WRONG / 8 RISKY (including an + invented `Live.Application.get_document()` API), with the claimed fixes in + no PR. +4. Not skill packages: no SKILL.md-per-convention, no plugin, no counters; + spaced filenames (`MD research/`) against kebab-case. + +Credit: the underlying REAPER/Ableton research is competent (the RPP-chunk and +reapy corrections are real). It just isn't a contribution *to this library*. + +**Draft close comment (post on #955, reference on #956/#957).** +> Closing all three together. The research quality is real — the RPP-chunk and +> reapy corrections are the kind of accuracy work we like — but these are +> Gemini/Cursor prompt documents in `.gemini/`, which is a machine-generated +> sync directory here (built by `scripts/sync-gemini-skills.py` from canonical +> SKILL.md packages; hand-added files there get orphaned by the next sync). +> The repo also can't take personal working files (the test reports embed +> `C:\Users\...` paths and internal MCP server names). If you'd like to +> contribute DAW automation properly, the path is a real skill package — +> `SKILL.md` + stdlib scripts (an RPP parser would be a great deterministic +> tool) + cited references — per `engineering/write-a-skill`. Happy to review +> that. + +**Verification.** +```bash +for n in 955 956 957; do git fetch origin pull/$n/head:pr-$n; git diff --stat origin/dev...pr-$n | tail -1; done +git ls-tree origin/dev .gemini/ # sync-output only +git grep -l 'C:\\\\Users' pr-957 -- '.gemini/' # personal-path leakage +``` diff --git a/audit/pr-stream-2026-08/fix-series-governance.md b/audit/pr-stream-2026-08/fix-series-governance.md new file mode 100644 index 00000000..dd75fa03 --- /dev/null +++ b/audit/pr-stream-2026-08/fix-series-governance.md @@ -0,0 +1,232 @@ +# PR audit detail — the benrfairless governance series (#936–#940) + +**Audited:** 2026-08-21 — PR states below (CI, mergeability, commit counts) are a snapshot from that date; re-run each verification block before acting on a verdict. + +Back to [00-MASTER.md](00-MASTER.md). All five: base `dev` ✓, conventional +commits ✓, zero reviews/comments, **zero CI runs** (fork PRs; workflows never +approved). **Stacked series on one base** — verified via +`git merge-base --is-ancestor`: 936 ⊂ 937 ⊂ 938 ⊂ 939 ⊂ 940. Merging a later PR +lands all earlier commits; out-of-order merging is impossible. + +Context drift under the series: since base `2800f833`, dev merged #941 +(book-to-skill) and #947 (memory-engineering) plus a codex-symlink sync — the +cause of #939/#940's `dirty` state and #940's stale counter payload. + +--- + +## #936 — repair 14 unloadable YAML frontmatter blocks + gate G10 — **MERGE** + +**What it does.** 16 files, +271/−12. Fixes 12 files whose unquoted +`description:` containing `": "` makes `yaml.safe_load` fail ("mapping values +are not allowed here") and 2 agents with no frontmatter at all +(`c-level-advisor/executive-mentor/agents/devils-advocate.md`, +`engineering/autoresearch-agent/agents/experiment-runner.md`). Adds +`scripts/check_frontmatter.py` (242 lines) as blocking gate G10 in +`ci-quality-gate.yml`. + +**Evidence.** All 14 files re-tested at base (12 parse-fail, 2 missing) and at +head (14 parse, non-empty description). "Byte-identical text" verified +programmatically for all 11 pure-quoting fixes. Gate output reproduced exactly: +`Scanned 593 files; 0 errors, 17 warnings`, exit 0 — and re-run against +**dev + series** (601 files): still 0 errors. Test-merges clean into current dev. + +**Risk noted, accepted.** `check_frontmatter.py` imports PyYAML (not stdlib); +mitigated by graceful exit-2 on ImportError and CI installing `yamllint` +(vendors PyYAML). The stdlib-only rule binds *skill* scripts; `scripts/` build +tooling already assumes CI deps. + +**Plan.** Merge first, unchanged. **Improvement stream:** none needed. + +**Verification.** +```bash +git fetch origin pull/936/head:pr936 && git checkout pr936 +python3 scripts/check_frontmatter.py --all # 593 files, 0 errors, 17 warnings, exit 0 +python3 scripts/check_frontmatter.py --all --strict # exit 1 (warnings escalate) +python3 scripts/check_paths.py --all && python3 scripts/check_plugin_json.py --all +# regression probe: break one quote in compliance-os/agents/cs-aims-iso42001.md → G10 exit 1 with line/col +``` + +--- + +## #937 — recalibrate skill-tester validator + advisory gate G7 — **MERGE** + +**What it does.** Incremental: 5 files, +339/−47. Replaces the fictional +required-frontmatter list (`Name/Tier/Category/Dependencies/Author/Version`) +with the real schema (`name`, `description`); required-sections list becomes a +scored recommendation (≥2 of 12 headings); hand-maintained stdlib set replaced +by `sys.stdlib_module_names` + `__future__`. Rewrites the sample fixture to +carry real frontmatter. Adds `scripts/check_model_freshness.py` + allowlist as +**advisory** G7 (`continue-on-error: true`) flagging retired model IDs. + +**Evidence.** Base validator on `c-level-advisor/skills/cfo-advisor` → 11 bogus +errors; PR validator → 0 errors, exactly the claimed 86.4→95.5 shift. G7 exits 1 +on the pr937 tree (advisory, tolerated). One immaterial nit: PR body says "34 +references"; script reports 33. + +**Interaction.** `skill-quality-review.yml` calls this validator — expect score +shifts there (the point of the PR). #938 modifies the G7 script it creates. + +**Plan.** Merge second, unchanged. **Improvement stream:** none. + +**Verification.** +```bash +git checkout pr937 +python3 engineering/skills/skill-tester/scripts/skill_validator.py c-level-advisor/skills/cfo-advisor # 0 errors +python3 scripts/check_model_freshness.py --all; echo $? # exit 1 advisory, 33 findings / 13 executable +python3 scripts/check_frontmatter.py --all && python3 scripts/smoke_scripts.py +``` + +--- + +## #938 — remove retired model IDs and stale pricing, flip G7 blocking — **MERGE** + +**What it does.** Incremental: 19 files, +111/−94. Deletes dead 2024 cost +benchmarks from agent-designer's `agent_evaluator.py` (verified: no remaining +reader); makes senior-ml-engineer model-agnostic (price tables → tier-ratio +guidance; `calculate_cost()`/`count_tokens()` parameterized); pins +genuinely-needed IDs to current ones (`claude-opus-5`, `Claude Sonnet 5` in both +dual-publish CAIO copies); fixes a never-runnable CLI example in +`TEAM_STRUCTURE_GUIDE.md:344` (verified against the target script's real +argparse surface); flips G7 blocking and hardens it (`o-mini`-before-`o` +alternation-order bug, self-file exclusion, 3 reasoned allowlist entries). + +**Evidence.** G7 on pr938: `2653 files; 0 retired-identifier references`, +exit 0 — and on **dev + pr938** (2,703 files, incl. post-base merges): still 0. +The blocking flip cannot redden CI. `check_dual_publish.py`: 12 pairs, 0 +drifted. Clears the "senior-ml-engineer stale 2024 pricing" defect logged +STILL-OPEN in `audit/engineering-agentic-2026-07/`. + +**Nit (optional).** `AnthropicProvider(model="claude-opus-5")` keeps a +hardcoded default the same diff removed for OpenAI; self-policing via G7. + +**Plan.** Merge third, unchanged. **Improvement stream:** make the Anthropic +model a required param for symmetry (one-liner, any future PR). + +**Verification.** +```bash +git checkout pr938 +python3 scripts/check_model_freshness.py --all; echo $? # exit 0, 0 findings +python3 engineering/skills/agent-designer/agent_evaluator.py --help +python3 scripts/check_dual_publish.py # 12 pairs, 0 drifted +python3 engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py --help +``` + +--- + +## #939 — resolve `skills:` preloading + namespace collisions — **MERGE-WITH-CHANGES** + +**What it does.** Incremental: ~558 files, +2,859/−353, 3 commits. +(a) Rewrites every agent `skills:` value to `plugin:skill` form +(e.g. `skills: c-level-skills:cfo-advisor`); drops two phantom entries; removes +`context: fork` from 11 agents (skill-only field); renames the colliding +`handoff` plugins → `handoff-engineering`/`handoff-productivity`. +(b) Renames colliding bare-verb skills: agenthub `init/run/status` → +`hub-init/hub-run/hub-status`; autoresearch `run/status` → `ar-run/ar-status`; +playwright-pro `init` → `pw-init`, skill `playwright-pro` → `pw`. +(c) Regenerates all four mirrors (`.codex`/`.gemini`/`.hermes`/`.vibe`, 468 +files), pruning dead symlinks. + +**Evidence.** Independently re-validated: full `plugin:skill` pair set built +from every plugin.json + SKILL.md; **109 agent skill references, 0 +unresolvable**; duplicate-plugin-name check clean; G10 warnings 17→6 as claimed; +broken symlinks 3→0; `check_plugin_json.py`/`check_paths.py` exit 0 (directory +`"skills": ["./skills"]` form means the dir renames need no manifest edits). + +**Blockers before merge:** +1. **Decision D2** (master §3): preloading ON (~2.5k tokens/agent-spawn) vs + deleting the field. Author explicitly offers both. Recommend: keep preloading; + record on the PR. +2. **Rebase + mirror resync.** One real conflict + (`.hermes/skills/claude-skills/skills-index.json`) — resolve by re-running the + four sync scripts, never by hand-merge. +3. **Cover the new dev agent.** `engineering/book-to-skill/agents/cs-book-to-skill.md` + (landed after the PR) still carries the old path form — convert to + `book-to-skill:book-to-skill` or the PR re-lands the bug it fixes. +4. **Confirm the comma-separated encoding.** 9 agents got multi-skill values + flattened to one comma-joined string (e.g. `agents/personas/content-strategist.md`, + 8 refs on one line). If the sub-agent spec wants a YAML list, these resolve to + nothing — re-encode as YAML lists (safe either way). +5. **Release note** for renamed invocations (`pw`, `hub-*`, `ar-*`, `handoff-*`). + +**Improvement stream:** resolve the documented `/hub:` vs `/agenthub:` doc +mismatch (flagged in-PR, deferred). + +**Verification (post-rebase).** +```bash +git checkout pr939 +for d in .codex .gemini .vibe .hermes; do find $d -xtype l | wc -l; done # all 0 +python3 scripts/check_frontmatter.py --all # 0 errors, 6 warnings +python3 scripts/check_paths.py --all && python3 scripts/check_plugin_json.py --all +python3 scripts/check_dual_publish.py && python3 scripts/derive_counters.py --check +# resolver check: rebuild plugin:skill pairs from all plugin.json + SKILL.md names, +# split every agent skills: value on commas, assert 0 unresolvable (script in audit tooling) +``` + +--- + +## #940 — gate the drifted counter sites, rewrite ClawHub §5 — **MERGE-WITH-CHANGES (merge LAST)** + +**What it does.** Incremental: 5 files, +40/−18. Extends +`derive_counters.py::run_check` from 1 gated JSON site to 4 (adds marketplace +`description`, `mkdocs.yml site_description`, `.codex-plugin/plugin.json` +description); rewrites the three drifted texts with uniform gated phrasing; +bumps `.codex-plugin/plugin.json` from v2.2.0-era numbers (nine releases +behind — verified). Rewrites CLAUDE.md ClawHub §5: drops "No other extras" and +the `./`-prefix regression history, asserts unrecognized top-level fields are +tolerated. + +**Evidence & defects.** +- The three drift sites and before-values are real; the gate design is right. +- **Fails its own gate on today's dev**: simulated merge + `--check` → 12 + mismatches ("claims skills=362, derived 364 … tools 644 vs 667 … plugins 88 vs + 90") across all three newly gated sites. Numbers must be regenerated at rebase. +- **Ungated claims inside gated sites**: `CLAIM_PATTERNS` has no + `agents`/`commands` patterns, yet the PR writes "102 agents, 116 slash + commands" (both already stale: 104/120) into sites the gate scans but cannot + see. +- **Policy collision with #966 (decision D1)**: the §5 rewrite says extension + fields "need no special dispensation" while `check_plugin_json.py` (untouched + here; made *stricter* by #966) hard-errors on any extra key. An author + following the new prose would be rejected by the repo's own blocking CI. +- A governance change ("No other extras" was a stated non-negotiable) is + smuggled under `fix(docs)` — needs an explicit maintainer ACK either way. + +**Required changes.** +1. Rebase onto post-Phase-4 dev; regenerate all descriptions from + `derive_counters.py` output; `--check` must exit 0. +2. Add `agents` + `commands` patterns to `CLAIM_PATTERNS` (or drop those two + figures from gated strings). +3. Rework §5 per D1 (recommended: keep #966's strict policy; state that + `authoring-notes.json` is the sidecar home for provenance; keep one line + recording the historical `./`-prefix regression — the deleted text was the + only in-repo record of it). + +**Why last:** its own gate freezes the counters it writes, so it must be the +final write of the release — the natural true-up vehicle after the new-skill +batch (D4). + +**Verification (post-rebase).** +```bash +git checkout pr940 +python3 scripts/derive_counters.py # ground truth +python3 scripts/derive_counters.py --check # MUST exit 0 across all gated sites +# perturbation probe: change "364"→"363" in mkdocs.yml site_description → --check FAILS; revert +python3 -c "import json; json.load(open('.codex-plugin/plugin.json')); json.load(open('.claude-plugin/marketplace.json'))" +``` + +--- + +## Overlap map (why the order is fixed) + +| File | 936 | 937 | 938 | 939 | 940 | +|---|---|---|---|---|---| +| `ci-quality-gate.yml` | +G10 | +G7 advisory | G7→blocking | — | — | +| `check_model_freshness.py` + allowlist | — | creates | hardens | — | — | +| `check_frontmatter.py` | creates | — | — | (warning count depends on 939) | — | +| agent `.md` files | quotes descriptions | — | — | rewrites `skills:` in same files | — | +| mirrors (4 dirs) | — | — | — | regenerates (sole dev conflict) | inherited | +| counters/CLAUDE.md/marketplace/mkdocs/codex-plugin | — | — | — | — | sole owner | + +If #939's preloading question stalls: #940's 5-file payload touches nothing +#939 owns except the inherited mirror commit — it can be rebased off the stack +directly onto #938 and re-submitted. Worth offering the author. diff --git a/audit/pr-stream-2026-08/fix-series-small.md b/audit/pr-stream-2026-08/fix-series-small.md new file mode 100644 index 00000000..4d5a36dc --- /dev/null +++ b/audit/pr-stream-2026-08/fix-series-small.md @@ -0,0 +1,190 @@ +# PR audit detail — small-fix PRs (#966, #964, #932, #929, #895) + +**Audited:** 2026-08-21 — PR states below (CI, mergeability, commit counts) are a snapshot from that date; re-run each verification block before acting on a verdict. + +Back to [00-MASTER.md](00-MASTER.md). All five: base `dev` ✓, zero +reviews/comments/CI runs. **Pairwise file overlaps: NONE** (computed over +changed-file sets); all five test-merge clean onto dev `6972e65` — merge order +is git-unconstrained. Semantic constraint: once #966 lands, its stricter +validator hard-fails any future manifest reintroducing `source`/`attribution` +(this binds #948/#961, not these five). + +--- + +## #966 — strip `source`/`attribution` from 39 plugin.json manifests — **MERGE** + +**What it does.** 80 files, +336/−258. Removes `source` from 24 manifests and +`attribution` from 16 (39 distinct); adds a sibling +`.claude-plugin/authoring-notes.json` per manifest holding the removed value(s). +`check_plugin_json.py`: deletes `APPROVED_EXTENSIONS` — any extra key is now a +hard FAIL. CLAUDE.md ClawHub rule 5 rewritten in the same change ("Authoring +metadata now lives in a sibling file the validator never reads … `source` +remains valid in `marketplace.json` — the two schemas are not interchangeable"). +`marketplace.json` correctly untouched. + +**The policy question, resolved by evidence.** CLAUDE.md did bless +`source`/`attribution` as approved extension fields — *pending a ClawHub-time +stripping pipeline that never landed*. Claude Code's installer reads the raw +manifest, and issue #954 (open, 2026-08-14) documents the verbatim failure: +`✘ Failed to install plugin "roast@claude-code-skills" … Unrecognized key: +"source"` (same for `"attribution"` on grill-me). **39 of 90 plugins are +uninstallable today.** (Count reconciliation: #954 said 37 of 88 at filing, +against `aa8d778`; book-to-skill and memory-engineering landed since, each +carrying the keys — hence 39 of 90 as of this audit. Not a discrepancy.) The PR amends the documented policy in the same diff — +this is a policy update with evidence, not a violation. + +**Attribution loss: none.** All 39 base-vs-head manifests compared +programmatically: every diff is a pure removal of exactly those keys, zero other +key changed; every sidecar is byte-equal (as parsed JSON) to the removed +content. Example: `engineering/caveman/.claude-plugin/authoring-notes.json` +carries the full MIT credit verbatim. MIT-derived plugins also retain +attribution in READMEs/LICENSE; the sidecar ships inside `.claude-plugin/` with +the installed plugin. + +**Gates reproduced locally on the PR tree:** `check_plugin_json.py --all` → 90 +OK; `derive_counters.py --check` → pass; `check_dual_publish.py` → 0 drifted; +negative test: pre-fix caveman manifest → `FAIL … extra fields: +['attribution']`, exit 1. + +**Plan.** Merge in Phase 2, first of the pair. **Improvement stream (follow-up +PR):** three living docs still teach plugin.json as the attribution home and now +contradict policy — +`engineering/write-a-skill/skills/write-a-skill/references/quality_gates_for_skills.md` +(lines 61, 129), `engineering/write-a-skill/agents/cs-skill-author.md` (line +100), `engineering/security-guidance/skills/security-guidance/SKILL.md` (line +123). Point them at `authoring-notes.json`. Also: #948/#961 must move their +extension blocks to sidecars before undrafting (D1). + +**Verification.** +```bash +git fetch origin pull/966/head:pr966 && git worktree add /tmp/wt966 pr966 && cd /tmp/wt966 +python3 scripts/check_plugin_json.py --all # 90 OK, 0 FAIL +python3 scripts/derive_counters.py --check && python3 scripts/check_dual_publish.py +# post-merge real-world check (the exact failing command from issue #954): +claude plugin marketplace add alirezarezvani/claude-skills && claude plugin install roast@claude-code-skills +``` + +--- + +## #964 — cap 4 marketplace descriptions at 1024 chars — **MERGE** + +**What it does.** 1 file (`.claude-plugin/marketplace.json`), +4/−4. Shortens +exactly the 4 over-cap descriptions: `engineering-advanced-skills` 1132→986, +`memory-engineering` 1044→964, `research-ops-skills` 1593→957, +`markdown-html-skills` 1240→914. Unblocks GitHub Copilot CLI marketplace +loading (1024-char limit per GitHub docs). + +**Evidence.** Verified on base: exactly those 4 exceed 1024, no others. +Parsed-JSON field diff over all 90 entries: only `description` differs, only in +those 4. Trims are genuinely parenthetical — all 37 skill names kept in +engineering-advanced-skills; no inventory item dropped; no mid-word cuts. One +immaterial PR-body inaccuracy: claims post-fix max is 986; actually 1021 +(`commercial-skills`, untouched) — still under cap. + +**Risk.** `commercial-skills` at **1021/1024** — 3 chars of headroom; the next +routine tweak re-breaks Copilot. The author offered a CI guard; it is not in +this PR. + +**Plan.** Merge in Phase 2 after #966 (no overlap; release-note them together). +**Improvement stream:** accept the offered ≤1024 guard — fold into +`check_plugin_json.py` or `ci-quality-gate.yml`. + +**Verification.** +```bash +git fetch origin pull/964/head:pr964 +git diff origin/dev pr964 --stat # 1 file, +4 -4 +git show pr964:.claude-plugin/marketplace.json | python3 -c " +import json,sys; d=json.load(sys.stdin) +ls=sorted(((len(p['description']),p['name']) for p in d['plugins']),reverse=True)[:5] +print(ls); assert ls[0][0]<=1024" +``` + +--- + +## #932 — correct stale DynamoDB on-demand pricing — **MERGE** + +**What it does.** 1 file, +1/−1: +`engineering-team/skills/aws-solution-architect/references/service_selection.md:122` +— `$1.25/M writes, $0.25/M reads` → `$0.625/M writes, $0.125/M reads`. + +**Evidence.** The cited AWS Database Blog post was fetched live during audit: +"DynamoDB lowers pricing for on-demand throughput … 50% … November 1, 2024." +Post-cut us-east-1 rates match the diff exactly; both numbers precisely halved; +line context is standard (not transactional) throughput — the author's own note +that $1.25 is the correct *transactional* rate shows unusual domain care. One +harmless PR-prose overstatement (mentions figures not present in the file). + +**Plan.** Merge in Phase 3, unchanged. **Improvement stream:** consider an +"as of (us-east-1)" annotation convention for priced reference lines — +this class of drift will recur (same disease #938 fixed elsewhere). + +**Verification.** +```bash +git fetch origin pull/932/head:pr932 && git diff origin/dev pr932 # exactly the 1-line swap +curl -sL https://aws.amazon.com/blogs/database/new-amazon-dynamodb-lowers-pricing-for-on-demand-throughput-and-global-tables/ | grep -o "50%" +``` + +--- + +## #929 — harden gws_recipe_runner subprocess execution — **MERGE** + +**What it does.** 1 file, +23/−3 +(`engineering-team/google-workspace-cli/.../scripts/gws_recipe_runner.py`). +Replaces `subprocess.run(cmd, shell=True)` with +`shlex.split(cmd, comments=True)` + `shell=False` (unparseable/empty handled by +skip-and-continue); adds a required `--yes` flag — `--run` without `--dry-run` +and without `--yes` now prints a refusal naming the irreversible side effects +and exits 1. Docstring/epilog updated. + +**Evidence — executed, not just read.** `shell=True` count on head: 0. On the PR +head: `--help` OK; `--list --json` valid JSON (43 recipes); +`--run standup-report --dry-run` unchanged; bare `--run` → refusal + exit 1. +All 48 command templates scanned: zero use pipes/redirects/`&&`/`;`/`$()`/globs +— `shell=False` changes nothing for the current catalog; the 2 inline-comment +templates are handled by `comments=True`. The "latent footgun" framing is +honest: the fix pre-empts the injection that `cmd.format(**args)` + `shell=True` +would have created. + +**Breaking change, intended:** bare `--run X` no longer executes. SKILL.md never +documents bare `--run` (checked) — no doc drift. + +**Plan.** Merge in Phase 3, unchanged. **Improvement stream:** cosmetic +indentation nit on the `--yes` argument line. + +**Verification.** +```bash +git fetch origin pull/929/head:pr929 && git worktree add /tmp/wt929 pr929 +P=/tmp/wt929/engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py +python3 $P --help && python3 $P --list --json | python3 -m json.tool >/dev/null +python3 $P --run standup-report --dry-run +python3 $P --run standup-report; test $? -eq 1 # refusal without --yes +grep -c "shell=True" $P # 0 +``` + +--- + +## #895 — add LinkedIn Skills to Related Projects — **MERGE-WITH-CHANGES** + +**What it does.** 1 file, +1/−0: one row in the README Related Projects table +linking `sergebulaev/linkedin-skills` ("10 LinkedIn skills … MIT, 303 stars"). + +**Evidence.** Self-promotion, yes — but matching the established `toprank` +precedent (#517/#601, disclosed in the PR). The repo is real and healthy: +verified live — public, **578★ / 90 forks**, actively pushed, genuine MIT +LICENSE, real Claude Code + Codex install docs. Genuinely on-topic. Row text is +stale, not fabricated (10→11 skills, 303→578 stars since July filing). +Docs-only; counters unaffected. + +**Required change (pre-merge).** Refresh the row: "11 LinkedIn skills … MIT" — +and preferably drop the hardcoded star count entirely (toprank's "107 stars" +has the same rot disease). One-line review suggestion; author has been +convention-careful (correct base, correct table format). + +**Plan.** Phase 3 after the row refresh. **Improvement stream:** decide the +Related-Projects star-count policy repo-wide (master §5.7). + +**Verification.** +```bash +git fetch origin pull/895/head:pr895 && git diff origin/dev pr895 # single added row +curl -s https://api.github.com/repos/sergebulaev/linkedin-skills | python3 -c "import json,sys;d=json.load(sys.stdin);print(d['stargazers_count'],d['license']['spdx_id'],d['pushed_at'])" +``` diff --git a/audit/pr-stream-2026-08/maintainer-drafts.md b/audit/pr-stream-2026-08/maintainer-drafts.md new file mode 100644 index 00000000..1e7d96b7 --- /dev/null +++ b/audit/pr-stream-2026-08/maintainer-drafts.md @@ -0,0 +1,174 @@ +# PR audit detail — maintainer draft PRs (#961, #948, #946) + +**Audited:** 2026-08-21 — PR states below (CI, mergeability, commit counts) are a snapshot from that date; re-run each verification block before acting on a verdict. + +Back to [00-MASTER.md](00-MASTER.md). All three are the maintainer's own drafts. +The question for each is not merge-worthiness but a **finish plan**: what +remains between the current head and a clean merge. Sequencing constraint: +#948 and #961 both append entry #91 at the tail of `marketplace.json` `plugins` +and both rewrite the same three counter surfaces — **merge #948 first** +(smaller, already CI-green), then rebase #961. Both are bound by decision D1 +(#966's sidecar policy) — their manifests carry `source`/`attribution` blocks +that #966's stricter validator hard-fails. + +--- + +## #948 — engineering/human-gate (draft) — **FINISH-PLAN → MERGE** (closest to ready) + +**What it ships.** 19 files, +3,497/−13. Two deliverables: +(a) public audit record `audit/human-review-2026-08/AUDIT.md` — a +do-not-vendor / do-adopt-the-pattern verdict on `petergyang/human-review` +(~5,200 LOC Node 20 + npm deps fails stdlib-only; findings F1 unpinned +`npx -y` auto-execution, F2 unbounded re-poll, F3 ungated artifact routes); +(b) a conceptual derivation: `review_page_builder.py` (883 ln, Markdown/HTML → +single-file sanitized review page, zero network requests), `feedback_parser.py` +(482), `human_gate.py` (639, open/status/collect/close state machine, gates +G1–G7 — "G1 is never waivable"), SKILL.md, 3 references, 2 assets, agent, +command, plugin.json, marketplace entry. + +**State of quality.** Battle-tested: 7 bot-review rounds in-thread, each finding +reproduced and fixed with regression fixtures (`` void-element +body-swallow, `data-hg` attribute-forgery vector, `__CONTENT__` placeholder +collision, `## BLOKCER` typo silently downgrading severity — G7 was added for +that one). **CI fully green on head `5d03ed9`** (Lint/Tests/Docs/Security, +claude-review, VirusTotal). Attribution block is the best in the repo +("CONCEPTUAL derivation — no upstream source code is copied," each divergence +mapped to an audit finding, upstream's own 90/90 tests run during the audit). +Overlap fenced correctly: humanizers (behuman, content-humanizer) are voice; +this is approval — the missing human lane of agent-harness's machine-only loop. + +**Finish plan.** +1. Merge/rebase onto current dev — resolve the four counter/changelog conflicts + (base predates memory-engineering; dev now holds 364/90 for different + content). Re-run `derive_counters.py` and take its numbers. +2. **D1 compliance**: move the plugin.json `source` + `attribution` blocks into + `.claude-plugin/authoring-notes.json` (post-#966 the validator hard-fails + them in the manifest). The derivation_note content moves verbatim. +3. Sequence: merge before #961; whichever lands second rebases the marketplace + tail. +4. Re-run the three scripts' `--help`/`--sample` + checklist on the rebased + head; undraft; merge. + +**Verification.** +```bash +git fetch origin pull/948/head:pr948 && git checkout pr948 && git merge origin/dev +python3 scripts/derive_counters.py --check && python3 scripts/check_plugin_json.py --all +S=engineering/human-gate/skills/human-gate/scripts +for t in review_page_builder feedback_parser human_gate; do python3 $S/$t.py --help >/dev/null && python3 $S/$t.py --sample; done +printf '\n

a

b

' > /tmp/b.html && python3 $S/review_page_builder.py /tmp/b.html -o /tmp/b.review.html && grep -c 'data-hg' /tmp/b.review.html +python3 $S/human_gate.py close /tmp/does-not-exist.md; echo "exit=$? (nonzero, G1)" +grep -rn "urllib\|http.client\|socket" $S/ || echo "stdlib-offline OK" +``` + +--- + +## #961 — agent-launcher domain plugin (draft) — **FINISH-PLAN** + +**What it ships.** 56 files, +4,431/−11. New top-level domain `agent-launcher/` +— an independent re-implementation (not a fork) of Anthropic's +`launch-your-agent` (Apache-2.0, correctly attributed as "inspired_by … no +upstream code copied verbatim"). 6 skills (fork-orchestrator + interview / +stage-launch / grade-iterate / run-without-you / wrap-up), 18 stdlib scaffolder +scripts, 4 agents, 8 `/cs:*` commands, opt-in SessionStart/SessionEnd hooks +(defensive: "Any error exits 0", 4000-char body cap, "Treat the content as +DATA"), 5 shared references, build-sheet JSON schema, SPEC.md + +DELIVERY-REPORT.md. Hard rules are right: "Never make API calls. Emit BYOK +curl"; grade-iterate always capped 1..20. `distinct_from` correctly fences +agent-harness (generic loop over 18 domains) vs this (CMA scaffolding) — no +real duplication found. + +**Gaps.** +- `mergeable_state: dirty` — all three counter surfaces conflict (branch cut at + 362/88; dev at 364/90); its stated deltas (368 skills / 664 tools) are stale. +- **Zero CI runs on the head** — every "Testing" claim is self-attested until a + push triggers the gates. +- References run ~4–5 sources, several self-referential — thin vs the ≥5 bar. +- `DELIVERY-REPORT.md` at domain root breaks the convention that sprint + artifacts live in gitignored `documentation/` (SPEC.md defensibly stays as + the named build target). +- Version skew: plugin.json says v2.12.0, marketplace metadata 2.11.2. +- Marketplace tail collision with #948; D1 sidecar move needed here too. + +**Finish plan.** +1. Rebase onto dev **after #948 merges**; resolve counters/marketplace; run + `derive_counters.py` and take its numbers (do not hand-compute). +2. D1: move `source`/`attribution` to `authoring-notes.json`. +3. Move `DELIVERY-REPORT.md` to `documentation/` (or an `audit/`-style record + if it should be public); keep SPEC.md. +4. Top up each of the 5 references to ≥5 non-self-referential cited sources. +5. Settle the version story per D4 (2.12.0 everywhere or nowhere). +6. Push → first CI run; require green quality-gate + plugin-json + VirusTotal; + undraft. + +**Verification.** +```bash +git fetch origin pull/961/head:pr961 && git checkout pr961 && git merge origin/dev +python3 scripts/derive_counters.py --check && python3 scripts/check_plugin_json.py --all +for f in agent-launcher/skills/*/scripts/*.py agent-launcher/hooks/*.py; do python3 -m py_compile "$f"; done +for f in agent-launcher/skills/*/scripts/*.py; do python3 "$f" --help >/dev/null && python3 "$f" --sample >/dev/null || echo "FAIL $f"; done +AGENT_LAUNCHER_SESSION=1 python3 agent-launcher/hooks/session_start.py; echo $? # and without env var: silent, 0 +grep -rn "ANTHROPIC_API_KEY" agent-launcher/ | grep -v '\$ANTHROPIC_API_KEY' # no literal keys +``` + +--- + +## #946 — agent-memory L0–L3 spec (draft) — **REWORK, not superseded** + +**What it ships.** Spec-only, 4 files, +2,085: `engineering/agent-memory/DESIGN.md` +(1,263 ln), memory schema JSON, a validator deliberately parked as `.py.txt` +(so counters don't move), and a `hooks.json` contract. Four-tier memory +(L0 transcripts → L1 atomic facts ≤500 → L2 project CLAUDE.md block ≤60 → +L3 global persona ≤30) with deterministic recurrence-based promotion, derived +from TencentDB-Agent-Memory (MIT, no code vendored) while rejecting its +`ANTHROPIC_BASE_URL` proxy on four grounds. Exceptional rigor: 69-check +validator with injected-regression tests; latency measured not estimated +(spawn+scan p50 23.2 ms). CI green; `mergeable_state: clean`. + +**The critical finding.** The spec's decision-driving §2 overlap analysis +**never mentions `engineering/memory-engineering`** (grep over the full diff: +0 hits, vs skillopt-sleep 14, llm-wiki 6) — which merged into dev via #947 in +the same window. **This is not supersession**: memory-engineering is an +*advisory/audit* toolkit (cost profiler, architecture picker, density auditor, +forgetting-policy linter — it designs and prices *other* memory systems); +agent-memory would *be* a runtime memory system. Different layer. But they now +collide in namespace and concept, and memory-engineering's F1–F8 +forgetting-policy linter is precisely the gate agent-memory's own L1/L2 +eviction policy should be linted by. Closing #946 as "superseded" would be +factually wrong; merging it with a stale §2 would be negligent. + +**Second issue — placement precedent (decision D3).** A DESIGN.md-only folder +under a domain root is a new pattern the PR itself flags as an unresolved +maintainer call; house precedent keeps plans in gitignored `documentation/` +with `audit/` as the only public non-skill record. And the spec's own decision +3 concedes the folder may be deleted if the §9.2 two-week extraction trial +fails — merging a folder scheduled for possible deletion is backwards. + +**Rework plan (preferred over both merge-as-is and close).** +1. Add a §2 subsection on memory-engineering: advisory-vs-runtime layer + distinction, the namespace fence, and a commitment that agent-memory's + forgetting policy will be expressible in a form + `forgetting_policy_linter.py` can lint (F1 explicit-forgetting-rule and F4 + contradictions-surfaced map directly onto §5.1's contradiction constraint). +2. Resolve D3: move the spec to `audit/agent-memory-design-2026-08/` + (counter-free, precedent-safe, matches how "should we build this" decisions + are already recorded — #948's `audit/human-review-2026-08/` is the model) — + or record an explicit maintainer statement sanctioning DESIGN-only folders. +3. Run the §9.2 rule-based-extraction trial *before* the folder enters + `engineering/`; the spec's own honesty ("the honest outcome is 'extend the + nightly cycle instead' and this folder gets deleted") demands it. +4. Stage a formal `attribution` disposition (sidecar, per D1) for the eventual + plugin. + +**Defensible alternative:** close the PR, keep the branch, park DESIGN.md in +maintainer-local `documentation/implementation/` until the trial justifies +building — no counters or CI depend on it, so nothing is lost. + +**Verification.** +```bash +git fetch origin pull/946/head:pr946 && git checkout pr946 +grep -c "memory-engineering" engineering/agent-memory/DESIGN.md # 0 now — must be >0 after rework +cp engineering/agent-memory/assets/validate_examples.py.txt /tmp/_t.py && python3 /tmp/_t.py # 69 checks, 0 failures +python3 -c "import json; json.load(open('engineering/agent-memory/assets/memory_schema.json')); json.load(open('engineering/agent-memory/hooks/hooks.json'))" +python3 scripts/derive_counters.py --check # counters must not move +ls engineering/memory-engineering/ && grep -l "forgetting" engineering/memory-engineering/*/scripts/*.py +``` diff --git a/audit/pr-stream-2026-08/new-skills.md b/audit/pr-stream-2026-08/new-skills.md new file mode 100644 index 00000000..9866136a --- /dev/null +++ b/audit/pr-stream-2026-08/new-skills.md @@ -0,0 +1,266 @@ +# PR audit detail — accepted external new-skill PRs (#967, #944, #926, #965, #942, #943) + +**Audited:** 2026-08-21 — PR states below (CI, mergeability, commit counts) are a snapshot from that date; re-run each verification block before acting on a verdict. + +Back to [00-MASTER.md](00-MASTER.md). Shared context: all six target `dev` ✓, +all purely additive (no conflicts), none has ever had a CI run, none touches +counters/marketplace/generated indexes — which is exactly what CONTRIBUTING +asks of external contributors. The public contributor contract +(CONTRIBUTING/CONVENTIONS) makes `scripts/` and `references/` optional; the +stricter internal CLAUDE.md bar (scripts + refs ≥5 sources + agent + command) +is applied below as improvement-stream items, not blockers — precedent exists +on dev for doc-only skills (`engineering/minimalist/`, `engineering/strict-api/`). + +Security: `skill_security_auditor.py --strict` run on every PR — all clean +(0 CRITICAL / 0 HIGH) except one **verified false positive** on #944 (below). + +Cross-cutting maintainer actions after merges: run `derive_counters.py` (all +six drift headline counters — Phase 5's rebased #940 is the true-up vehicle), +re-run the four sync scripts, and make the plugin/marketplace call for +#967/#965/#943 (#944 and #942 auto-join their domain plugins via +`"skills": ["./skills"]`). + +--- + +## #967 — engineering/boost-asio-pro (async C++ networking) — **MERGE** + +**What it ships.** Docs-only, 6 files, +882: SKILL.md (145) + 5 references +(coroutines 412, pre-cpp20 164, build 89, ssl 39, classic-boost 33). Core +thesis: establish Boost version × C++ standard **first** (coroutines ≥1.77 / +callbacks ≥1.74 / stackful spawn ≥1.80 / classic `io_service` 1.62–1.65), then +write in that style. + +**Why it clears the bar.** The strongest doc-only submission in the stream — +specific, hard-won, verified-accurate knowledge: the strand-write-interleaving +trap ("Two `async_write`s in flight on the same strand still interleave bytes +on the wire") with the correct write-queue pattern in both styles; a +version-floor table that bites in practice ("Debian bookworm ships Boost 1.74 — +the `#include` fails outright"); `async_accept(make_strand(...))` return-type +subtlety; `operation_aborted`-as-keep-waiting timer semantics. Ends "It +compiles. Build it." — the repo's verification-first ethos. Zero overlap on dev +(no C++ networking skill anywhere). Frontmatter/trigger/desc all pass; the only +validator error is the waivable missing-`scripts/` (doc-only, justified in the +PR body). Security PASS. + +**Plan.** Merge first in Phase 4, as-is. **Improvement stream:** (1) in-tree +attribution note for the author's linked MIT examples repo (PR body offers it); +(2) add a short Sources block per reference (official Boost/Asio docs + release +notes clear ≥5 easily); (3) maintainer plugin/marketplace decision + counter +true-up. + +**Verification.** +```bash +git fetch origin pull/967/head:pr967 && git checkout pr967 +python3 engineering/skills/skill-tester/scripts/skill_validator.py engineering/boost-asio-pro # only the waivable no-scripts error +python3 engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py engineering/boost-asio-pro --strict # PASS 0C/0H +``` + +--- + +## #944 — finance/skills/stock-analysis — **MERGE-WITH-CHANGES** + +**What it ships.** The deepest domain skill in the stream: 61 files, +24,758. +SKILL.md (304, 10-stage workflow + sector router + output contract), 21 core +references (159–629 lines each: data sourcing, earnings quality, forensic red +flags, valuation, epistemics, IPO/forensic modes, …), **26 sector playbooks** +(banks, NBFC, insurance, IT/SaaS, pharma, REITs, holdco, semiconductors, …), +**5 stdlib CLI engines** (`ratios.py` 2,690 ln, `score.py` 2,072, +`verify_data.py` 1,663, `lint_report.py` 1,121, `valuation.py` 893) + +1,608-line `benchmarks.json`, declarative `evals/` + worked `examples/`. +India-first (SEBI LODR, Ind-AS, CARO 2020) and global (EDGAR, IFRS/US-GAAP). + +**Why it clears the bar.** Practitioner-grade throughout: "For banks, insurers, +REITs and miners the standard ratios are not merely less useful, they are +undefined or inverted"; holdco look-through P/E, double leverage ">1.3x a red +flag… invisible in consolidated D/E", India NAV discounts 40–75%; "You cannot +compute a quarterly CCC [in India]… State that limitation rather than +interpolating silently." "Never invent a number" is enforced structurally. +Scripts verified by execution: all 5 pass `--help`; `--example`/`--json` modes +exit 0; `lint_report.py` on the bundled example → OVERALL PASS; imports are +argparse/json/math/re/statistics/dataclasses only — zero +subprocess/eval/urllib/socket/file-writes, no `random`/`now()` → fully +deterministic. Distinct lane from `financial-analyst` (FP&A/DCF) and +`business-investment-advisor` (capex ROI). Auto-joins the finance plugin +(`"skills": ["./skills"]`). "Not investment advice" boundary present in both +description and body. + +**Required changes (pre-merge).** +1. **Trim `description:` to ≤1024 chars** (currently 1,463 — the one hard + checklist violation). Keep the trigger set (analyse/value a stock; + OPM/ROCE/NIM/GNPA; forensic "is the profit real"; IPO/DRHP); cut the quoted + example enumeration. +2. Add `## Anti-Patterns` and `## Cross-References` headings (content largely + exists; cross-refs must name `finance/financial-analyst` and + `finance/business-investment-advisor` with the lane boundary). +3. Disposition the auditor's one CRITICAL [PROMPT-EXFIL] at + `references/sectors/holdco-assetmgr.md:58` — **verified false positive** + (finance-vocabulary pattern match on the LTV/double-leverage table, nothing + about credentials). Needs an auditor allowlist entry or maintainer waiver + note so strict CI can pass (see master §5.5). + +**Improvement stream (post-merge).** `source`-style provenance for the upstream +MIT repo (in `authoring-notes.json` per D1); split `ratios.py`/`score.py` per +the validator's karpathy-style size nit; decide whether `evals/`+`examples/` +dirs become a blessed pattern (they are genuinely good). + +**Verification.** +```bash +git fetch origin pull/944/head:pr944 && git checkout pr944 +cd finance/skills/stock-analysis/scripts +for s in ratios score valuation verify_data lint_report; do python3 $s.py --help; done +python3 ratios.py --example --json && python3 score.py --example --json && python3 valuation.py --example && python3 verify_data.py --example +python3 lint_report.py ../examples/standard-analysis-example.md # OVERALL PASS +grep -rnE 'subprocess|eval\(|urllib|requests|socket' *.py # no hits +# description-length gate (must be ≤1024 post-fix): +python3 - <<'EOF' +import re; t=open('finance/skills/stock-analysis/SKILL.md').read() +print(len(re.search(r'description:\s*(.*)',t.split('---')[1]).group(1))) +EOF +``` + +--- + +## #926 — marketing-skill/skills/business-name-fit — **MERGE-WITH-CHANGES** + +**What it ships.** 3 files, +323: SKILL.md (120) + 2 references (naming-research +95, worked-examples 108). Correctly attributed port of +`Elham-Farajnejad/business-name-fit`. Cross-cultural business-name +suggestion/vetting: meaning, look-alike, pronunciation, spelling, WIPO +distinctiveness, sound symbolism, closing with a trademark/domain/native-speaker +verification handoff. + +**Why it clears the bar.** Genuinely expert and epistemically honest: "a founder +can build a business on such a name and still never own it"; the cross-cultural +inversion ("a word plainly descriptive at home may be arbitrary and strong +abroad, and the reverse"); Scenario C rejects both the on-the-nose name and the +distinctiveness winner (Simorgh) for search pollution; "these associations come +mainly from English-language research and do not transfer automatically" is +repeated as an Anti-Pattern. No naming skill exists among 46 marketing skills; +`brand-guidelines` is correctly sequenced as post-name work. Auto-registers via +the marketing plugin's directory glob. Contributor iterated 4 commits including +a self-caught fix — engaged. + +**Required changes (pre-merge).** +1. Description: "Use **whenever**" → "Use **when**" (one word; makes the repo + validator's trigger regex pass). +2. Add 2 cited sources to reach the ≥5 floor (currently 3: WIPO 900.1E, Kohli & + LaBahn 1997, Pogacar et al. 2015 — candidates: USPTO TMEP §1209, + Usunier & Shaner 2002, Interbrand/Lexicon methodology). +3. Optional: swap `❌/⚠️` table tokens for `FAIL/CAUTION` text. + +**Verification.** +```bash +git fetch origin pull/926/head:pr926 && git checkout pr926 +python3 engineering/write-a-skill/skills/write-a-skill/scripts/skill_description_validator.py marketing-skill/skills/business-name-fit/SKILL.md +python3 engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py marketing-skill/skills/business-name-fit/ +python3 scripts/check_plugin_json.py --all +``` + +--- + +## #965 — research/dsh-deepread → deepread — **MERGE-WITH-CHANGES** + +**What it ships.** 3 files, +272: SKILL.md (156) + 2 references (feynman 60, +knowledge-map 56). Evidence-first reading of **supplied** documents: 5 modes +(quick/deep/map/feynman/book), claim/reason/evidence/assumption/counterargument +decomposition, 4-level confidence labels, evidence ledger. Bilingual triggers +(`精读`, `费曼读书法`). + +**Why it clears the bar.** Disciplined, not slop: "A topic label is not a +claim. Bad: 'This chapter is about habits.' Good: 'The author argues that +changing environmental cues is more reliable than relying on willpower'"; +"Do not convert confidence into fake numerical precision"; book mode requires +"a final thesis map that could not be obtained by reading only the introduction +and conclusion"; prompt-injection defense in both body and Anti-Patterns. Real +lane: `research/deep-research` is discovery, `product-team/research-summarizer` +is briefs — the boundary is drawn explicitly with cross-refs. + +**Required changes (pre-merge).** +1. **Rename `research/dsh-deepread` → `research/deepread`** (folder + `name:` + + the two "DSH" H1 strings) — personal branding prefix has no meaning here; + renaming after sync/marketplace registration is costly, so do it now. +2. Add ≥5 cited sources across the references (Adler & Van Doren, Toulmin, + Karpicke/Roediger retrieval practice, Ahrens, Feynman-technique canon). +3. Path-qualify the `research-summarizer` cross-reference + (`product-team/research-summarizer`). +4. Registration: add `.claude-plugin/plugin.json` (`"skills": ["./"]`) + + marketplace entry to match every `research/` sibling, and a SIGNALS routing + row in the `research/research` orchestrator (maintainer or follow-up). + +**Verification.** +```bash +git fetch origin pull/965/head:pr965 && git checkout pr965 +python3 engineering/skills/skill-tester/scripts/skill_validator.py research/deepread +python3 engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py research/deepread --strict # PASS 0C/0H +grep -rn 'research-summarizer' research/deepread/ # path-qualified +``` + +--- + +## #942 — engineering-team/skills/embedded-iot-mentor — **MERGE-WITH-CHANGES (light)** + +**What it ships.** 1 file, +129 (SKILL.md). MCU/board/toolchain selection +(ESP32/Pico W/STM32/nRF52 decision table), firmware-reuse-first doctrine +(ESPHome/Tasmota/Meshtastic/WLED before writing code), data-destination table, +cost/time snapshots, breadboard-MVP-by-default phasing. + +**Why it clears the bar.** Real practitioner judgment: "Writing firmware is a +cost the user pays, not a deliverable they receive"; the soil-NPK-probe +conductivity example; "'on my phone' is not 'from anywhere' — away from home +means a VPN, a tunnel, or a hosted service, never a port forward"; two-axis +experience probe; per-section output caps with drop conditions. Zero +embedded/firmware coverage on dev; correct domain (practitioner +engineering-team); **auto-joins the domain plugin** via `"skills": ["./skills"]` +— unlike its sibling #943, it is distributable on merge. Security PASS; no +vendor lock-in. + +**Required change (pre-merge).** Clear the validator's 100-content-line floor +(currently 92): extract the MCU + toolchain + data-destination tables into +`references/hardware-selection.md` with ≥5 cited sources +(Espressif/ST/Nordic/RPi docs, ESPHome/PlatformIO) — kills two findings at once. + +**Improvement stream.** One stdlib script (`bom_cost_estimator.py` or a power- +budget estimator) + `/cs:` command to reach the Path-B house shape. + +**Verification.** +```bash +git fetch origin pull/942/head:pr942 && git checkout pr942 +python3 engineering/skills/skill-tester/scripts/skill_validator.py engineering-team/skills/embedded-iot-mentor +python3 -c "import json; print(json.load(open('engineering-team/.claude-plugin/plugin.json'))['skills'])" # ['./skills'] → auto-included +``` + +--- + +## #943 — productivity/swedish-mentor — **MERGE-WITH-CHANGES (borderline REWORK)** + +**What it ships.** 1 file, +81 (SKILL.md). CEFR-leveled Swedish-learning +mentor: 2-question placement probe (don't take "I'm intermediate" at face +value), curated real channel/podcast recommendations with level tags, learning +path across the four skills. Prompt-injection guard and a "Never invent a URL" +rule present. + +**Why it is borderline.** Thinnest of the batch: a well-groomed system prompt +more than a skill package — no references at all (the only one of the six), a +small resource list that will go stale with nothing to maintain it, generic +CEFR table, and a formulaic mandated opener ("Start every reply with a warm +agency line"). It also would land as the **only unregistered skill in +`productivity/`** — all 10 siblings are their own plugins — i.e. present in the +tree but undistributable. Validator: 61 content lines < 100 floor + no scripts. +Placement debatable (language learning ≠ productivity) but no better domain +exists and there is zero overlap. + +**Required changes (pre-merge — all three, or defer the PR).** +1. Move the resource catalog + CEFR guide into + `references/swedish-resources.md` with real URLs and ≥5 cited sources + (Skolverket/SFI, Council of Europe CEFR, UR Play, Sveriges Radio) — fixes + the length floor and the staleness problem simultaneously. +2. Add `.claude-plugin/plugin.json` (`"skills": ["./"]`) to match the domain, + or the maintainer explicitly accepts tree-only status. +3. Soften the mandated opener into guidance. + +**Verification.** +```bash +git fetch origin pull/943/head:pr943 && git checkout pr943 +python3 engineering/skills/skill-tester/scripts/skill_validator.py productivity/swedish-mentor # 0 errors post-fix +python3 scripts/check_plugin_json.py --all # after plugin.json added +``` diff --git a/business-operations/.claude-plugin/authoring-notes.json b/business-operations/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..5fc4d647 --- /dev/null +++ b/business-operations/.claude-plugin/authoring-notes.json @@ -0,0 +1,7 @@ +{ + "source": { + "spec": "documentation/implementation/bizops-commercial-expansion-plan.md", + "build_pattern": "Path B (direct conversion) — orchestrator skill uses context: fork to chain sub-skills without polluting parent context. Sprint 1 shipped orchestrator + 2 sub-skills (process-mapper, vendor-management). Sprint 2 adds capacity-planner (Erlang-C), internal-comms (ADKAR+Kotter), knowledge-ops (5W2H SOP+runbook with context: fork for heavy multi-doc KB intake), procurement-optimizer (UNSPSC spend categorization + supplier consolidation). Every SKILL.md ships a Forcing-question library section per Matt Pocock grill-with-docs discipline.", + "distinct_from": "business-growth (external sales motion: CSM, sales engineering, RevOps, contracts). c-level-advisor (strategic executive judgment, not operational tactics). engineering/slo-architect (system reliability, not business-process reliability). engineering/llm-wiki (personal PKM, not company SOPs)." + } +} diff --git a/business-operations/.claude-plugin/plugin.json b/business-operations/.claude-plugin/plugin.json index 78495723..cb7b0586 100644 --- a/business-operations/.claude-plugin/plugin.json +++ b/business-operations/.claude-plugin/plugin.json @@ -17,10 +17,5 @@ "./skills/internal-comms", "./skills/knowledge-ops", "./skills/procurement-optimizer" - ], - "source": { - "spec": "documentation/implementation/bizops-commercial-expansion-plan.md", - "build_pattern": "Path B (direct conversion) — orchestrator skill uses context: fork to chain sub-skills without polluting parent context. Sprint 1 shipped orchestrator + 2 sub-skills (process-mapper, vendor-management). Sprint 2 adds capacity-planner (Erlang-C), internal-comms (ADKAR+Kotter), knowledge-ops (5W2H SOP+runbook with context: fork for heavy multi-doc KB intake), procurement-optimizer (UNSPSC spend categorization + supplier consolidation). Every SKILL.md ships a Forcing-question library section per Matt Pocock grill-with-docs discipline.", - "distinct_from": "business-growth (external sales motion: CSM, sales engineering, RevOps, contracts). c-level-advisor (strategic executive judgment, not operational tactics). engineering/slo-architect (system reliability, not business-process reliability). engineering/llm-wiki (personal PKM, not company SOPs)." - } + ] } diff --git a/business-operations/commands/cs-bizops.md b/business-operations/commands/cs-bizops.md index 23b9fe57..6a8d7272 100644 --- a/business-operations/commands/cs-bizops.md +++ b/business-operations/commands/cs-bizops.md @@ -1,5 +1,5 @@ --- -description: Top-level Business Operations router. Routes the inquiry to one of six BizOps sub-skills (process, vendor, capacity, comms, knowledge, procurement) and returns a digest. Invokes the business-operations-skills orchestrator (context: fork). +description: "Top-level Business Operations router. Routes the inquiry to one of six BizOps sub-skills (process, vendor, capacity, comms, knowledge, procurement) and returns a digest. Invokes the business-operations-skills orchestrator (context: fork)." argument-hint: "" --- diff --git a/c-level-advisor/.claude-plugin/plugin.json b/c-level-advisor/.claude-plugin/plugin.json index 2ca4cd4d..a98b4594 100644 --- a/c-level-advisor/.claude-plugin/plugin.json +++ b/c-level-advisor/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "c-level-skills", - "description": "33 C-level advisory skills + c-level-agents plugin layer (13 cs-* persona agents + 21 /cs:* slash commands). Complete virtual board of directors with CEO, CTO, COO, CPO, CMO, CFO, CRO, CISO, CHRO advisors plus General Counsel, Chief Data Officer, Chief AI Officer, Chief Customer Officer, and VP of Engineering (delivery throughput DORA analyzer, eng hiring funnel calculator, eng team structure designer), executive mentor, founder coach, Chief of Staff router, board meetings, decision logger, board deck builder, scenario war room, competitive intel, org health diagnostic, M&A playbook, international expansion, culture architect, change management, strategic alignment, and the founder-mode plugin (office-hours, boardroom, brief/decide/execute/post-mortem pipeline, cross-model consensus, decision freeze).", + "description": "33 C-level advisory skills (persona layer: install the separate companion c-level-agents plugin for 13 cs-* persona agents + 21 /cs:* slash commands). Complete virtual board of directors with CEO, CTO, COO, CPO, CMO, CFO, CRO, CISO, CHRO advisors plus General Counsel, Chief Data Officer, Chief AI Officer, Chief Customer Officer, and VP of Engineering (delivery throughput DORA analyzer, eng hiring funnel calculator, eng team structure designer), executive mentor, founder coach, Chief of Staff router, board meetings, decision logger, board deck builder, scenario war room, competitive intel, org health diagnostic, M&A playbook, international expansion, culture architect, change management, strategic alignment, and the founder-mode plugin (office-hours, boardroom, brief/decide/execute/post-mortem pipeline, cross-model consensus, decision freeze).", "version": "2.9.0", "author": { "name": "Alireza Rezvani", diff --git a/c-level-advisor/CLAUDE.md b/c-level-advisor/CLAUDE.md index 2cfb4f4f..909241af 100644 --- a/c-level-advisor/CLAUDE.md +++ b/c-level-advisor/CLAUDE.md @@ -76,9 +76,9 @@ A complete virtual board of directors: 28 skills covering 10 executive roles, or ## c-level-agents Plugin (v1.0.0 — new in v2.5.0) -A separate plugin at `c-level-agents/` that wraps the 10 C-roles with persona agents and slash commands. Founder-mode entry layer. +A separate plugin at the repo's top-level `c-level-agents/` directory (moved out of `c-level-advisor/` in #949 so the two marketplace sources no longer overlap) that wraps the 10 C-roles with persona agents and slash commands. Founder-mode entry layer. -### 13 cs-* Agents (in `c-level-agents/agents/`) +### 13 cs-* Agents (in `../c-level-agents/agents/`) | Agent | Voice | Wraps Skill | |---|---|---| @@ -98,7 +98,7 @@ A separate plugin at `c-level-agents/` that wraps the 10 C-roles with persona ag Existing `cs-ceo-advisor` and `cs-cto-advisor` live in `/agents/c-level/` and integrate with the same protocol. -### 17 /cs:* Slash Commands (in `c-level-agents/skills/`) +### 17 /cs:* Slash Commands (in `../c-level-agents/skills/`) **Forcing-question office hours (8):** `/cs:office-hours`, `/cs:cfo-review`, `/cs:cmo-review`, `/cs:cpo-review`, `/cs:cro-review`, `/cs:cto-review`, `/cs:ciso-review`, `/cs:gc-review` @@ -106,7 +106,7 @@ Existing `cs-ceo-advisor` and `cs-cto-advisor` live in `/agents/c-level/` and in **Meta + safety (4):** `/cs:founder-mode` (auto-router), `/cs:onboard` (founder interview), `/cs:cross-eval` (multi-model consensus), `/cs:freeze` (cooldown lock) -See [c-level-agents/README.md](c-level-agents/README.md) for the full plugin guide and [c-level-agents/references/persona-voices.md](c-level-agents/references/persona-voices.md) for voice specs. +See [c-level-agents/README.md](../c-level-agents/README.md) for the full plugin guide and [c-level-agents/references/persona-voices.md](../c-level-agents/references/persona-voices.md) for voice specs. ## Executive Mentor Slash Commands @@ -156,6 +156,6 @@ python decision-logger/scripts/decision_tracker.py **Last Updated:** 2026-05-13 **Skills Deployed:** 33 skills (15 roles incl. General Counsel, CDO, CAIO, CCO, and VPE + 5 mentor commands + 6 orchestration + 6 cross-cutting + 6 culture) + 21 /cs:* sub-skills in c-level-agents plugin -**Agents:** 15 cs-* (cs-ceo, cs-cto in /agents/c-level/; 13 in c-level-agents/agents/ including new cs-vpe-advisor) +**Agents:** 15 cs-* (cs-ceo, cs-cto in /agents/c-level/; 13 in ../c-level-agents/agents/ including new cs-vpe-advisor) **Python Tools:** 39 (stdlib-only) — +3 with vpe-advisor (delivery_throughput_analyzer, eng_hiring_funnel_calculator, eng_team_structure_designer) **Reference Docs:** 73 (71 in skills + 2 in c-level-agents/references) diff --git a/c-level-advisor/arquiteto-de-empresa/agents/cs-arquiteto.md b/c-level-advisor/arquiteto-de-empresa/agents/cs-arquiteto.md index cb7c9eb1..cf672cb8 100644 --- a/c-level-advisor/arquiteto-de-empresa/agents/cs-arquiteto.md +++ b/c-level-advisor/arquiteto-de-empresa/agents/cs-arquiteto.md @@ -1,6 +1,6 @@ --- name: cs-arquiteto -description: Company Architect — a senior chief of staff who builds a business from scratch as an OKF (Open Knowledge Format) bundle: a tree of version-controllable .md files with frontmatter type, links forming a graph, and reserved index.md/log.md. Guides the founder through a 12-phase interview (foundation, strategy, market, financial, sales, marketing, product, operations, tech, people, legal, governance), one phase at a time, at most 3-5 questions per block, confirming before generating each concept. Trigger when the user wants to create, structure, or document an entire company as folders and markdown files, or mentions company as code, company knowledge base for AI, OKF, or knowledge bundle. Works in English. Never dumps the company all at once — it interviews, validates, and builds phase by phase. +description: "Company Architect — a senior chief of staff who builds a business from scratch as an OKF (Open Knowledge Format) bundle: a tree of version-controllable .md files with frontmatter type, links forming a graph, and reserved index.md/log.md. Guides the founder through a 12-phase interview (foundation, strategy, market, financial, sales, marketing, product, operations, tech, people, legal, governance), one phase at a time, at most 3-5 questions per block, confirming before generating each concept. Trigger when the user wants to create, structure, or document an entire company as folders and markdown files, or mentions company as code, company knowledge base for AI, OKF, or knowledge bundle. Works in English. Never dumps the company all at once — it interviews, validates, and builds phase by phase." skills: c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa domain: c-level model: opus diff --git a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md index 17ff8463..8c723d80 100644 --- a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md +++ b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md @@ -18,8 +18,8 @@ Per million tokens, USD: | Tier | Example models | Input | Output | |---|---|---|---| -| Frontier-premium | Claude Sonnet 4.6, GPT-4o-tier | $3.00 | $15.00 | -| Frontier-economy | Gemini 2.5 Flash, Claude Haiku 4.5-tier | $1.25 | $5.00 | +| Frontier-premium | Claude Sonnet 5, frontier-mid tier | $3.00 | $15.00 | +| Frontier-economy | Claude Haiku 4.5, small-model tier | $1.25 | $5.00 | | Open-hosted | Llama 3.1 70B / Qwen 2.5 72B via Together, Fireworks, OpenRouter | $0.50 | $1.50 | | Open-economy | 8B-13B-class hosted | $0.10 | $0.30 | @@ -126,7 +126,7 @@ If your utilization is 30% instead of 70%, your effective cost per token roughly ### 2. Capability Drift - Provider updates models silently or with brief notice - Your prompts may produce different outputs after upgrade -- Mitigation: pin model IDs (e.g., `claude-sonnet-4-6` vs `claude-sonnet-latest`) +- Mitigation: pin model IDs (e.g., `claude-sonnet-5` vs `claude-sonnet-latest`) - Cost: regression eval runs on every model swap ### 3. Rate Limits diff --git a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py index 04141cef..cb18922f 100644 --- a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py +++ b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py @@ -48,8 +48,8 @@ SAMPLE: Dict[str, Any] = { # 2026 API pricing per million tokens, $USD (input / output) API_PRICING = { - "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 4.6 / GPT-4o-tier"}, - "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Gemini 2.5 Flash / Claude Haiku 4.5-tier"}, + "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 5 / frontier-mid tier"}, + "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Claude Haiku 4.5 / small-model tier"}, "open-hosted": {"input": 0.50, "output": 1.50, "label": "Llama 3.1 70B / Qwen 2.5 72B via hosted endpoint"}, } diff --git a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py index da0d537f..2b1f4c03 100644 --- a/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py +++ b/c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py @@ -54,8 +54,8 @@ SAMPLE: Dict[str, Any] = { # 2026 API pricing per million tokens, $USD (input / output). These are illustrative; # real pricing changes; rerun this calculator quarterly. API_PRICING = { - "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 4.6 / GPT-4o-tier"}, - "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Gemini 2.5 Flash / Claude Haiku 4.5-tier"}, + "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 5 / frontier-mid tier"}, + "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Claude Haiku 4.5 / small-model tier"}, "open-router-hosted": {"input": 0.50, "output": 1.50, "label": "Llama 3.1 70B / Qwen 2.5 72B via hosted endpoint"}, } diff --git a/c-level-advisor/executive-mentor/agents/devils-advocate.md b/c-level-advisor/executive-mentor/agents/devils-advocate.md index 8b7fe872..5379ee36 100644 --- a/c-level-advisor/executive-mentor/agents/devils-advocate.md +++ b/c-level-advisor/executive-mentor/agents/devils-advocate.md @@ -1,3 +1,8 @@ +--- +name: devils-advocate +description: "Adversarial reviewer for executive plans, proposals, and decisions. Returns exactly three specific concerns, each severity-rated CRITICAL / HIGH / MEDIUM, with the evidence that would confirm or kill it. Use before committing resources to a plan, before a board or investor presentation, or when feedback so far has been one-sidedly positive. Not a code reviewer." +--- + # Devil's Advocate Agent **Role:** Adversarial thinker. Finds what's wrong before others do. diff --git a/c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/SKILL.md b/c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/SKILL.md index 1d1cef3d..2ae12eec 100644 --- a/c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/SKILL.md +++ b/c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/SKILL.md @@ -146,7 +146,7 @@ See `references/ip_and_regulatory.md` for sequencing. - `c-level-advisor/skills/cfo-advisor/` — Term sheet → dilution math - `c-level-advisor/skills/ma-playbook/` — Acquisition agreements, integration playbooks - `ra-qm-team/` — ISO 13485, MDR, FDA 510(k), GDPR execution -- `c-level-advisor/c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command +- `c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command ## References diff --git a/c-level-advisor/skills/c-level-skills/SKILL.md b/c-level-advisor/skills/c-level-skills/SKILL.md index 7e40a382..14acba02 100644 --- a/c-level-advisor/skills/c-level-skills/SKILL.md +++ b/c-level-advisor/skills/c-level-skills/SKILL.md @@ -42,6 +42,6 @@ Full matrix in `../chief-of-staff/SKILL.md` and `../chief-of-staff/references/ro ## Related Layers -- `../../c-level-agents/` — 13 cs-* persona agents + 21 `/cs:*` slash commands on top of these skills +- `../../../c-level-agents/` — 13 cs-* persona agents + 21 `/cs:*` slash commands on top of these skills - `../../executive-mentor/` — adversarial `/em:*` critic commands - `../../CLAUDE.md` — full architecture diagram and integration guide diff --git a/c-level-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md b/c-level-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md index 17ff8463..8c723d80 100644 --- a/c-level-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md +++ b/c-level-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md @@ -18,8 +18,8 @@ Per million tokens, USD: | Tier | Example models | Input | Output | |---|---|---|---| -| Frontier-premium | Claude Sonnet 4.6, GPT-4o-tier | $3.00 | $15.00 | -| Frontier-economy | Gemini 2.5 Flash, Claude Haiku 4.5-tier | $1.25 | $5.00 | +| Frontier-premium | Claude Sonnet 5, frontier-mid tier | $3.00 | $15.00 | +| Frontier-economy | Claude Haiku 4.5, small-model tier | $1.25 | $5.00 | | Open-hosted | Llama 3.1 70B / Qwen 2.5 72B via Together, Fireworks, OpenRouter | $0.50 | $1.50 | | Open-economy | 8B-13B-class hosted | $0.10 | $0.30 | @@ -126,7 +126,7 @@ If your utilization is 30% instead of 70%, your effective cost per token roughly ### 2. Capability Drift - Provider updates models silently or with brief notice - Your prompts may produce different outputs after upgrade -- Mitigation: pin model IDs (e.g., `claude-sonnet-4-6` vs `claude-sonnet-latest`) +- Mitigation: pin model IDs (e.g., `claude-sonnet-5` vs `claude-sonnet-latest`) - Cost: regression eval runs on every model swap ### 3. Rate Limits diff --git a/c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py b/c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py index 04141cef..cb18922f 100644 --- a/c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py +++ b/c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py @@ -48,8 +48,8 @@ SAMPLE: Dict[str, Any] = { # 2026 API pricing per million tokens, $USD (input / output) API_PRICING = { - "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 4.6 / GPT-4o-tier"}, - "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Gemini 2.5 Flash / Claude Haiku 4.5-tier"}, + "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 5 / frontier-mid tier"}, + "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Claude Haiku 4.5 / small-model tier"}, "open-hosted": {"input": 0.50, "output": 1.50, "label": "Llama 3.1 70B / Qwen 2.5 72B via hosted endpoint"}, } diff --git a/c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py b/c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py index da0d537f..2b1f4c03 100644 --- a/c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py +++ b/c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py @@ -54,8 +54,8 @@ SAMPLE: Dict[str, Any] = { # 2026 API pricing per million tokens, $USD (input / output). These are illustrative; # real pricing changes; rerun this calculator quarterly. API_PRICING = { - "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 4.6 / GPT-4o-tier"}, - "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Gemini 2.5 Flash / Claude Haiku 4.5-tier"}, + "frontier-premium": {"input": 3.00, "output": 15.00, "label": "Claude Sonnet 5 / frontier-mid tier"}, + "frontier-economy": {"input": 1.25, "output": 5.00, "label": "Claude Haiku 4.5 / small-model tier"}, "open-router-hosted": {"input": 0.50, "output": 1.50, "label": "Llama 3.1 70B / Qwen 2.5 72B via hosted endpoint"}, } diff --git a/c-level-advisor/skills/general-counsel-advisor/SKILL.md b/c-level-advisor/skills/general-counsel-advisor/SKILL.md index 1d1cef3d..2ae12eec 100644 --- a/c-level-advisor/skills/general-counsel-advisor/SKILL.md +++ b/c-level-advisor/skills/general-counsel-advisor/SKILL.md @@ -146,7 +146,7 @@ See `references/ip_and_regulatory.md` for sequencing. - `c-level-advisor/skills/cfo-advisor/` — Term sheet → dilution math - `c-level-advisor/skills/ma-playbook/` — Acquisition agreements, integration playbooks - `ra-qm-team/` — ISO 13485, MDR, FDA 510(k), GDPR execution -- `c-level-advisor/c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command +- `c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command ## References diff --git a/c-level-advisor/c-level-agents/.claude-plugin/plugin.json b/c-level-agents/.claude-plugin/plugin.json similarity index 95% rename from c-level-advisor/c-level-agents/.claude-plugin/plugin.json rename to c-level-agents/.claude-plugin/plugin.json index f65885bc..c23ffc78 100644 --- a/c-level-advisor/c-level-agents/.claude-plugin/plugin.json +++ b/c-level-agents/.claude-plugin/plugin.json @@ -6,7 +6,7 @@ "name": "Alireza Rezvani", "url": "https://alirezarezvani.com" }, - "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents", + "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents", "repository": "https://github.com/alirezarezvani/claude-skills", "license": "MIT", "skills": [ diff --git a/c-level-advisor/c-level-agents/README.md b/c-level-agents/README.md similarity index 96% rename from c-level-advisor/c-level-agents/README.md rename to c-level-agents/README.md index de0cd987..03631af6 100644 --- a/c-level-advisor/c-level-agents/README.md +++ b/c-level-agents/README.md @@ -66,8 +66,8 @@ Existing `cs-ceo-advisor` and `cs-cto-advisor` live in `/agents/c-level/` and in - [persona-voices.md](references/persona-voices.md) — voice spec for each role - [llm-wiki-bridge.md](references/llm-wiki-bridge.md) — point company-context at an llm-wiki vault -- [Parent CLAUDE.md](../CLAUDE.md) — c-level domain guide -- [executive-mentor sibling](../executive-mentor/) — `/em:*` adversarial commands +- [c-level domain CLAUDE.md](../c-level-advisor/CLAUDE.md) — c-level domain guide +- [executive-mentor sibling](../c-level-advisor/executive-mentor/) — `/em:*` adversarial commands ## What's Different vs `gstack` diff --git a/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md b/c-level-agents/agents/cs-caio-advisor.md similarity index 75% rename from c-level-advisor/c-level-agents/agents/cs-caio-advisor.md rename to c-level-agents/agents/cs-caio-advisor.md index 7a0cc9be..e9ba359d 100644 --- a/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md +++ b/c-level-agents/agents/cs-caio-advisor.md @@ -32,32 +32,32 @@ Differentiates from `cs-cdo-advisor` (data strategy, training rights), `cs-cto-a ## Skill Integration -**Skill Location:** `../../skills/chief-ai-officer-advisor/` +**Skill Location:** `../../c-level-advisor/skills/chief-ai-officer-advisor/` ### Python Tools 1. **Model Build-vs-Buy Calculator** - - Path: `../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py` - - Usage: `python ../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json` + - Path: `../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py` + - Usage: `python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json` - Returns: API / FINE_TUNE / BUILD recommendation, 3-year TCO across all 3 paths + open-hosted variant, breakeven analysis, failure modes per chosen path - Deterministic: balances economic breakeven with practical feasibility (data availability, ML team capacity, compliance constraints) 2. **AI Risk Classifier** - - Path: `../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py` - - Usage: `python ../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json` + - Path: `../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py` + - Usage: `python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json` - Returns: EU AI Act tier (PROHIBITED/HIGH/LIMITED/MINIMAL) with citations, US state triggers (NYC LL 144, CO AI Act, IL HB 53, CA SB 1001, IL BIPA), industry overlays (FDA, NYDFS, NAIC, ECOA), required controls list, conformity assessment flag 3. **AI Cost Economics** - - Path: `../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py` - - Usage: `python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json` + - Path: `../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py` + - Usage: `python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json` - Returns: API costs at 3 tiers, self-hosted costs at low/mid/high GPU rates with 24/7 warm + ops attribution, breakeven monthly tokens, API/SELF_HOSTED/HYBRID recommendation with caveats ### Knowledge Bases -- `../../skills/chief-ai-officer-advisor/references/model_buildvsbuy_strategy.md` — Full decision tree + 3 paths with failure modes + fine-tuning approaches table (RAG / LoRA / full FT / RLHF / DPO / continued pre-training) + when each fails -- `../../skills/chief-ai-officer-advisor/references/ai_risk_governance.md` — EU AI Act full risk-tier map + NIST AI RMF + US state patchwork + industry overlays (FDA, financial, insurance) + governance program checklist -- `../../skills/chief-ai-officer-advisor/references/ai_cost_economics.md` — 2026 API pricing + GPU rental economics + utilization reality + hidden costs (ops, monitoring, model updates, capacity, failover, security) + migration cost + prompt caching as economics lever -- `../../skills/chief-ai-officer-advisor/references/ai_team_org_evolution.md` — 5-stage role map + 9-role definition table + AI team vs data team contrast + 7 anti-patterns +- `../../c-level-advisor/skills/chief-ai-officer-advisor/references/model_buildvsbuy_strategy.md` — Full decision tree + 3 paths with failure modes + fine-tuning approaches table (RAG / LoRA / full FT / RLHF / DPO / continued pre-training) + when each fails +- `../../c-level-advisor/skills/chief-ai-officer-advisor/references/ai_risk_governance.md` — EU AI Act full risk-tier map + NIST AI RMF + US state patchwork + industry overlays (FDA, financial, insurance) + governance program checklist +- `../../c-level-advisor/skills/chief-ai-officer-advisor/references/ai_cost_economics.md` — 2026 API pricing + GPU rental economics + utilization reality + hidden costs (ops, monitoring, model updates, capacity, failover, security) + migration cost + prompt caching as economics lever +- `../../c-level-advisor/skills/chief-ai-officer-advisor/references/ai_team_org_evolution.md` — 5-stage role map + 9-role definition table + AI team vs data team contrast + 7 anti-patterns ## Workflows @@ -67,7 +67,7 @@ Differentiates from `cs-cdo-advisor` (data strategy, training rights), `cs-cto-a ```bash # 1. Define use_case.json with: volume, latency budget, accuracy required, domain-specific?, # data for fine-tune available?, ML team capacity, compliance constraints -python ../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json # 2. Review 3-year TCO + breakeven analysis # 3. Cross-check with cs-cfo-advisor on budget commitment (multi-year vendor / GPU) # 4. Cross-check with cs-cto-advisor on engineering capacity (esp. for fine-tune) @@ -81,7 +81,7 @@ python ../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator ```bash # 1. Define use_case.json with: domain, geography (EU? states?), automation level, biometric?, # consequential decisions?, user-facing? -python ../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json # 2. For PROHIBITED: scope out EU OR redesign # 3. For HIGH: budget conformity assessment ($50-200K + 3-12 months) + register in EU DB # 4. For LIMITED: implement transparency requirements before launch @@ -95,7 +95,7 @@ python ../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_c ```bash # 1. Build workload.json: monthly tokens, quality tier, model size, latency target, utilization -python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json # 2. Review monthly cost comparison + breakeven analysis + sensitivity to GPU rates # 3. Estimate migration cost (3-6 months, 2-3 engineers = $150-300K) # 4. Cross-check with cs-cfo-advisor on capex commitment + reserved GPU pricing @@ -130,13 +130,13 @@ python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py worklo # AI feature pre-launch gate — must pass all three before deployment # 1. Model selection sanity check -python ../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json # 2. Regulatory classification + controls -python ../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json # 3. Cost projection at expected scale -python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json +python ../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json # Required before ship: # ☐ Recommendation logged via /cs:decide @@ -158,7 +158,7 @@ python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py worklo ## Related Agents - [cs-cdo-advisor](cs-cdo-advisor.md) — Training data rights, data strategy (chains directly to model decisions) -- [cs-cto-advisor](../../../agents/c-level/cs-cto-advisor.md) — Architecture capacity, scaling cliffs +- [cs-cto-advisor](../../agents/c-level/cs-cto-advisor.md) — Architecture capacity, scaling cliffs - [cs-ciso-advisor](cs-ciso-advisor.md) — Threat modeling for AI (prompt injection, jailbreak, training-data poisoning) - [cs-general-counsel-advisor](cs-general-counsel-advisor.md) — AI contracts, vendor liability, output ownership - [cs-cfo-advisor](cs-cfo-advisor.md) — Build-vs-buy TCO, multi-year vendor commitments @@ -166,7 +166,7 @@ python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py worklo ## References -- Skill: [../../skills/chief-ai-officer-advisor/SKILL.md](../../skills/chief-ai-officer-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/chief-ai-officer-advisor/SKILL.md](../../c-level-advisor/skills/chief-ai-officer-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Sibling command: [`/cs:caio-review`](../skills/caio-review/SKILL.md) diff --git a/c-level-advisor/c-level-agents/agents/cs-cco-advisor.md b/c-level-agents/agents/cs-cco-advisor.md similarity index 72% rename from c-level-advisor/c-level-agents/agents/cs-cco-advisor.md rename to c-level-agents/agents/cs-cco-advisor.md index 7971f5fc..77683563 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cco-advisor.md +++ b/c-level-agents/agents/cs-cco-advisor.md @@ -35,31 +35,31 @@ Differentiates from: ## Skill Integration -**Skill Location:** `../../skills/chief-customer-officer-advisor/` +**Skill Location:** `../../c-level-advisor/skills/chief-customer-officer-advisor/` ### Python Tools 1. **Retention Decomposition Analyzer** - - Path: `../../skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py` - - Usage: `python ../../skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json` + - Path: `../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py` + - Usage: `python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json` - Decomposes ARR retention by cohort (GRR / NRR / Logo separately), flags leaky-bucket pattern (NRR healthy + GRR poor), categorizes churn into 7-category root-cause taxonomy with preventable % 2. **Customer Segmentation Designer** - - Path: `../../skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py` - - Usage: `python ../../skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json` + - Path: `../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py` + - Usage: `python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json` - Assigns tier (Strategic / Enterprise / Mid-market / SMB-long-tail), scores ICP fit 0-10 across 7 weighted signals, identifies kill list (support cost > 50% of ARR + low fit), surfaces upgrade candidates 3. **CS Coverage Calculator** - - Path: `../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py` - - Usage: `python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json` + - Path: `../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py` + - Usage: `python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json` - Calculates required CSM headcount per tier (ARR ratio + account count, whichever is binding), surfaces manager-trigger thresholds, generates 12-month hiring plan with quarterly sequencing ### Knowledge Bases -- `../../skills/chief-customer-officer-advisor/references/retention_decomposition.md` — GRR vs NRR honest math + leaky-bucket pattern + 7-category churn taxonomy + leading-indicator playbook + cohort discipline -- `../../skills/chief-customer-officer-advisor/references/customer_segmentation_strategy.md` — 4-tier framework + ICP fit weighting (7 signals) + tier transition triggers + kill list criteria + the 3 paths for kill candidates -- `../../skills/chief-customer-officer-advisor/references/cs_coverage_model.md` — Tech-touch / pooled / named / named+exec models + ARR-per-CSM ratios by stage and segment + manager-trigger criteria + CS comp design + ramp curves -- `../../skills/chief-customer-officer-advisor/references/cs_team_org_evolution.md` — 5-stage role map + 6-role definition table (CSM ≠ Support ≠ AM ≠ IM ≠ CS Ops ≠ Customer Marketing) + AM-vs-CSM split decision + 7 anti-patterns +- `../../c-level-advisor/skills/chief-customer-officer-advisor/references/retention_decomposition.md` — GRR vs NRR honest math + leaky-bucket pattern + 7-category churn taxonomy + leading-indicator playbook + cohort discipline +- `../../c-level-advisor/skills/chief-customer-officer-advisor/references/customer_segmentation_strategy.md` — 4-tier framework + ICP fit weighting (7 signals) + tier transition triggers + kill list criteria + the 3 paths for kill candidates +- `../../c-level-advisor/skills/chief-customer-officer-advisor/references/cs_coverage_model.md` — Tech-touch / pooled / named / named+exec models + ARR-per-CSM ratios by stage and segment + manager-trigger criteria + CS comp design + ramp curves +- `../../c-level-advisor/skills/chief-customer-officer-advisor/references/cs_team_org_evolution.md` — 5-stage role map + 6-role definition table (CSM ≠ Support ≠ AM ≠ IM ≠ CS Ops ≠ Customer Marketing) + AM-vs-CSM split decision + 7 anti-patterns ## Workflows @@ -68,7 +68,7 @@ Differentiates from: ```bash # 1. Pull cohort data (closed/won by quarter for last 8 quarters) -python ../../skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json # 2. Identify any leaky-bucket cohort (NRR > 100% AND GRR < 85%) # 3. For each cohort with poor GRR: identify churn root cause from 7-category taxonomy # 4. Cross-check expansion math with cs-cro-advisor @@ -82,7 +82,7 @@ python ../../skills/chief-customer-officer-advisor/scripts/retention_decompositi ```bash # 1. Build customers.json with ARR, tenure, ICP fit signals -python ../../skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json # 2. Review tier distribution (% of customers AND % of ARR per tier) # 3. Surface kill list (customers where support cost > 50% of ARR AND ICP fit < 5) # 4. Surface upgrade candidates (high ICP fit + expansion potential) @@ -95,7 +95,7 @@ python ../../skills/chief-customer-officer-advisor/scripts/customer_segmentation ```bash # 1. Build book.json with current book composition + growth_target_pct -python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json # 2. Identify gap now + gap in 12mo across all 4 tiers # 3. Review manager-trigger thresholds (CS manager needed if any tier has 5+ CSMs) # 4. Cross-check 12mo cost with cs-cfo-advisor @@ -129,13 +129,13 @@ python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculato # Quarterly CCO brief — must run before every board meeting # 1. Retention decomposition (honest GRR vs NRR) -python ../../skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py current-cohorts.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py current-cohorts.json # 2. Segmentation health (tier distribution + kill/upgrade lists) -python ../../skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py current-customers.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py current-customers.json # 3. Team sizing (does the CS team match the book?) -python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py current-book.json +python ../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py current-book.json # Board narrative requires: # - GRR truth (not just NRR) @@ -160,11 +160,11 @@ python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculato - [cs-cmo-advisor](cs-cmo-advisor.md) — Customer marketing, advocacy, references - [cs-cfo-advisor](cs-cfo-advisor.md) — CS team cost, retention-impact-on-revenue - [cs-chro-advisor](cs-chro-advisor.md) — CS team hiring + leveling + comp -- [cs-growth-strategist](../../../agents/business-growth/cs-growth-strategist.md) — Tactical CS execution +- [cs-growth-strategist](../../agents/business-growth/cs-growth-strategist.md) — Tactical CS execution ## References -- Skill: [../../skills/chief-customer-officer-advisor/SKILL.md](../../skills/chief-customer-officer-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/chief-customer-officer-advisor/SKILL.md](../../c-level-advisor/skills/chief-customer-officer-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Sibling command: [`/cs:cco-review`](../skills/cco-review/SKILL.md) diff --git a/c-level-advisor/c-level-agents/agents/cs-cdo-advisor.md b/c-level-agents/agents/cs-cdo-advisor.md similarity index 71% rename from c-level-advisor/c-level-agents/agents/cs-cdo-advisor.md rename to c-level-agents/agents/cs-cdo-advisor.md index 0ce1b0ce..b2a52b70 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cdo-advisor.md +++ b/c-level-agents/agents/cs-cdo-advisor.md @@ -32,31 +32,31 @@ Differentiates from `cs-cto-advisor` (architecture), `cs-ciso-advisor` (security ## Skill Integration -**Skill Location:** `../../skills/chief-data-officer-advisor/` +**Skill Location:** `../../c-level-advisor/skills/chief-data-officer-advisor/` ### Python Tools 1. **AI Training Data Audit** - - Path: `../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py` - - Usage: `python ../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json` + - Path: `../../c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py` + - Usage: `python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json` - Audits data sources on 3 dimensions (origin × class × use case), returns GO/MITIGATE/NO-GO per source with risk + remediation + GDPR/AI Act citations 2. **Data Product Strategy Picker** - - Path: `../../skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py` - - Usage: `python ../../skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json` + - Path: `../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py` + - Usage: `python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json` - Picks warehouse/lakehouse/mesh + build-vs-buy per layer + 12-month sequencing roadmap. Deterministic, derived from profile. 3. **Data Asset Valuator** - - Path: `../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py` - - Usage: `python ../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json` + - Path: `../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py` + - Usage: `python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json` - Computes strategic value (0-10), moat strength, M&A multiplier (with carve-out penalties), and ranks 3 productization paths ### Knowledge Bases -- `../../skills/chief-data-officer-advisor/references/ai_training_data_rights.md` — Training rights matrix + GDPR Art. 6 + EU AI Act + US state patchwork -- `../../skills/chief-data-officer-advisor/references/data_product_strategy.md` — Architecture kill criteria + build-vs-buy decision tree + sequencing pattern -- `../../skills/chief-data-officer-advisor/references/customer_data_as_asset.md` — Valuation framework + 3 productization paths + M&A diligence prep checklist + contractual constraint audit -- `../../skills/chief-data-officer-advisor/references/data_team_org_evolution.md` — Stage-to-role map + centralize-vs-embed trigger + anti-patterns +- `../../c-level-advisor/skills/chief-data-officer-advisor/references/ai_training_data_rights.md` — Training rights matrix + GDPR Art. 6 + EU AI Act + US state patchwork +- `../../c-level-advisor/skills/chief-data-officer-advisor/references/data_product_strategy.md` — Architecture kill criteria + build-vs-buy decision tree + sequencing pattern +- `../../c-level-advisor/skills/chief-data-officer-advisor/references/customer_data_as_asset.md` — Valuation framework + 3 productization paths + M&A diligence prep checklist + contractual constraint audit +- `../../c-level-advisor/skills/chief-data-officer-advisor/references/data_team_org_evolution.md` — Stage-to-role map + centralize-vs-embed trigger + anti-patterns ## Workflows @@ -66,7 +66,7 @@ Differentiates from `cs-cto-advisor` (architecture), `cs-ciso-advisor` (security ```bash # 1. Build sources.json (one entry per source, tagged with origin × class × use case) # 2. Run the audit -python ../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json # 3. For each NO-GO: document the kill reason; either drop the source or change the use case # 4. For each MITIGATE: assign owner + remediation; block training until complete # 5. Cross-check top-3 mitigations with cs-general-counsel-advisor @@ -79,7 +79,7 @@ python ../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py ```bash # 1. Build profile.json (stage, consumers, volume, ML models, culture, priorities) # 2. Run the picker -python ../../skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json # 3. Cross-check architecture choice with cs-cto-advisor (engineering capacity) # 4. Cross-check 3-year TCO with cs-cfo-advisor # 5. Identify kill criteria explicitly; commit to revisiting in Q4 @@ -92,7 +92,7 @@ python ../../skills/chief-data-officer-advisor/scripts/data_product_strategy_pic ```bash # 1. Inventory corpus (customers, history, exclusivity, carve-outs, regulated content) # 2. Run the valuator -python ../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json # 3. Run the M&A diligence checklist in customer_data_as_asset.md # 4. Surface contractual carve-outs to cs-general-counsel-advisor # 5. Decide productization path (benchmark → embedding → license, in viability order) @@ -104,7 +104,7 @@ python ../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py co **Goal:** Sequence the next 18 months of data hires aligned to business decisions. 1. List top 5 decisions the business can't make today due to missing data/analysis -2. Map each decision to the role that unblocks it (see ../../skills/chief-data-officer-advisor/references/data_team_org_evolution.md) +2. Map each decision to the role that unblocks it (see ../../c-level-advisor/skills/chief-data-officer-advisor/references/data_team_org_evolution.md) 3. Sequence hires (one at a time, ramp before next) 4. Cross-check with cs-chro-advisor on comp bands + leveling 5. Identify centralize-vs-embed trigger date @@ -125,11 +125,11 @@ python ../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py co #!/bin/bash echo "📊 CDO Quarterly Review" echo "1. Training data audit" -python ../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py current-sources.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py current-sources.json echo "2. Architecture review" -python ../../skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py current-profile.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py current-profile.json echo "3. Data asset valuation" -python ../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json +python ../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json echo "Kill criteria + checkpoint dates in each output." ``` @@ -144,7 +144,7 @@ echo "Kill criteria + checkpoint dates in each output." ## Related Agents -- [cs-cto-advisor](../../../agents/c-level/cs-cto-advisor.md) — architecture capacity +- [cs-cto-advisor](../../agents/c-level/cs-cto-advisor.md) — architecture capacity - [cs-ciso-advisor](cs-ciso-advisor.md) — data security, threat modeling for productized data - [cs-cpo-advisor](cs-cpo-advisor.md) — product strategy (when data becomes product) - [cs-general-counsel-advisor](cs-general-counsel-advisor.md) — contractual constraints, DPA, training-rights @@ -153,7 +153,7 @@ echo "Kill criteria + checkpoint dates in each output." ## References -- Skill: [../../skills/chief-data-officer-advisor/SKILL.md](../../skills/chief-data-officer-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/chief-data-officer-advisor/SKILL.md](../../c-level-advisor/skills/chief-data-officer-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Sibling command: [`/cs:cdo-review`](../skills/cdo-review/SKILL.md) diff --git a/c-level-advisor/c-level-agents/agents/cs-cfo-advisor.md b/c-level-agents/agents/cs-cfo-advisor.md similarity index 70% rename from c-level-advisor/c-level-agents/agents/cs-cfo-advisor.md rename to c-level-agents/agents/cs-cfo-advisor.md index d5953347..d8da1db9 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cfo-advisor.md +++ b/c-level-agents/agents/cs-cfo-advisor.md @@ -25,30 +25,30 @@ It pairs with `cs-ceo-advisor` (strategy → capital allocation), `cs-cro-adviso ## Skill Integration -**Skill Location:** `../../skills/cfo-advisor/` +**Skill Location:** `../../c-level-advisor/skills/cfo-advisor/` ### Python Tools 1. **Burn Rate Calculator** - - Path: `../../skills/cfo-advisor/scripts/burn_rate_calculator.py` - - Usage: `python ../../skills/cfo-advisor/scripts/burn_rate_calculator.py` + - Path: `../../c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py` + - Usage: `python ../../c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py` - Outputs base/bull/bear runway scenarios, months-of-cash, default-alive vs default-dead status 2. **Unit Economics Analyzer** - - Path: `../../skills/cfo-advisor/scripts/unit_economics_analyzer.py` - - Usage: `python ../../skills/cfo-advisor/scripts/unit_economics_analyzer.py` + - Path: `../../c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py` + - Usage: `python ../../c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py` - Per-cohort LTV, per-channel CAC, payback months, gross margin breakdown 3. **Fundraising Model** - - Path: `../../skills/cfo-advisor/scripts/fundraising_model.py` - - Usage: `python ../../skills/cfo-advisor/scripts/fundraising_model.py` + - Path: `../../c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py` + - Usage: `python ../../c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py` - Dilution modeling, cap table projections, round sensitivity, valuation negotiation ranges ### Knowledge Bases -- `../../skills/cfo-advisor/references/financial_planning.md` — modeling, FP&A cadence, scenario design -- `../../skills/cfo-advisor/references/fundraising_playbook.md` — round preparation, term sheet decoding, investor outreach -- `../../skills/cfo-advisor/references/cash_management.md` — treasury, working capital, AR/AP discipline +- `../../c-level-advisor/skills/cfo-advisor/references/financial_planning.md` — modeling, FP&A cadence, scenario design +- `../../c-level-advisor/skills/cfo-advisor/references/fundraising_playbook.md` — round preparation, term sheet decoding, investor outreach +- `../../c-level-advisor/skills/cfo-advisor/references/cash_management.md` — treasury, working capital, AR/AP discipline ## Workflows @@ -62,7 +62,7 @@ It pairs with `cs-ceo-advisor` (strategy → capital allocation), `cs-cro-adviso 4. Output: revised plan with cut triggers at month -6, -3 from zero ```bash -python ../../skills/cfo-advisor/scripts/burn_rate_calculator.py > runway.txt +python ../../c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py > runway.txt ``` ### Workflow 2: Unit Economics Decomposition @@ -98,9 +98,9 @@ python ../../skills/cfo-advisor/scripts/burn_rate_calculator.py > runway.txt ```bash #!/bin/bash echo "📊 CFO Pre-Boardroom Brief" -python ../../skills/cfo-advisor/scripts/burn_rate_calculator.py > /tmp/burn.txt -python ../../skills/cfo-advisor/scripts/unit_economics_analyzer.py > /tmp/ue.txt -python ../../skills/cfo-advisor/scripts/fundraising_model.py > /tmp/fund.txt +python ../../c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py > /tmp/burn.txt +python ../../c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py > /tmp/ue.txt +python ../../c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py > /tmp/fund.txt echo "Artifacts ready in /tmp/. Feed into /cs:boardroom brief." ``` @@ -114,14 +114,14 @@ echo "Artifacts ready in /tmp/. Feed into /cs:boardroom brief." ## Related Agents -- [cs-ceo-advisor](../../../agents/c-level/cs-ceo-advisor.md) — strategy & capital allocation partner +- [cs-ceo-advisor](../../agents/c-level/cs-ceo-advisor.md) — strategy & capital allocation partner - [cs-cro-advisor](cs-cro-advisor.md) — revenue forecast feed -- [cs-financial-analyst](../../../agents/finance/cs-financial-analyst.md) — deep modeling +- [cs-financial-analyst](../../agents/finance/cs-financial-analyst.md) — deep modeling - [cs-chief-of-staff](cs-chief-of-staff.md) — routes financial questions here ## References -- Skill: [../../skills/cfo-advisor/SKILL.md](../../skills/cfo-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/cfo-advisor/SKILL.md](../../c-level-advisor/skills/cfo-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Domain guide: [../../CLAUDE.md](../../CLAUDE.md) diff --git a/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md b/c-level-agents/agents/cs-chief-of-staff.md similarity index 78% rename from c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md rename to c-level-agents/agents/cs-chief-of-staff.md index 3149fc62..94a17434 100644 --- a/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md +++ b/c-level-agents/agents/cs-chief-of-staff.md @@ -25,19 +25,19 @@ This is the agent the founder talks to **first**. It pulls company-context.md, p ## Skill Integration -**Skill Location:** `../../skills/chief-of-staff/` +**Skill Location:** `../../c-level-advisor/skills/chief-of-staff/` ### Knowledge Bases -- `../../skills/chief-of-staff/references/routing-matrix.md` — keywords → role mapping, multi-role triggers -- `../../skills/chief-of-staff/references/synthesis-framework.md` — how to combine inputs from multiple advisors +- `../../c-level-advisor/skills/chief-of-staff/references/routing-matrix.md` — keywords → role mapping, multi-role triggers +- `../../c-level-advisor/skills/chief-of-staff/references/synthesis-framework.md` — how to combine inputs from multiple advisors ### Coordination Skills -- `../../skills/board-meeting/` — 6-phase deliberation protocol with Phase 2 isolation -- `../../skills/decision-logger/` — two-layer memory (raw transcripts + approved decisions) -- `../../skills/context-engine/` — company-context loading + anonymization -- `../../skills/agent-protocol/` — inter-agent invocation, loop prevention, quality loop +- `../../c-level-advisor/skills/board-meeting/` — 6-phase deliberation protocol with Phase 2 isolation +- `../../c-level-advisor/skills/decision-logger/` — two-layer memory (raw transcripts + approved decisions) +- `../../c-level-advisor/skills/context-engine/` — company-context loading + anonymization +- `../../c-level-advisor/skills/agent-protocol/` — inter-agent invocation, loop prevention, quality loop ## Workflows @@ -119,14 +119,14 @@ echo "Decision logged to ~/.claude/decisions/raw/$(date +%Y-%m-%d)-$RANDOM.md" ## Related Agents - All cs-* C-level advisors (routes to them) -- [cs-ceo-advisor](../../../agents/c-level/cs-ceo-advisor.md) — primary upward report -- [executive-mentor / devils-advocate](../../executive-mentor/agents/devils-advocate.md) — pre-decision adversarial check +- [cs-ceo-advisor](../../agents/c-level/cs-ceo-advisor.md) — primary upward report +- [executive-mentor / devils-advocate](../../c-level-advisor/executive-mentor/agents/devils-advocate.md) — pre-decision adversarial check ## References -- Skill: [../../skills/chief-of-staff/SKILL.md](../../skills/chief-of-staff/SKILL.md) +- Skill: [../../c-level-advisor/skills/chief-of-staff/SKILL.md](../../c-level-advisor/skills/chief-of-staff/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) -- Decision-logger: [../../skills/decision-logger/SKILL.md](../../skills/decision-logger/SKILL.md) +- Decision-logger: [../../c-level-advisor/skills/decision-logger/SKILL.md](../../c-level-advisor/skills/decision-logger/SKILL.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-chro-advisor.md b/c-level-agents/agents/cs-chro-advisor.md similarity index 74% rename from c-level-advisor/c-level-agents/agents/cs-chro-advisor.md rename to c-level-agents/agents/cs-chro-advisor.md index 0776beb4..2f4f6e4c 100644 --- a/c-level-advisor/c-level-agents/agents/cs-chro-advisor.md +++ b/c-level-agents/agents/cs-chro-advisor.md @@ -25,23 +25,23 @@ Pairs with `cs-coo-advisor` (org design), `cs-cfo-advisor` (comp budget), and `c ## Skill Integration -**Skill Location:** `../../skills/chro-advisor/` +**Skill Location:** `../../c-level-advisor/skills/chro-advisor/` ### Python Tools 1. **Hiring Plan Modeler** - - Path: `../../skills/chro-advisor/scripts/hiring_plan_modeler.py` + - Path: `../../c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py` - Headcount plan by quarter, ramp-adjusted productivity, hiring funnel sensitivity 2. **Comp Benchmarker** - - Path: `../../skills/chro-advisor/scripts/comp_benchmarker.py` + - Path: `../../c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py` - Stage-and-geo comp bands, equity refresh design, total-rewards composition ### Knowledge Bases -- `../../skills/chro-advisor/references/people_strategy.md` — sourcing channels, interview rubrics, scorecards, time-to-fill -- `../../skills/chro-advisor/references/comp_frameworks.md` — band design, equity strategy, refresh policy -- `../../skills/chro-advisor/references/org_design.md` — IC + manager tracks, level expectations, promotion criteria +- `../../c-level-advisor/skills/chro-advisor/references/people_strategy.md` — sourcing channels, interview rubrics, scorecards, time-to-fill +- `../../c-level-advisor/skills/chro-advisor/references/comp_frameworks.md` — band design, equity strategy, refresh policy +- `../../c-level-advisor/skills/chro-advisor/references/org_design.md` — IC + manager tracks, level expectations, promotion criteria ## Workflows @@ -55,7 +55,7 @@ Pairs with `cs-coo-advisor` (org design), `cs-cfo-advisor` (comp budget), and `c 4. Output: hiring plan with scorecards, time-to-productivity per role, kill candidates ```bash -python ../../skills/chro-advisor/scripts/hiring_plan_modeler.py +python ../../c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py ``` ### Workflow 2: Comp Band Audit @@ -90,9 +90,9 @@ python ../../skills/chro-advisor/scripts/hiring_plan_modeler.py ```bash echo "👥 CHRO Quarterly Review" -python ../../skills/chro-advisor/scripts/hiring_plan_modeler.py -python ../../skills/chro-advisor/scripts/comp_benchmarker.py -echo "Ladder reference: ../../skills/chro-advisor/references/org_design.md" +python ../../c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py +python ../../c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py +echo "Ladder reference: ../../c-level-advisor/skills/chro-advisor/references/org_design.md" ``` ## Success Metrics @@ -107,12 +107,12 @@ echo "Ladder reference: ../../skills/chro-advisor/references/org_design.md" - [cs-coo-advisor](cs-coo-advisor.md) — org design partner - [cs-cfo-advisor](cs-cfo-advisor.md) — comp budget -- [cs-ceo-advisor](../../../agents/c-level/cs-ceo-advisor.md) — exec team -- [cs-workspace-admin](../../../agents/engineering-team/cs-workspace-admin.md) — onboarding tooling +- [cs-ceo-advisor](../../agents/c-level/cs-ceo-advisor.md) — exec team +- [cs-workspace-admin](../../agents/engineering-team/cs-workspace-admin.md) — onboarding tooling ## References -- Skill: [../../skills/chro-advisor/SKILL.md](../../skills/chro-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/chro-advisor/SKILL.md](../../c-level-advisor/skills/chro-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md b/c-level-agents/agents/cs-ciso-advisor.md similarity index 72% rename from c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md rename to c-level-agents/agents/cs-ciso-advisor.md index b3ed0303..76457060 100644 --- a/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md +++ b/c-level-agents/agents/cs-ciso-advisor.md @@ -25,27 +25,27 @@ Pairs with `cs-cto-advisor` (security architecture), `cs-cfo-advisor` (risk quan ## Skill Integration -**Skill Location:** `../../skills/ciso-advisor/` +**Skill Location:** `../../c-level-advisor/skills/ciso-advisor/` ### Python Tools 1. **Risk Quantifier** - - Path: `../../skills/ciso-advisor/scripts/risk_quantifier.py` + - Path: `../../c-level-advisor/skills/ciso-advisor/scripts/risk_quantifier.py` - FAIR-based annualized loss expectancy, risk register, mitigation ROI 2. **Compliance Tracker** - - Path: `../../skills/ciso-advisor/scripts/compliance_tracker.py` + - Path: `../../c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py` - SOC 2 / ISO 27001 / HIPAA / GDPR control mapping, gap analysis, audit readiness ### Knowledge Bases -- `../../skills/ciso-advisor/references/security_strategy.md` — STRIDE, PASTA, attacker journey -- `../../skills/ciso-advisor/references/compliance_roadmap.md` — SOC 2 Type 2, ISO 27001, GDPR sequencing -- `../../skills/ciso-advisor/references/incident_response.md` — IR runbooks, comms plan, regulator notification windows +- `../../c-level-advisor/skills/ciso-advisor/references/security_strategy.md` — STRIDE, PASTA, attacker journey +- `../../c-level-advisor/skills/ciso-advisor/references/compliance_roadmap.md` — SOC 2 Type 2, ISO 27001, GDPR sequencing +- `../../c-level-advisor/skills/ciso-advisor/references/incident_response.md` — IR runbooks, comms plan, regulator notification windows ### Adjacent Skills -- `../../../ra-qm-team/` — ISO 27001 ISMS, GDPR controls, audit prep +- `../../ra-qm-team/` — ISO 27001 ISMS, GDPR controls, audit prep ## Workflows @@ -68,7 +68,7 @@ Pairs with `cs-cto-advisor` (security architecture), `cs-cfo-advisor` (risk quan 4. Output: 18-month roadmap, audit budget, controls owners ```bash -python ../../skills/ciso-advisor/scripts/compliance_tracker.py +python ../../c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py ``` ### Workflow 3: Incident Response Readiness @@ -94,9 +94,9 @@ python ../../skills/ciso-advisor/scripts/compliance_tracker.py ```bash echo "🔐 CISO Pre-Prod Gate" -python ../../skills/ciso-advisor/scripts/risk_quantifier.py -python ../../skills/ciso-advisor/scripts/compliance_tracker.py -echo "IR runbook check: ../../skills/ciso-advisor/references/incident_response.md" +python ../../c-level-advisor/skills/ciso-advisor/scripts/risk_quantifier.py +python ../../c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py +echo "IR runbook check: ../../c-level-advisor/skills/ciso-advisor/references/incident_response.md" ``` ## Success Metrics @@ -110,14 +110,14 @@ echo "IR runbook check: ../../skills/ciso-advisor/references/incident_response.m ## Related Agents -- [cs-cto-advisor](../../../agents/c-level/cs-cto-advisor.md) — security architecture +- [cs-cto-advisor](../../agents/c-level/cs-cto-advisor.md) — security architecture - [cs-cfo-advisor](cs-cfo-advisor.md) — risk → insurance, audit budget -- [cs-quality-regulatory](../../../agents/ra-qm-team/cs-quality-regulatory.md) — ISO 27001, GDPR execution -- [cs-senior-engineer](../../../agents/engineering/cs-senior-engineer.md) — secure coding +- [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — ISO 27001, GDPR execution +- [cs-senior-engineer](../../agents/engineering/cs-senior-engineer.md) — secure coding ## References -- Skill: [../../skills/ciso-advisor/SKILL.md](../../skills/ciso-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/ciso-advisor/SKILL.md](../../c-level-advisor/skills/ciso-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-cmo-advisor.md b/c-level-agents/agents/cs-cmo-advisor.md similarity index 75% rename from c-level-advisor/c-level-agents/agents/cs-cmo-advisor.md rename to c-level-agents/agents/cs-cmo-advisor.md index 0b8d6f3e..c4579570 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cmo-advisor.md +++ b/c-level-agents/agents/cs-cmo-advisor.md @@ -25,27 +25,27 @@ Pairs with `cs-cpo-advisor` (positioning ↔ product), `cs-cro-advisor` (positio ## Skill Integration -**Skill Location:** `../../skills/cmo-advisor/` +**Skill Location:** `../../c-level-advisor/skills/cmo-advisor/` ### Python Tools 1. **Marketing Budget Modeler** - - Path: `../../skills/cmo-advisor/scripts/marketing_budget_modeler.py` + - Path: `../../c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py` - Allocates budget across paid/content/events/partnerships with payback by channel 2. **Growth Model Simulator** - - Path: `../../skills/cmo-advisor/scripts/growth_model_simulator.py` + - Path: `../../c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py` - Simulates funnel: impressions → leads → opportunities → wins, with assumption sensitivity ### Knowledge Bases -- `../../skills/cmo-advisor/references/brand_positioning.md` — category design, message house, narrative arcs -- `../../skills/cmo-advisor/references/growth_frameworks.md` — channel-specific motions, PLG vs sales-led -- `../../skills/cmo-advisor/references/marketing_org.md` — attribution, cadence, content ops +- `../../c-level-advisor/skills/cmo-advisor/references/brand_positioning.md` — category design, message house, narrative arcs +- `../../c-level-advisor/skills/cmo-advisor/references/growth_frameworks.md` — channel-specific motions, PLG vs sales-led +- `../../c-level-advisor/skills/cmo-advisor/references/marketing_org.md` — attribution, cadence, content ops ### Adjacent Execution -- `../../../marketing-skill/` — full content/SEO/CRO/demand-gen pods for tactical execution +- `../../marketing-skill/` — full content/SEO/CRO/demand-gen pods for tactical execution ## Workflows @@ -68,7 +68,7 @@ Pairs with `cs-cpo-advisor` (positioning ↔ product), `cs-cro-advisor` (positio 4. Output: new allocation, 90-day test plan, success metrics ```bash -python ../../skills/cmo-advisor/scripts/marketing_budget_modeler.py +python ../../c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py ``` ### Workflow 3: Pipeline-Generation Pressure Test @@ -94,8 +94,8 @@ python ../../skills/cmo-advisor/scripts/marketing_budget_modeler.py ```bash echo "📣 CMO Quarterly Plan" -python ../../skills/cmo-advisor/scripts/marketing_budget_modeler.py -python ../../skills/cmo-advisor/scripts/growth_model_simulator.py +python ../../c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py +python ../../c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py echo "📚 Reference: positioning + playbooks" ``` @@ -111,12 +111,12 @@ echo "📚 Reference: positioning + playbooks" - [cs-cpo-advisor](cs-cpo-advisor.md) — positioning ↔ product alignment - [cs-cro-advisor](cs-cro-advisor.md) — pipeline contribution -- [cs-content-creator](../../../agents/marketing/cs-content-creator.md) — execution -- [cs-demand-gen-specialist](../../../agents/marketing/cs-demand-gen-specialist.md) — execution +- [cs-content-creator](../../agents/marketing/cs-content-creator.md) — execution +- [cs-demand-gen-specialist](../../agents/marketing/cs-demand-gen-specialist.md) — execution ## References -- Skill: [../../skills/cmo-advisor/SKILL.md](../../skills/cmo-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/cmo-advisor/SKILL.md](../../c-level-advisor/skills/cmo-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-coo-advisor.md b/c-level-agents/agents/cs-coo-advisor.md similarity index 72% rename from c-level-advisor/c-level-agents/agents/cs-coo-advisor.md rename to c-level-agents/agents/cs-coo-advisor.md index 443116d6..db041b9c 100644 --- a/c-level-advisor/c-level-agents/agents/cs-coo-advisor.md +++ b/c-level-agents/agents/cs-coo-advisor.md @@ -25,28 +25,28 @@ Pairs with `cs-cfo-advisor` (finance cadence), `cs-cro-advisor` (revenue cadence ## Skill Integration -**Skill Location:** `../../skills/coo-advisor/` +**Skill Location:** `../../c-level-advisor/skills/coo-advisor/` ### Python Tools 1. **Ops Efficiency Analyzer** - - Path: `../../skills/coo-advisor/scripts/ops_efficiency_analyzer.py` + - Path: `../../c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py` - Process throughput, cycle time, error rate, automation candidates 2. **OKR Tracker** - - Path: `../../skills/coo-advisor/scripts/okr_tracker.py` + - Path: `../../c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py` - Quarter-to-date OKR progress, leading/lagging indicators, on-track / at-risk / off-track ### Knowledge Bases -- `../../skills/coo-advisor/references/ops_cadence.md` — weekly/monthly/quarterly rhythm, meeting design -- `../../skills/coo-advisor/references/process_frameworks.md` — OKR design, scoring, cascading -- `../../skills/coo-advisor/references/scaling_playbook.md` — 1-10, 10-100, 100-1000 transitions +- `../../c-level-advisor/skills/coo-advisor/references/ops_cadence.md` — weekly/monthly/quarterly rhythm, meeting design +- `../../c-level-advisor/skills/coo-advisor/references/process_frameworks.md` — OKR design, scoring, cascading +- `../../c-level-advisor/skills/coo-advisor/references/scaling_playbook.md` — 1-10, 10-100, 100-1000 transitions ### Adjacent Skills -- `../../skills/company-os/` — EOS / Scaling Up / OKR selection -- `../../skills/strategic-alignment/` — strategy cascade & silo detection +- `../../c-level-advisor/skills/company-os/` — EOS / Scaling Up / OKR selection +- `../../c-level-advisor/skills/strategic-alignment/` — strategy cascade & silo detection ## Workflows @@ -69,14 +69,14 @@ Pairs with `cs-cfo-advisor` (finance cadence), `cs-cro-advisor` (revenue cadence 4. Output: OKR scorecard, at-risk list, fix actions ```bash -python ../../skills/coo-advisor/scripts/okr_tracker.py +python ../../c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py ``` ### Workflow 3: Operating-System Selection **Goal:** Pick EOS, Scaling Up, or OKR for the company. **Steps:** -1. Reference `../../skills/company-os/SKILL.md` for selection criteria +1. Reference `../../c-level-advisor/skills/company-os/SKILL.md` for selection criteria 2. Reference `scaling_playbooks.md` for stage fit 3. Map current pain points to which OS solves them 4. Output: recommended OS, 90-day rollout, success metrics @@ -95,9 +95,9 @@ python ../../skills/coo-advisor/scripts/okr_tracker.py ```bash echo "⚙️ COO Quarterly Review" -python ../../skills/coo-advisor/scripts/okr_tracker.py -python ../../skills/coo-advisor/scripts/ops_efficiency_analyzer.py -echo "Reference: ../../skills/coo-advisor/references/ops_cadence.md" +python ../../c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py +python ../../c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py +echo "Reference: ../../c-level-advisor/skills/coo-advisor/references/ops_cadence.md" ``` ## Success Metrics @@ -113,11 +113,11 @@ echo "Reference: ../../skills/coo-advisor/references/ops_cadence.md" - [cs-cfo-advisor](cs-cfo-advisor.md) — finance cadence - [cs-cro-advisor](cs-cro-advisor.md) — revenue cadence - [cs-chief-of-staff](cs-chief-of-staff.md) — decision logging -- [cs-engineering-lead](../../../agents/engineering-team/cs-engineering-lead.md) — eng ops +- [cs-engineering-lead](../../agents/engineering-team/cs-engineering-lead.md) — eng ops ## References -- Skill: [../../skills/coo-advisor/SKILL.md](../../skills/coo-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/coo-advisor/SKILL.md](../../c-level-advisor/skills/coo-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md b/c-level-agents/agents/cs-cpo-advisor.md similarity index 73% rename from c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md rename to c-level-agents/agents/cs-cpo-advisor.md index e2116d57..c1e5cd63 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md +++ b/c-level-agents/agents/cs-cpo-advisor.md @@ -25,27 +25,27 @@ Pairs with `cs-cmo-advisor` (positioning ↔ product), `cs-cro-advisor` (win/los ## Skill Integration -**Skill Location:** `../../skills/cpo-advisor/` +**Skill Location:** `../../c-level-advisor/skills/cpo-advisor/` ### Python Tools 1. **PMF Scorer** - - Path: `../../skills/cpo-advisor/scripts/pmf_scorer.py` + - Path: `../../c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py` - Sean Ellis test, retention cohort score, organic-pull score → composite PMF rating 2. **Portfolio Analyzer** - - Path: `../../skills/cpo-advisor/scripts/portfolio_analyzer.py` + - Path: `../../c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py` - 3-horizon analysis, kill candidates, double-down candidates, resource allocation ### Knowledge Bases -- `../../skills/cpo-advisor/references/product_strategy.md` — vision design, North Star metrics, opportunity solution tree -- `../../skills/cpo-advisor/references/product_org_design.md` — 3-horizon, ROI vs strategic fit, kill criteria -- `../../skills/cpo-advisor/references/pmf_playbook.md` — Sean Ellis, retention, organic pull, what PMF actually looks like +- `../../c-level-advisor/skills/cpo-advisor/references/product_strategy.md` — vision design, North Star metrics, opportunity solution tree +- `../../c-level-advisor/skills/cpo-advisor/references/product_org_design.md` — 3-horizon, ROI vs strategic fit, kill criteria +- `../../c-level-advisor/skills/cpo-advisor/references/pmf_playbook.md` — Sean Ellis, retention, organic pull, what PMF actually looks like ### Adjacent Execution -- `../../../product-team/skills/product-manager-toolkit/` — RICE, OKR cascade, user stories +- `../../product-team/skills/product-manager-toolkit/` — RICE, OKR cascade, user stories ## Workflows @@ -59,7 +59,7 @@ Pairs with `cs-cmo-advisor` (positioning ↔ product), `cs-cro-advisor` (win/los 4. Output: composite PMF score, weakest signal, top-3 fixes to lift it ```bash -python ../../skills/cpo-advisor/scripts/pmf_scorer.py +python ../../c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py ``` ### Workflow 2: Portfolio Rationalization @@ -94,9 +94,9 @@ python ../../skills/cpo-advisor/scripts/pmf_scorer.py ```bash echo "✂️ CPO Portfolio Audit" -python ../../skills/cpo-advisor/scripts/portfolio_analyzer.py -python ../../skills/cpo-advisor/scripts/pmf_scorer.py -echo "Pair with RICE: python ../../../product-team/skills/product-manager-toolkit/scripts/rice_prioritizer.py" +python ../../c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py +python ../../c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py +echo "Pair with RICE: python ../../product-team/skills/product-manager-toolkit/scripts/rice_prioritizer.py" ``` ## Success Metrics @@ -111,12 +111,12 @@ echo "Pair with RICE: python ../../../product-team/skills/product-manager-toolki - [cs-cmo-advisor](cs-cmo-advisor.md) — positioning alignment - [cs-cro-advisor](cs-cro-advisor.md) — win/loss feedback -- [cs-product-manager](../../../agents/product/cs-product-manager.md) — execution -- [cs-product-strategist](../../../agents/product/cs-product-strategist.md) — OKR cascade +- [cs-product-manager](../../agents/product/cs-product-manager.md) — execution +- [cs-product-strategist](../../agents/product/cs-product-strategist.md) — OKR cascade ## References -- Skill: [../../skills/cpo-advisor/SKILL.md](../../skills/cpo-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/cpo-advisor/SKILL.md](../../c-level-advisor/skills/cpo-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-cro-advisor.md b/c-level-agents/agents/cs-cro-advisor.md similarity index 77% rename from c-level-advisor/c-level-agents/agents/cs-cro-advisor.md rename to c-level-agents/agents/cs-cro-advisor.md index 0a16b2e5..fafb35bf 100644 --- a/c-level-advisor/c-level-agents/agents/cs-cro-advisor.md +++ b/c-level-agents/agents/cs-cro-advisor.md @@ -25,23 +25,23 @@ Pairs with `cs-cfo-advisor` (revenue → cash conversion), `cs-cmo-advisor` (pip ## Skill Integration -**Skill Location:** `../../skills/cro-advisor/` +**Skill Location:** `../../c-level-advisor/skills/cro-advisor/` ### Python Tools 1. **Revenue Forecast Model** - - Path: `../../skills/cro-advisor/scripts/revenue_forecast_model.py` + - Path: `../../c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py` - Bottom-up + top-down forecast, pipeline coverage by stage, ramp-adjusted 2. **Churn Analyzer** - - Path: `../../skills/cro-advisor/scripts/churn_analyzer.py` + - Path: `../../c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py` - Logo churn, gross retention, NRR, cohort decay, expansion vs contraction ### Knowledge Bases -- `../../skills/cro-advisor/references/sales_playbook.md` — pipeline cadence, win/loss process, forecasting hygiene -- `../../skills/cro-advisor/references/pricing_strategy.md` — PLG vs sales-led, hiring profiles, ramp curves -- `../../skills/cro-advisor/references/nrr_playbook.md` — NRR levers, customer success cadence, expansion plays +- `../../c-level-advisor/skills/cro-advisor/references/sales_playbook.md` — pipeline cadence, win/loss process, forecasting hygiene +- `../../c-level-advisor/skills/cro-advisor/references/pricing_strategy.md` — PLG vs sales-led, hiring profiles, ramp curves +- `../../c-level-advisor/skills/cro-advisor/references/nrr_playbook.md` — NRR levers, customer success cadence, expansion plays ## Workflows @@ -55,7 +55,7 @@ Pairs with `cs-cfo-advisor` (revenue → cash conversion), `cs-cmo-advisor` (pip 4. Output: gap-to-plan, top-3 stage fixes, weekly check-in template ```bash -python ../../skills/cro-advisor/scripts/revenue_forecast_model.py +python ../../c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py ``` ### Workflow 2: NRR Decomposition @@ -91,8 +91,8 @@ python ../../skills/cro-advisor/scripts/revenue_forecast_model.py ```bash #!/bin/bash echo "📈 CRO Weekly Review" -python ../../skills/cro-advisor/scripts/revenue_forecast_model.py -python ../../skills/cro-advisor/scripts/churn_analyzer.py +python ../../c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py +python ../../c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py echo "Pipeline coverage and retention dashboard ready." ``` @@ -109,11 +109,11 @@ echo "Pipeline coverage and retention dashboard ready." - [cs-cfo-advisor](cs-cfo-advisor.md) — revenue → cash conversion - [cs-cmo-advisor](cs-cmo-advisor.md) — pipeline contribution - [cs-cpo-advisor](cs-cpo-advisor.md) — product gaps in win/loss -- [cs-growth-strategist](../../../agents/business-growth/cs-growth-strategist.md) — execution +- [cs-growth-strategist](../../agents/business-growth/cs-growth-strategist.md) — execution ## References -- Skill: [../../skills/cro-advisor/SKILL.md](../../skills/cro-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/cro-advisor/SKILL.md](../../c-level-advisor/skills/cro-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) --- diff --git a/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md b/c-level-agents/agents/cs-general-counsel-advisor.md similarity index 76% rename from c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md rename to c-level-agents/agents/cs-general-counsel-advisor.md index bc90a4e9..4713795e 100644 --- a/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md +++ b/c-level-agents/agents/cs-general-counsel-advisor.md @@ -27,27 +27,27 @@ Pairs with `cs-cfo-advisor` (term-sheet → dilution math), `cs-ciso-advisor` (d ## Skill Integration -**Skill Location:** `../../skills/general-counsel-advisor/` +**Skill Location:** `../../c-level-advisor/skills/general-counsel-advisor/` ### Python Tools 1. **Contract Risk Scanner** - - Path: `../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py` - - Usage: `python ../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt` + - Path: `../../c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py` + - Usage: `python ../../c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt` - Scans contract text for 12 founder-killer clauses: auto-renew traps, uncapped indemnity, one-sided liability, vague IP, aggressive non-compete, one-sided venue, missing DPA, MFN pricing, broad audit rights, perpetual license-back, force majeure asymmetry, broad non-solicit - Output: ranked findings (CRITICAL / HIGH / MEDIUM) with excerpt, why-it-matters, suggested redline 2. **Term Sheet Analyzer** - - Path: `../../skills/general-counsel-advisor/scripts/term_sheet_analyzer.py` - - Usage: `python ../../skills/general-counsel-advisor/scripts/term_sheet_analyzer.py term_sheet.json` + - Path: `../../c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py` + - Usage: `python ../../c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py term_sheet.json` - Scores a term sheet 0-100 across 12 dimensions: liquidation preference, anti-dilution, option pool, board, vesting, pro-rata, drag-along, protective provisions, info rights, dividends, valuation/dilution, holistic - Output: founder-friendliness grade (FOUNDER_FRIENDLY / NEGOTIATE / HOSTILE) + per-clause flags ### Knowledge Bases -- `../../skills/general-counsel-advisor/references/contracts_playbook.md` — 7 startup contract types (MSA, SaaS, NDA, DPA, employment, contractor, equity), top redlines per type, quick triage heuristics -- `../../skills/general-counsel-advisor/references/ip_and_regulatory.md` — IP inventory (patents, copyright, trademark, trade secrets), invention assignment, OSS license compliance, regulatory trigger matrix (HIPAA, GDPR, FDA, fintech, AI Act), SOC 2 → ISO sequencing -- `../../skills/general-counsel-advisor/references/term_sheet_decoder.md` — Full term sheet glossary, founder-friendly defaults cheat sheet, negotiation strategy, the three clauses that matter most +- `../../c-level-advisor/skills/general-counsel-advisor/references/contracts_playbook.md` — 7 startup contract types (MSA, SaaS, NDA, DPA, employment, contractor, equity), top redlines per type, quick triage heuristics +- `../../c-level-advisor/skills/general-counsel-advisor/references/ip_and_regulatory.md` — IP inventory (patents, copyright, trademark, trade secrets), invention assignment, OSS license compliance, regulatory trigger matrix (HIPAA, GDPR, FDA, fintech, AI Act), SOC 2 → ISO sequencing +- `../../c-level-advisor/skills/general-counsel-advisor/references/term_sheet_decoder.md` — Full term sheet glossary, founder-friendly defaults cheat sheet, negotiation strategy, the three clauses that matter most ## Workflows @@ -57,7 +57,7 @@ Pairs with `cs-cfo-advisor` (term-sheet → dilution math), `cs-ciso-advisor` (d ```bash # 1. Save contract as text # 2. Scan for the 12 common founder-killer clauses -python ../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt +python ../../c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt # 3. For each CRITICAL/HIGH finding, draft a counter-proposal # 4. Send redlines + counter-proposals to outside counsel ``` @@ -69,7 +69,7 @@ python ../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py pat ```bash # 1. Build term_sheet.json matching the schema (see --help) -python ../../skills/general-counsel-advisor/scripts/term_sheet_analyzer.py term_sheet.json +python ../../c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py term_sheet.json # 2. Identify the top 3 NEGOTIATE / CRITICAL items # 3. Cross-check with cs-cfo-advisor for dilution math # 4. Decide which 3 to fight for (don't try to win all 20) @@ -125,12 +125,12 @@ echo "Source: $CONTRACT" echo "" # 1. Risk scan -python ../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py "$CONTRACT" +python ../../c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py "$CONTRACT" echo "" echo "📚 Reference checks:" -echo "- Contracts playbook: ../../skills/general-counsel-advisor/references/contracts_playbook.md" -echo "- Regulatory triggers: ../../skills/general-counsel-advisor/references/ip_and_regulatory.md" +echo "- Contracts playbook: ../../c-level-advisor/skills/general-counsel-advisor/references/contracts_playbook.md" +echo "- Regulatory triggers: ../../c-level-advisor/skills/general-counsel-advisor/references/ip_and_regulatory.md" echo "" echo "📋 Required before sign:" echo " ☐ All CRITICAL findings addressed or accepted with documented reason" @@ -152,12 +152,12 @@ echo " ☐ /cs:freeze applied if irreversible (term sheet, M&A LOI, employment - [cs-cfo-advisor](cs-cfo-advisor.md) — term sheet → dilution math - [cs-ciso-advisor](cs-ciso-advisor.md) — data-touching contracts, compliance overlap -- [cs-ceo-advisor](../../../agents/c-level/cs-ceo-advisor.md) — board / fundraising strategic context -- [cs-quality-regulatory](../../../agents/ra-qm-team/cs-quality-regulatory.md) — regulated-industry execution (ISO 13485, MDR, FDA) +- [cs-ceo-advisor](../../agents/c-level/cs-ceo-advisor.md) — board / fundraising strategic context +- [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — regulated-industry execution (ISO 13485, MDR, FDA) ## References -- Skill: [../../skills/general-counsel-advisor/SKILL.md](../../skills/general-counsel-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/general-counsel-advisor/SKILL.md](../../c-level-advisor/skills/general-counsel-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Sibling command: [`/cs:gc-review`](../skills/gc-review/SKILL.md) diff --git a/c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md b/c-level-agents/agents/cs-vpe-advisor.md similarity index 69% rename from c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md rename to c-level-agents/agents/cs-vpe-advisor.md index 96bdcf04..60a886a8 100644 --- a/c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md +++ b/c-level-agents/agents/cs-vpe-advisor.md @@ -37,31 +37,31 @@ Differentiates clearly: ## Skill Integration -**Skill Location:** `../../skills/vpe-advisor/` +**Skill Location:** `../../c-level-advisor/skills/vpe-advisor/` ### Python Tools 1. **Delivery Throughput Analyzer** - - Path: `../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py` - - Usage: `python ../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json` + - Path: `../../c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py` + - Usage: `python ../../c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json` - Returns: DORA 4 metrics (Deployment Frequency, Lead Time, MTTR, Change Failure Rate) with Elite/High/Medium/Low verdict per metric and overall. Cycle-time bottleneck identification (top wait stage as % of cycle) + typical fixes per bottleneck 2. **Engineering Hiring Funnel Calculator** - - Path: `../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py` - - Usage: `python ../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json` + - Path: `../../c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py` + - Usage: `python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json` - Returns: Stage-by-stage conversion rates (7-stage funnel) with healthy/leaky verdict, end-to-end conversion, required top-of-funnel volume for hiring target, weakest-stage identification + fixes (sourcing, calibration, interview design, comp/close discipline) 3. **Engineering Team Structure Designer** - - Path: `../../skills/vpe-advisor/scripts/eng_team_structure_designer.py` - - Usage: `python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json` + - Path: `../../c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py` + - Usage: `python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json` - Returns: Recommended structure (informal pods / formal squads / squads+tribes / multi-tribe) based on headcount, squad sizing assessment (5-9 IC range), manager-trigger (first EM, EM-overstretched, EM-underutilized), director-trigger (3+ EMs reporting to VPE/CTO) ### Knowledge Bases -- `../../skills/vpe-advisor/references/delivery_throughput.md` — Full DORA framework + thresholds + 4 common bottlenecks (PR review, CI flakiness, deploy gates, scheduled releases) + what to fix first (lead time → failure rate → frequency → MTTR) + anti-patterns -- `../../skills/vpe-advisor/references/engineering_hiring_funnel.md` — 7-stage funnel + healthy conversion benchmarks + leakage diagnosis per stage + pipeline volume math + time-to-fill discipline + technical interview design + cost-per-hire -- `../../skills/vpe-advisor/references/eng_team_structure.md` — Conway's Law + headcount-to-structure map + span-of-control benchmarks + EM-vs-tech-lead distinction + manager + director + VPE triggers + squad sizing + chapter discipline -- `../../skills/vpe-advisor/references/production_discipline.md` — On-call rotation (≥ 6 people; burnout signals) + incident response (severity levels, IC role, blameless postmortems) + deployment cadence (continuous vs scheduled; progressive delivery) + SLO discipline + maturity-level model (Level 1-5) +- `../../c-level-advisor/skills/vpe-advisor/references/delivery_throughput.md` — Full DORA framework + thresholds + 4 common bottlenecks (PR review, CI flakiness, deploy gates, scheduled releases) + what to fix first (lead time → failure rate → frequency → MTTR) + anti-patterns +- `../../c-level-advisor/skills/vpe-advisor/references/engineering_hiring_funnel.md` — 7-stage funnel + healthy conversion benchmarks + leakage diagnosis per stage + pipeline volume math + time-to-fill discipline + technical interview design + cost-per-hire +- `../../c-level-advisor/skills/vpe-advisor/references/eng_team_structure.md` — Conway's Law + headcount-to-structure map + span-of-control benchmarks + EM-vs-tech-lead distinction + manager + director + VPE triggers + squad sizing + chapter discipline +- `../../c-level-advisor/skills/vpe-advisor/references/production_discipline.md` — On-call rotation (≥ 6 people; burnout signals) + incident response (severity levels, IC role, blameless postmortems) + deployment cadence (continuous vs scheduled; progressive delivery) + SLO discipline + maturity-level model (Level 1-5) ## Workflows @@ -69,7 +69,7 @@ Differentiates clearly: **Goal:** DORA diagnosis + identify top bottleneck + 90-day fix plan. ```bash -python ../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json # Cross-check architectural causes with cs-cto-advisor # Output: top bottleneck + one engineer named to own the fix # Log via /cs:decide @@ -79,7 +79,7 @@ python ../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_m **Goal:** Identify funnel leakage + compute pipeline gap. ```bash -python ../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json # Cross-check comp + leveling with cs-chro-advisor # Cross-check cost-per-hire envelope with cs-cfo-advisor # Output: weakest-stage fixes + sourcing channel diversification plan @@ -89,7 +89,7 @@ python ../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.j **Goal:** Confirm structure matches headcount + work streams; identify manager-trigger. ```bash -python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json # Cross-check Conway's Law alignment with cs-cto-advisor # Output: structure recommendation + manager hire plan ``` @@ -119,13 +119,13 @@ python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json # Quarterly VPE brief — pre-board version # 1. Delivery throughput (DORA 4 metrics + bottleneck) -python ../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py current-sprint.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py current-sprint.json # 2. Hiring funnel health + pipeline gap -python ../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py current-funnel.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py current-funnel.json # 3. Team structure check -python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py current-team.json +python ../../c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py current-team.json # Board narrative requires: # - DORA verdict + top bottleneck @@ -145,15 +145,15 @@ python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py current-t ## Related Agents -- [cs-cto-advisor](../../../agents/c-level/cs-cto-advisor.md) — Architecture, scaling cliffs (CTO decides what to build; VPE decides how to ship) +- [cs-cto-advisor](../../agents/c-level/cs-cto-advisor.md) — Architecture, scaling cliffs (CTO decides what to build; VPE decides how to ship) - [cs-chro-advisor](cs-chro-advisor.md) — Hiring systems (ladders, bands) - [cs-coo-advisor](cs-coo-advisor.md) — Operating cadence company-wide - [cs-cfo-advisor](cs-cfo-advisor.md) — Cost-per-hire envelope, eng budget -- [cs-engineering-lead](../../../agents/engineering-team/cs-engineering-lead.md) — Day-to-day incident + on-call coordination +- [cs-engineering-lead](../../agents/engineering-team/cs-engineering-lead.md) — Day-to-day incident + on-call coordination ## References -- Skill: [../../skills/vpe-advisor/SKILL.md](../../skills/vpe-advisor/SKILL.md) +- Skill: [../../c-level-advisor/skills/vpe-advisor/SKILL.md](../../c-level-advisor/skills/vpe-advisor/SKILL.md) - Voice spec: [../references/persona-voices.md](../references/persona-voices.md) - Sibling command: [`/cs:vpe-review`](../skills/vpe-review/SKILL.md) diff --git a/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md b/c-level-agents/references/llm-wiki-bridge.md similarity index 100% rename from c-level-advisor/c-level-agents/references/llm-wiki-bridge.md rename to c-level-agents/references/llm-wiki-bridge.md diff --git a/c-level-advisor/c-level-agents/references/persona-voices.md b/c-level-agents/references/persona-voices.md similarity index 100% rename from c-level-advisor/c-level-agents/references/persona-voices.md rename to c-level-agents/references/persona-voices.md diff --git a/c-level-advisor/c-level-agents/skills/boardroom/SKILL.md b/c-level-agents/skills/boardroom/SKILL.md similarity index 96% rename from c-level-advisor/c-level-agents/skills/boardroom/SKILL.md rename to c-level-agents/skills/boardroom/SKILL.md index d969594d..e6395189 100644 --- a/c-level-advisor/c-level-agents/skills/boardroom/SKILL.md +++ b/c-level-agents/skills/boardroom/SKILL.md @@ -127,7 +127,7 @@ If advisors see each other's positions before forming their own, they anchor. Ph ## Related - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) -- Skills: [`board-meeting`](../../../skills/board-meeting/SKILL.md), [`executive-mentor`](../../../executive-mentor/) +- Skills: [`board-meeting`](../../../c-level-advisor/skills/board-meeting/SKILL.md), [`executive-mentor`](../../../c-level-advisor/executive-mentor/) --- diff --git a/c-level-advisor/c-level-agents/skills/brief/SKILL.md b/c-level-agents/skills/brief/SKILL.md similarity index 95% rename from c-level-advisor/c-level-agents/skills/brief/SKILL.md rename to c-level-agents/skills/brief/SKILL.md index aa5f7a8a..7829b5e1 100644 --- a/c-level-advisor/c-level-agents/skills/brief/SKILL.md +++ b/c-level-agents/skills/brief/SKILL.md @@ -111,7 +111,7 @@ This is also the **artifact handoff** — the next command consumes this file, n ## Related - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) -- Skills: [`context-engine`](../../../skills/context-engine/SKILL.md), [`board-meeting`](../../../skills/board-meeting/SKILL.md) +- Skills: [`context-engine`](../../../c-level-advisor/skills/context-engine/SKILL.md), [`board-meeting`](../../../c-level-advisor/skills/board-meeting/SKILL.md) --- diff --git a/c-level-advisor/c-level-agents/skills/c-level-agents/SKILL.md b/c-level-agents/skills/c-level-agents/SKILL.md similarity index 98% rename from c-level-advisor/c-level-agents/skills/c-level-agents/SKILL.md rename to c-level-agents/skills/c-level-agents/SKILL.md index ca59e815..da8acb33 100644 --- a/c-level-advisor/c-level-agents/skills/c-level-agents/SKILL.md +++ b/c-level-agents/skills/c-level-agents/SKILL.md @@ -110,7 +110,7 @@ User question - [persona-voices.md](../../references/persona-voices.md) - [llm-wiki-bridge.md](../../references/llm-wiki-bridge.md) - [Parent c-level CLAUDE.md](../../../CLAUDE.md) -- [Existing executive-mentor sibling](../../../executive-mentor/) +- [Existing executive-mentor sibling](../../../c-level-advisor/executive-mentor/) --- diff --git a/c-level-advisor/c-level-agents/skills/caio-review/SKILL.md b/c-level-agents/skills/caio-review/SKILL.md similarity index 90% rename from c-level-advisor/c-level-agents/skills/caio-review/SKILL.md rename to c-level-agents/skills/caio-review/SKILL.md index dd135a23..697ac95e 100644 --- a/c-level-advisor/c-level-agents/skills/caio-review/SKILL.md +++ b/c-level-agents/skills/caio-review/SKILL.md @@ -68,13 +68,13 @@ The eval-demanding CAIO pressure-tests any plan that involves AI. Six questions ```bash # 1. Model selection check -python ../../../skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json +python ../../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py use_case.json # 2. Regulatory classification -python ../../../skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json +python ../../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py use_case.json # 3. Cost projection -python ../../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json +python ../../../c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py workload.json ``` ## Output Format @@ -132,8 +132,8 @@ python ../../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py wor ## Related - Agent: [`cs-caio-advisor`](../../agents/cs-caio-advisor.md) -- Skill: [`chief-ai-officer-advisor`](../../../skills/chief-ai-officer-advisor/SKILL.md) -- Adjacent: `../../../skills/chief-data-officer-advisor/` (training data rights, data strategy) +- Skill: [`chief-ai-officer-advisor`](../../../c-level-advisor/skills/chief-ai-officer-advisor/SKILL.md) +- Adjacent: `../../../c-level-advisor/skills/chief-data-officer-advisor/` (training data rights, data strategy) --- diff --git a/c-level-advisor/c-level-agents/skills/cco-review/SKILL.md b/c-level-agents/skills/cco-review/SKILL.md similarity index 89% rename from c-level-advisor/c-level-agents/skills/cco-review/SKILL.md rename to c-level-agents/skills/cco-review/SKILL.md index 9de92d43..17e0a4e1 100644 --- a/c-level-advisor/c-level-agents/skills/cco-review/SKILL.md +++ b/c-level-agents/skills/cco-review/SKILL.md @@ -64,13 +64,13 @@ The retention-obsessed CCO pressure-tests any plan that touches customer experie ```bash # 1. Retention decomposition (always start here) -python ../../../skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json +python ../../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py cohorts.json # 2. Segmentation audit -python ../../../skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json +python ../../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py customers.json # 3. Coverage sizing (if making CS team changes) -python ../../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json +python ../../../c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py book.json ``` ## Output Format @@ -122,8 +122,8 @@ python ../../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calcul ## Related - Agent: [`cs-cco-advisor`](../../agents/cs-cco-advisor.md) -- Skill: [`chief-customer-officer-advisor`](../../../skills/chief-customer-officer-advisor/SKILL.md) -- Adjacent: `../../../../business-growth/` (tactical CS execution) +- Skill: [`chief-customer-officer-advisor`](../../../c-level-advisor/skills/chief-customer-officer-advisor/SKILL.md) +- Adjacent: `../../../business-growth/` (tactical CS execution) --- diff --git a/c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md b/c-level-agents/skills/cdo-review/SKILL.md similarity index 87% rename from c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md rename to c-level-agents/skills/cdo-review/SKILL.md index b962d71d..7cda8568 100644 --- a/c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md +++ b/c-level-agents/skills/cdo-review/SKILL.md @@ -60,13 +60,13 @@ The decision-driven CDO pressure-tests any plan that touches data strategy. Six ```bash # 1. AI training audit (if any ML / AI use case) -python ../../../skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json +python ../../../c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py sources.json # 2. Architecture decision (if changing the stack) -python ../../../skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json +python ../../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py profile.json # 3. Data asset valuation (if productizing or pre-M&A) -python ../../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json +python ../../../c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py corpus.json ``` ## Output Format @@ -118,8 +118,8 @@ python ../../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py ## Related - Agent: [`cs-cdo-advisor`](../../agents/cs-cdo-advisor.md) -- Skill: [`chief-data-officer-advisor`](../../../skills/chief-data-officer-advisor/SKILL.md) -- Adjacent: `../../../skills/general-counsel-advisor/` (contractual constraints), `../../../skills/cto-advisor/` (architecture capacity) +- Skill: [`chief-data-officer-advisor`](../../../c-level-advisor/skills/chief-data-officer-advisor/SKILL.md) +- Adjacent: `../../../c-level-advisor/skills/general-counsel-advisor/` (contractual constraints), `../../../c-level-advisor/skills/cto-advisor/` (architecture capacity) --- diff --git a/c-level-advisor/c-level-agents/skills/cfo-review/SKILL.md b/c-level-agents/skills/cfo-review/SKILL.md similarity index 89% rename from c-level-advisor/c-level-agents/skills/cfo-review/SKILL.md rename to c-level-agents/skills/cfo-review/SKILL.md index bc59bd04..041d468e 100644 --- a/c-level-advisor/c-level-agents/skills/cfo-review/SKILL.md +++ b/c-level-agents/skills/cfo-review/SKILL.md @@ -53,9 +53,9 @@ The numerate skeptic stress-tests anything that touches money. Six questions bef 1. **Run the numbers:** ```bash - python ../../../skills/cfo-advisor/scripts/burn_rate_calculator.py - python ../../../skills/cfo-advisor/scripts/unit_economics_analyzer.py - python ../../../skills/cfo-advisor/scripts/fundraising_model.py + python ../../../c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py + python ../../../c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py + python ../../../c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py ``` 2. **Answer all six questions** with numbers, not adjectives. 3. **Apply the verdict:** @@ -98,7 +98,7 @@ The numerate skeptic stress-tests anything that touches money. Six questions bef ## Related - Agent: [`cs-cfo-advisor`](../../agents/cs-cfo-advisor.md) -- Skill: [`cfo-advisor`](../../../skills/cfo-advisor/SKILL.md) +- Skill: [`cfo-advisor`](../../../c-level-advisor/skills/cfo-advisor/SKILL.md) --- diff --git a/c-level-advisor/c-level-agents/skills/ciso-review/SKILL.md b/c-level-agents/skills/ciso-review/SKILL.md similarity index 91% rename from c-level-advisor/c-level-agents/skills/ciso-review/SKILL.md rename to c-level-agents/skills/ciso-review/SKILL.md index db874772..df2089b0 100644 --- a/c-level-advisor/c-level-agents/skills/ciso-review/SKILL.md +++ b/c-level-agents/skills/ciso-review/SKILL.md @@ -53,8 +53,8 @@ The risk-paranoid threat-modeler. Six questions before any production change tha ## Workflow ```bash -python ../../../skills/ciso-advisor/scripts/risk_quantifier.py -python ../../../skills/ciso-advisor/scripts/compliance_tracker.py +python ../../../c-level-advisor/skills/ciso-advisor/scripts/risk_quantifier.py +python ../../../c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py ``` ## Output Format @@ -105,8 +105,8 @@ python ../../../skills/ciso-advisor/scripts/compliance_tracker.py ## Related - Agent: [`cs-ciso-advisor`](../../agents/cs-ciso-advisor.md) -- Skill: [`ciso-advisor`](../../../skills/ciso-advisor/SKILL.md) -- Compliance: `../../../../ra-qm-team/` +- Skill: [`ciso-advisor`](../../../c-level-advisor/skills/ciso-advisor/SKILL.md) +- Compliance: `../../../ra-qm-team/` --- diff --git a/c-level-advisor/c-level-agents/skills/cmo-review/SKILL.md b/c-level-agents/skills/cmo-review/SKILL.md similarity index 90% rename from c-level-advisor/c-level-agents/skills/cmo-review/SKILL.md rename to c-level-agents/skills/cmo-review/SKILL.md index 755ae792..aee53233 100644 --- a/c-level-advisor/c-level-agents/skills/cmo-review/SKILL.md +++ b/c-level-agents/skills/cmo-review/SKILL.md @@ -51,8 +51,8 @@ The narrative-first strategist pressure-tests positioning before debating tactic 1. **Run the models:** ```bash - python ../../../skills/cmo-advisor/scripts/marketing_budget_modeler.py - python ../../../skills/cmo-advisor/scripts/growth_model_simulator.py + python ../../../c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py + python ../../../c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py ``` 2. **Answer the six questions** in writing. 3. **Apply the verdict:** @@ -93,8 +93,8 @@ One-sentence statement: ## Related - Agent: [`cs-cmo-advisor`](../../agents/cs-cmo-advisor.md) -- Skill: [`cmo-advisor`](../../../skills/cmo-advisor/SKILL.md) -- Execution domain: `../../../../marketing-skill/` +- Skill: [`cmo-advisor`](../../../c-level-advisor/skills/cmo-advisor/SKILL.md) +- Execution domain: `../../../marketing-skill/` --- diff --git a/c-level-advisor/c-level-agents/skills/cpo-review/SKILL.md b/c-level-agents/skills/cpo-review/SKILL.md similarity index 92% rename from c-level-advisor/c-level-agents/skills/cpo-review/SKILL.md rename to c-level-agents/skills/cpo-review/SKILL.md index 1e32640f..c8cd55a3 100644 --- a/c-level-advisor/c-level-agents/skills/cpo-review/SKILL.md +++ b/c-level-agents/skills/cpo-review/SKILL.md @@ -53,8 +53,8 @@ python product-team/skills/product-manager-toolkit/scripts/rice_prioritizer.py 1. **Run the analyses:** ```bash - python ../../../skills/cpo-advisor/scripts/pmf_scorer.py - python ../../../skills/cpo-advisor/scripts/portfolio_analyzer.py + python ../../../c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py + python ../../../c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py ``` 2. **Answer the six questions.** 3. **Apply the verdict.** @@ -102,7 +102,7 @@ python product-team/skills/product-manager-toolkit/scripts/rice_prioritizer.py ## Related - Agent: [`cs-cpo-advisor`](../../agents/cs-cpo-advisor.md) -- Skill: [`cpo-advisor`](../../../skills/cpo-advisor/SKILL.md) +- Skill: [`cpo-advisor`](../../../c-level-advisor/skills/cpo-advisor/SKILL.md) - Execution: `product-team/skills/product-manager-toolkit/` --- diff --git a/c-level-advisor/c-level-agents/skills/cro-review/SKILL.md b/c-level-agents/skills/cro-review/SKILL.md similarity index 90% rename from c-level-advisor/c-level-agents/skills/cro-review/SKILL.md rename to c-level-agents/skills/cro-review/SKILL.md index b3f068d2..04c3b2da 100644 --- a/c-level-advisor/c-level-agents/skills/cro-review/SKILL.md +++ b/c-level-agents/skills/cro-review/SKILL.md @@ -52,8 +52,8 @@ The pipeline-paranoid operator pressure-tests revenue assumptions. Six questions ## Workflow ```bash -python ../../../skills/cro-advisor/scripts/revenue_forecast_model.py -python ../../../skills/cro-advisor/scripts/churn_analyzer.py +python ../../../c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py +python ../../../c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py ``` ## Output Format @@ -102,8 +102,8 @@ python ../../../skills/cro-advisor/scripts/churn_analyzer.py ## Related - Agent: [`cs-cro-advisor`](../../agents/cs-cro-advisor.md) -- Skill: [`cro-advisor`](../../../skills/cro-advisor/SKILL.md) -- Execution: `../../../../business-growth/` +- Skill: [`cro-advisor`](../../../c-level-advisor/skills/cro-advisor/SKILL.md) +- Execution: `../../../business-growth/` --- diff --git a/c-level-advisor/c-level-agents/skills/cross-eval/SKILL.md b/c-level-agents/skills/cross-eval/SKILL.md similarity index 96% rename from c-level-advisor/c-level-agents/skills/cross-eval/SKILL.md rename to c-level-agents/skills/cross-eval/SKILL.md index 5b7936fa..5dce0104 100644 --- a/c-level-advisor/c-level-agents/skills/cross-eval/SKILL.md +++ b/c-level-agents/skills/cross-eval/SKILL.md @@ -107,7 +107,7 @@ This is weaker than true multi-model. Treat the result as suggestive, not conclu ## Related -- Skills: [`board-meeting`](../../../skills/board-meeting/SKILL.md), [`executive-mentor`](../../../executive-mentor/) +- Skills: [`board-meeting`](../../../c-level-advisor/skills/board-meeting/SKILL.md), [`executive-mentor`](../../../c-level-advisor/executive-mentor/) - Inspiration: gstack's `/codex` cross-review pattern (adapted to business memos) --- diff --git a/c-level-advisor/c-level-agents/skills/cto-review/SKILL.md b/c-level-agents/skills/cto-review/SKILL.md similarity index 89% rename from c-level-advisor/c-level-agents/skills/cto-review/SKILL.md rename to c-level-agents/skills/cto-review/SKILL.md index e28ee69a..99a85270 100644 --- a/c-level-advisor/c-level-agents/skills/cto-review/SKILL.md +++ b/c-level-agents/skills/cto-review/SKILL.md @@ -27,13 +27,13 @@ Pressure-tests architecture and engineering scaling decisions. Six questions to ### 2. Tech Debt Inventory **What's the top tech debt item, what's it costing per week, and when does it become blocking?** ```bash -python ../../../skills/cto-advisor/scripts/tech_debt_analyzer.py +python ../../../c-level-advisor/skills/cto-advisor/scripts/tech_debt_analyzer.py ``` ### 3. Team Scaling **For each open req, what's the ramp time and contribution model?** ```bash -python ../../../skills/cto-advisor/scripts/team_scaling_calculator.py +python ../../../c-level-advisor/skills/cto-advisor/scripts/team_scaling_calculator.py ``` ### 4. Build vs Buy @@ -108,9 +108,9 @@ python ../../../skills/cto-advisor/scripts/team_scaling_calculator.py ## Related -- Agent: [`cs-cto-advisor`](../../../../agents/c-level/cs-cto-advisor.md) -- Skill: [`cto-advisor`](../../../skills/cto-advisor/SKILL.md) -- SLO: `../../../../engineering/slo-architect/` +- Agent: [`cs-cto-advisor`](../../../agents/c-level/cs-cto-advisor.md) +- Skill: [`cto-advisor`](../../../c-level-advisor/skills/cto-advisor/SKILL.md) +- SLO: `../../../engineering/slo-architect/` --- diff --git a/c-level-advisor/c-level-agents/skills/decide/SKILL.md b/c-level-agents/skills/decide/SKILL.md similarity index 97% rename from c-level-advisor/c-level-agents/skills/decide/SKILL.md rename to c-level-agents/skills/decide/SKILL.md index 43d5b54b..fc5adc0c 100644 --- a/c-level-advisor/c-level-agents/skills/decide/SKILL.md +++ b/c-level-agents/skills/decide/SKILL.md @@ -95,7 +95,7 @@ The biggest risk in approved decisions is forgetting why someone disagreed. When ## Related -- Skill: [`decision-logger`](../../../skills/decision-logger/SKILL.md) +- Skill: [`decision-logger`](../../../c-level-advisor/skills/decision-logger/SKILL.md) - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) - Bridge: [`../../references/llm-wiki-bridge.md`](../../references/llm-wiki-bridge.md) diff --git a/c-level-advisor/c-level-agents/skills/execute/SKILL.md b/c-level-agents/skills/execute/SKILL.md similarity index 92% rename from c-level-advisor/c-level-agents/skills/execute/SKILL.md rename to c-level-agents/skills/execute/SKILL.md index dce7266d..8a4e4a5e 100644 --- a/c-level-advisor/c-level-agents/skills/execute/SKILL.md +++ b/c-level-agents/skills/execute/SKILL.md @@ -91,7 +91,7 @@ Saved to `~/.claude/execution/YYYY-MM-DD-.md`: ## Related -- Skills: [`coo-advisor`](../../../skills/coo-advisor/SKILL.md), [`strategic-alignment`](../../../skills/strategic-alignment/SKILL.md), [`change-management`](../../../skills/change-management/SKILL.md) +- Skills: [`coo-advisor`](../../../c-level-advisor/skills/coo-advisor/SKILL.md), [`strategic-alignment`](../../../c-level-advisor/skills/strategic-alignment/SKILL.md), [`change-management`](../../../c-level-advisor/skills/change-management/SKILL.md) - Agent: [`cs-coo-advisor`](../../agents/cs-coo-advisor.md) --- diff --git a/c-level-advisor/c-level-agents/skills/founder-mode/SKILL.md b/c-level-agents/skills/founder-mode/SKILL.md similarity index 95% rename from c-level-advisor/c-level-agents/skills/founder-mode/SKILL.md rename to c-level-agents/skills/founder-mode/SKILL.md index 89fbba96..76505ebf 100644 --- a/c-level-advisor/c-level-agents/skills/founder-mode/SKILL.md +++ b/c-level-agents/skills/founder-mode/SKILL.md @@ -100,8 +100,8 @@ gstack requires the founder to know all 23 slash commands and pick the right one ## Related - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) — does the routing -- Skill: [`chief-of-staff`](../../../skills/chief-of-staff/SKILL.md) — routing logic -- Skill: [`context-engine`](../../../skills/context-engine/SKILL.md) — loads context +- Skill: [`chief-of-staff`](../../../c-level-advisor/skills/chief-of-staff/SKILL.md) — routing logic +- Skill: [`context-engine`](../../../c-level-advisor/skills/context-engine/SKILL.md) — loads context --- diff --git a/c-level-advisor/c-level-agents/skills/freeze/SKILL.md b/c-level-agents/skills/freeze/SKILL.md similarity index 97% rename from c-level-advisor/c-level-agents/skills/freeze/SKILL.md rename to c-level-agents/skills/freeze/SKILL.md index 9b14684e..76d34a4a 100644 --- a/c-level-advisor/c-level-agents/skills/freeze/SKILL.md +++ b/c-level-agents/skills/freeze/SKILL.md @@ -93,7 +93,7 @@ Founders have authority. Without an explicit lock + log, every wobble produces a ## Related -- Skill: [`decision-logger`](../../../skills/decision-logger/SKILL.md) +- Skill: [`decision-logger`](../../../c-level-advisor/skills/decision-logger/SKILL.md) - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) — enforces freezes in routing --- diff --git a/c-level-advisor/c-level-agents/skills/gc-review/SKILL.md b/c-level-agents/skills/gc-review/SKILL.md similarity index 87% rename from c-level-advisor/c-level-agents/skills/gc-review/SKILL.md rename to c-level-agents/skills/gc-review/SKILL.md index dc9b7c73..fb6c34a1 100644 --- a/c-level-advisor/c-level-agents/skills/gc-review/SKILL.md +++ b/c-level-agents/skills/gc-review/SKILL.md @@ -108,24 +108,24 @@ The General Counsel lens. Six questions before any contract, term sheet, IP move ## Workflow Integration with `general-counsel-advisor` skill -Since v2.5.1, this command is backed by a full skill at `../../../skills/general-counsel-advisor/` with two Python tools: +Since v2.5.1, this command is backed by a full skill at `../../../c-level-advisor/skills/general-counsel-advisor/` with two Python tools: ```bash # Automated contract scan (12 founder-killer patterns) -python ../../../skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt +python ../../../c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py path/to/contract.txt # Term sheet scoring (0-100 founder-friendliness) -python ../../../skills/general-counsel-advisor/scripts/term_sheet_analyzer.py path/to/term_sheet.json +python ../../../c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py path/to/term_sheet.json ``` The `cs-general-counsel-advisor` agent orchestrates both tools plus 3 references (contracts playbook, IP + regulatory, term sheet decoder). ## Related -- Skill: [`general-counsel-advisor`](../../../skills/general-counsel-advisor/SKILL.md) — full skill with Python tools + references +- Skill: [`general-counsel-advisor`](../../../c-level-advisor/skills/general-counsel-advisor/SKILL.md) — full skill with Python tools + references - Agent: [`cs-general-counsel-advisor`](../../agents/cs-general-counsel-advisor.md) -- Compliance execution: `../../../../ra-qm-team/` -- Adjacent: `../../../skills/ma-playbook/` +- Compliance execution: `../../../ra-qm-team/` +- Adjacent: `../../../c-level-advisor/skills/ma-playbook/` --- diff --git a/c-level-advisor/c-level-agents/skills/office-hours/SKILL.md b/c-level-agents/skills/office-hours/SKILL.md similarity index 100% rename from c-level-advisor/c-level-agents/skills/office-hours/SKILL.md rename to c-level-agents/skills/office-hours/SKILL.md diff --git a/c-level-advisor/c-level-agents/skills/onboard/SKILL.md b/c-level-agents/skills/onboard/SKILL.md similarity index 80% rename from c-level-advisor/c-level-agents/skills/onboard/SKILL.md rename to c-level-agents/skills/onboard/SKILL.md index 47cbdef2..f23ecccc 100644 --- a/c-level-advisor/c-level-agents/skills/onboard/SKILL.md +++ b/c-level-agents/skills/onboard/SKILL.md @@ -40,7 +40,7 @@ The first command to run when adopting c-level-agents. A structured founder inte ## Output Format -**Canonical schema:** `~/.claude/company-context.md` is owned by the [`cs-onboard`](../../../skills/cs-onboard/SKILL.md) skill and follows its 7-dimension schema (`../../../skills/cs-onboard/templates/company-context-template.md`): Company Identity, Stage & Scale, Founder Profile, Team & Culture, Market & Competition, Current Challenges, Goals & Ambition. The 12 questions above are a faster structured intake that populates that same file — Identity/Business/Financial → Stage & Scale, Team → Team & Culture, Quarter priorities/risks → Current Challenges + Goals & Ambition. Write `[not captured]` for dimensions the quick intake doesn't reach (Founder Profile, Market & Competition); run the full `cs-onboard` interview to fill them. Never create a second context file or a divergent layout. +**Canonical schema:** `~/.claude/company-context.md` is owned by the [`cs-onboard`](../../../c-level-advisor/skills/cs-onboard/SKILL.md) skill and follows its 7-dimension schema (`../../../c-level-advisor/skills/cs-onboard/templates/company-context-template.md`): Company Identity, Stage & Scale, Founder Profile, Team & Culture, Market & Competition, Current Challenges, Goals & Ambition. The 12 questions above are a faster structured intake that populates that same file — Identity/Business/Financial → Stage & Scale, Team → Team & Culture, Quarter priorities/risks → Current Challenges + Goals & Ambition. Write `[not captured]` for dimensions the quick intake doesn't reach (Founder Profile, Market & Competition); run the full `cs-onboard` interview to fill them. Never create a second context file or a divergent layout. The intake summary captured by the 12 questions: @@ -117,8 +117,8 @@ By default, `~/.claude/company-context.md` is local to the founder's machine. To ## Related -- Skill: [`cs-onboard`](../../../skills/cs-onboard/SKILL.md) — the underlying interview protocol -- Skill: [`context-engine`](../../../skills/context-engine/SKILL.md) — reads this file +- Skill: [`cs-onboard`](../../../c-level-advisor/skills/cs-onboard/SKILL.md) — the underlying interview protocol +- Skill: [`context-engine`](../../../c-level-advisor/skills/context-engine/SKILL.md) — reads this file - Reference: [`../../references/llm-wiki-bridge.md`](../../references/llm-wiki-bridge.md) --- diff --git a/c-level-advisor/c-level-agents/skills/post-mortem/SKILL.md b/c-level-agents/skills/post-mortem/SKILL.md similarity index 94% rename from c-level-advisor/c-level-agents/skills/post-mortem/SKILL.md rename to c-level-agents/skills/post-mortem/SKILL.md index 37d7245a..7591fd9d 100644 --- a/c-level-advisor/c-level-agents/skills/post-mortem/SKILL.md +++ b/c-level-agents/skills/post-mortem/SKILL.md @@ -106,9 +106,9 @@ The dissent column from `/cs:boardroom` is the single most useful piece of organ ## Related -- Skill: [`decision-logger`](../../../skills/decision-logger/SKILL.md) +- Skill: [`decision-logger`](../../../c-level-advisor/skills/decision-logger/SKILL.md) - Agent: [`cs-chief-of-staff`](../../agents/cs-chief-of-staff.md) -- Sibling: [`/em:postmortem`](../../../executive-mentor/skills/postmortem/SKILL.md) — adversarial single-decision post-mortem +- Sibling: [`/em:postmortem`](../../../c-level-advisor/executive-mentor/skills/postmortem/SKILL.md) — adversarial single-decision post-mortem --- diff --git a/c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md b/c-level-agents/skills/vpe-review/SKILL.md similarity index 88% rename from c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md rename to c-level-agents/skills/vpe-review/SKILL.md index ee73496d..da3cccca 100644 --- a/c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md +++ b/c-level-agents/skills/vpe-review/SKILL.md @@ -61,13 +61,13 @@ The throughput-first VPE pressure-tests any plan touching eng operations. Six qu ```bash # 1. Delivery throughput -python ../../../skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json +python ../../../c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py sprint_metrics.json # 2. Hiring funnel -python ../../../skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json +python ../../../c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py funnel.json # 3. Team structure -python ../../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json +python ../../../c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py team.json ``` ## Output Format @@ -121,8 +121,8 @@ python ../../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.j ## Related - Agent: [`cs-vpe-advisor`](../../agents/cs-vpe-advisor.md) -- Skill: [`vpe-advisor`](../../../skills/vpe-advisor/SKILL.md) -- Adjacent: `../../../../engineering/slo-architect/`, `../../../../engineering/feature-flags-architect/`, `../../../../engineering/chaos-engineering/` +- Skill: [`vpe-advisor`](../../../c-level-advisor/skills/vpe-advisor/SKILL.md) +- Adjacent: `../../../engineering/slo-architect/`, `../../../engineering/feature-flags-architect/`, `../../../engineering/chaos-engineering/` --- diff --git a/commercial/.claude-plugin/authoring-notes.json b/commercial/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..ce178774 --- /dev/null +++ b/commercial/.claude-plugin/authoring-notes.json @@ -0,0 +1,7 @@ +{ + "source": { + "spec": "documentation/implementation/bizops-commercial-expansion-plan.md", + "build_pattern": "Path B (direct conversion) — orchestrator skill uses context: fork. Sprint 1 shipped orchestrator + 2 sub-skills (pricing-strategist, deal-desk). Sprint 2 adds partnerships-architect (5-tier + joint GTM + revshare), channel-economics (cost-to-serve + ROI + mix), commercial-policy (discount matrix + exception flow + linter), rfp-responder (Shipley structured response, context: fork for heavy intake), commercial-forecaster (4Q-weighted with mandatory assumption disclosure). Every SKILL.md ships a Forcing-question library section per Matt Pocock grill-with-docs discipline.", + "distinct_from": "business-growth/sales-engineer (technical sale: demos, POCs). business-growth/revenue-operations (lead routing, SDR motion). business-growth/contract-and-proposal-writer (free-form authoring, not buyer-dictated structured response). c-level-advisor/cro-advisor (strategic 'when to hire VP Sales' calls, not per-deal approval). finance/financial-analysis (close + report, not forward forecast or per-deal economics)." + } +} diff --git a/commercial/.claude-plugin/plugin.json b/commercial/.claude-plugin/plugin.json index dc13a643..55a90f58 100644 --- a/commercial/.claude-plugin/plugin.json +++ b/commercial/.claude-plugin/plugin.json @@ -18,10 +18,5 @@ "./skills/commercial-policy", "./skills/rfp-responder", "./skills/commercial-forecaster" - ], - "source": { - "spec": "documentation/implementation/bizops-commercial-expansion-plan.md", - "build_pattern": "Path B (direct conversion) — orchestrator skill uses context: fork. Sprint 1 shipped orchestrator + 2 sub-skills (pricing-strategist, deal-desk). Sprint 2 adds partnerships-architect (5-tier + joint GTM + revshare), channel-economics (cost-to-serve + ROI + mix), commercial-policy (discount matrix + exception flow + linter), rfp-responder (Shipley structured response, context: fork for heavy intake), commercial-forecaster (4Q-weighted with mandatory assumption disclosure). Every SKILL.md ships a Forcing-question library section per Matt Pocock grill-with-docs discipline.", - "distinct_from": "business-growth/sales-engineer (technical sale: demos, POCs). business-growth/revenue-operations (lead routing, SDR motion). business-growth/contract-and-proposal-writer (free-form authoring, not buyer-dictated structured response). c-level-advisor/cro-advisor (strategic 'when to hire VP Sales' calls, not per-deal approval). finance/financial-analysis (close + report, not forward forecast or per-deal economics)." - } + ] } diff --git a/commercial/commands/cs-commercial.md b/commercial/commands/cs-commercial.md index c31e0fdc..ef494855 100644 --- a/commercial/commands/cs-commercial.md +++ b/commercial/commands/cs-commercial.md @@ -1,5 +1,5 @@ --- -description: Top-level Commercial router. Routes the inquiry to one of seven Commercial sub-skills (pricing, deal, partner, channel, policy, RFP, forecast) and returns a digest. Invokes the commercial-skills orchestrator (context: fork). +description: "Top-level Commercial router. Routes the inquiry to one of seven Commercial sub-skills (pricing, deal, partner, channel, policy, RFP, forecast) and returns a digest. Invokes the commercial-skills orchestrator (context: fork)." argument-hint: "" --- diff --git a/compliance-os/agents/cs-ai-act-compliance.md b/compliance-os/agents/cs-ai-act-compliance.md index 6b0634a3..2796d38c 100644 --- a/compliance-os/agents/cs-ai-act-compliance.md +++ b/compliance-os/agents/cs-ai-act-compliance.md @@ -1,6 +1,6 @@ --- name: cs-ai-act-compliance -description: EU AI Act (Regulation (EU) 2024/1689) Article-cited compliance operator. Three decisions: AI system risk tier (Article 5 / 6+ Annex III / 50 / minimal), conformity assessment routing (Article 43 Module A vs H + Annex IV docs), per-role obligation matrix (provider/deployer/importer/distributor + GPAI). NOT executive AI strategy (see cs-caio-advisor). NOT a legal substitute (engage counsel for novel cases). +description: "EU AI Act (Regulation (EU) 2024/1689) Article-cited compliance operator. Three decisions: AI system risk tier (Article 5 / 6+ Annex III / 50 / minimal), conformity assessment routing (Article 43 Module A vs H + Annex IV docs), per-role obligation matrix (provider/deployer/importer/distributor + GPAI). NOT executive AI strategy (see cs-caio-advisor). NOT a legal substitute (engage counsel for novel cases)." skills: ra-qm-team/skills/eu-ai-act-specialist domain: compliance-os model: opus @@ -123,8 +123,8 @@ python conformity_assessment_planner.py system.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for EU AI Act deep work) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS specialist -- [cs-caio-advisor](../../c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy -- [cs-general-counsel-advisor](../../c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review +- [cs-caio-advisor](../../c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy +- [cs-general-counsel-advisor](../../c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review ## References diff --git a/compliance-os/agents/cs-aims-iso42001.md b/compliance-os/agents/cs-aims-iso42001.md index 0bec3f4f..cedc9386 100644 --- a/compliance-os/agents/cs-aims-iso42001.md +++ b/compliance-os/agents/cs-aims-iso42001.md @@ -1,6 +1,6 @@ --- name: cs-aims-iso42001 -description: ISO/IEC 42001:2023 AI Management System (AIMS) implementation + internal audit operator. Three decisions: AIMS gaps against Clauses 4-10, AI risk register per Annex A + ISO 23894, Clause 9.2 internal audit plan. NOT executive AI strategy (see cs-caio-advisor). NOT EU AI Act conformity (see cs-ai-act-compliance). +description: "ISO/IEC 42001:2023 AI Management System (AIMS) implementation + internal audit operator. Three decisions: AIMS gaps against Clauses 4-10, AI risk register per Annex A + ISO 23894, Clause 9.2 internal audit plan. NOT executive AI strategy (see cs-caio-advisor). NOT EU AI Act conformity (see cs-ai-act-compliance)." skills: ra-qm-team/skills/iso42001-specialist domain: compliance-os model: opus @@ -115,8 +115,8 @@ python aims_audit_scheduler.py audit_scope.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for ISO 42001 deep work) - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article-cited compliance -- [cs-caio-advisor](../../c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy -- [cs-ciso-advisor](../../c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity (ISO 27001 / SOC 2 strategy) +- [cs-caio-advisor](../../c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy +- [cs-ciso-advisor](../../c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity (ISO 27001 / SOC 2 strategy) - [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device QMS / regulatory orchestrator ## References diff --git a/compliance-os/agents/cs-ciso-iso27001.md b/compliance-os/agents/cs-ciso-iso27001.md index 77c0a3de..af5a54ee 100644 --- a/compliance-os/agents/cs-ciso-iso27001.md +++ b/compliance-os/agents/cs-ciso-iso27001.md @@ -121,7 +121,7 @@ python isms_audit_scheduler.py surveillance_scope.json - [cs-soc2-auditor](cs-soc2-auditor.md) — SOC 2 Type II auditor (75% overlap with 27001) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS auditor (60% reuse from 27001) - [cs-dpo-gdpr](cs-dpo-gdpr.md) — GDPR DPO (Article 32 = 27001 Annex A overlap) -- [cs-ciso-advisor](../../c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-ciso-advisor](../../c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/compliance-os/agents/cs-compliance-officer.md b/compliance-os/agents/cs-compliance-officer.md index c7c96069..91290132 100644 --- a/compliance-os/agents/cs-compliance-officer.md +++ b/compliance-os/agents/cs-compliance-officer.md @@ -183,9 +183,9 @@ python ../skills/compliance-os/scripts/evidence_pool_generator.py program.json - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 deep-dive specialist (paired with iso42001-specialist skill) - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article-cited operations (paired with eu-ai-act-specialist skill) - [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device-focused QMS / regulatory orchestrator (compliance-officer is broader; quality-regulatory is medical-device deep) -- [cs-caio-advisor](../../c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy (build-vs-buy, model selection) -- [cs-general-counsel-advisor](../../c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Legal exposure (contracts, IP) -- [cs-ciso-advisor](../../c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-caio-advisor](../../c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy (build-vs-buy, model selection) +- [cs-general-counsel-advisor](../../c-level-agents/agents/cs-general-counsel-advisor.md) — Legal exposure (contracts, IP) +- [cs-ciso-advisor](../../c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/compliance-os/agents/cs-cqm-iso13485.md b/compliance-os/agents/cs-cqm-iso13485.md index b6573e19..d84cd87a 100644 --- a/compliance-os/agents/cs-cqm-iso13485.md +++ b/compliance-os/agents/cs-cqm-iso13485.md @@ -130,7 +130,7 @@ python audit_schedule_optimizer.py audit_scope.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for ISO 13485 audit) - [cs-fda-qsr-auditor](cs-fda-qsr-auditor.md) — FDA QSR auditor (substantially harmonized post-Feb 2026) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS (for AI-enabled medical devices, layer on top of 13485) -- [cs-cpo-advisor](../../c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md) — Executive product strategy +- [cs-cpo-advisor](../../c-level-agents/agents/cs-cpo-advisor.md) — Executive product strategy - [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device orchestrator (routes here for audit work) ## References diff --git a/compliance-os/agents/cs-dpo-gdpr.md b/compliance-os/agents/cs-dpo-gdpr.md index eec24f3d..dc9e4575 100644 --- a/compliance-os/agents/cs-dpo-gdpr.md +++ b/compliance-os/agents/cs-dpo-gdpr.md @@ -144,7 +144,7 @@ python dpia_generator.py processing_activity.json - [cs-ciso-iso27001](cs-ciso-iso27001.md) — Article 32 organizational measures overlap - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article 27 FRIA integration - [cs-soc2-auditor](cs-soc2-auditor.md) — SOC 2 Privacy TSC overlap -- [cs-general-counsel-advisor](../../c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review +- [cs-general-counsel-advisor](../../c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review ## References diff --git a/compliance-os/agents/cs-fda-qsr-auditor.md b/compliance-os/agents/cs-fda-qsr-auditor.md index 3bcaa986..a1e87ee6 100644 --- a/compliance-os/agents/cs-fda-qsr-auditor.md +++ b/compliance-os/agents/cs-fda-qsr-auditor.md @@ -1,6 +1,6 @@ --- name: cs-fda-qsr-auditor -description: FDA 21 CFR 820 (QSR / QMSR) auditor persona. Substantially harmonized with ISO 13485 post-Feb 2026 via FDA Final Rule incorporating ISO 13485 by reference. Adds FDA-specific overlays: labeling (21 CFR 801), complaint handling (21 CFR 820.198), MDR reporting (21 CFR 803), 510(k) / PMA submissions. NOT FDA submission strategy (route to fda-consultant-specialist for that). +description: "FDA 21 CFR 820 (QSR / QMSR) auditor persona. Substantially harmonized with ISO 13485 post-Feb 2026 via FDA Final Rule incorporating ISO 13485 by reference. Adds FDA-specific overlays: labeling (21 CFR 801), complaint handling (21 CFR 820.198), MDR reporting (21 CFR 803), 510(k) / PMA submissions. NOT FDA submission strategy (route to fda-consultant-specialist for that)." skills: ra-qm-team/skills/fda-consultant-specialist domain: compliance-os model: opus @@ -152,7 +152,7 @@ python ../../compliance-os/skills/compliance-os/scripts/audit_simulator.py fda_q - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator - [cs-cqm-iso13485](cs-cqm-iso13485.md) — ISO 13485 audit (substantially harmonized post-Feb 2026) - [cs-quality-regulatory](../../agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device orchestrator -- [cs-general-counsel-advisor](../../c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Warning Letter response coordination +- [cs-general-counsel-advisor](../../c-level-agents/agents/cs-general-counsel-advisor.md) — Warning Letter response coordination ## References diff --git a/compliance-os/agents/cs-soc2-auditor.md b/compliance-os/agents/cs-soc2-auditor.md index 4dc27a25..452ce12e 100644 --- a/compliance-os/agents/cs-soc2-auditor.md +++ b/compliance-os/agents/cs-soc2-auditor.md @@ -138,7 +138,7 @@ python ../../compliance-os/skills/compliance-os/scripts/audit_simulator.py soc2_ - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator - [cs-ciso-iso27001](cs-ciso-iso27001.md) — ISO 27001 audit (75% cross-walk pair) - [cs-dpo-gdpr](cs-dpo-gdpr.md) — GDPR (Privacy TSC overlap) -- [cs-ciso-advisor](../../c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-ciso-advisor](../../c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/docs/agents/cs-ai-act-compliance.md b/docs/agents/cs-ai-act-compliance.md index 790b3dfc..add6db4a 100644 --- a/docs/agents/cs-ai-act-compliance.md +++ b/docs/agents/cs-ai-act-compliance.md @@ -126,8 +126,8 @@ python conformity_assessment_planner.py system.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for EU AI Act deep work) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS specialist -- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy -- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review +- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy +- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review ## References diff --git a/docs/agents/cs-aims-iso42001.md b/docs/agents/cs-aims-iso42001.md index 0204db71..4cfe0006 100644 --- a/docs/agents/cs-aims-iso42001.md +++ b/docs/agents/cs-aims-iso42001.md @@ -118,8 +118,8 @@ python aims_audit_scheduler.py audit_scope.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for ISO 42001 deep work) - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article-cited compliance -- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy -- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity (ISO 27001 / SOC 2 strategy) +- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy +- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity (ISO 27001 / SOC 2 strategy) - [cs-quality-regulatory](https://github.com/alirezarezvani/claude-skills/tree/main/agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device QMS / regulatory orchestrator ## References diff --git a/docs/agents/cs-backend-engineer.md b/docs/agents/cs-backend-engineer.md index 0b2ce730..814abd6e 100644 --- a/docs/agents/cs-backend-engineer.md +++ b/docs/agents/cs-backend-engineer.md @@ -126,8 +126,8 @@ python ../../engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surge - [cs-frontend-engineer](cs-frontend-engineer.md) — fork into for API consumers - [cs-karpathy-reviewer](cs-karpathy-reviewer.md) — invoke before every commit - [cs-cto-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/agents/c-level/cs-cto-advisor.md) — escalate strategic build-vs-buy -- [cs-vpe-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md) — escalate throughput / org / DORA -- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — escalate regulated-data exposure +- [cs-vpe-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-vpe-advisor.md) — escalate throughput / org / DORA +- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) — escalate regulated-data exposure ## Invocation Contract diff --git a/docs/agents/cs-caio-advisor.md b/docs/agents/cs-caio-advisor.md index f088874f..73aebbba 100644 --- a/docs/agents/cs-caio-advisor.md +++ b/docs/agents/cs-caio-advisor.md @@ -8,7 +8,7 @@ description: "Eval-demanding Chief AI Officer advisor for model build-vs-buy dec
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -170,8 +170,8 @@ python ../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py worklo ## References - Skill: [../../skills/chief-ai-officer-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-ai-officer-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- Sibling command: [`/cs:caio-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/skills/caio-review/SKILL.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- Sibling command: [`/cs:caio-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/skills/caio-review/SKILL.md) --- diff --git a/docs/agents/cs-capture.md b/docs/agents/cs-capture.md index b27a2d86..130e8524 100644 --- a/docs/agents/cs-capture.md +++ b/docs/agents/cs-capture.md @@ -203,7 +203,7 @@ Which should I tackle? ## References - Skill: [../skills/capture/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/capture/skills/capture/SKILL.md) -- Source spec: [`megaprompts/05-capture-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/05-capture-megaprompt.md) +- Source spec: `megaprompts/05-capture-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:capture`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/capture/commands/cs-capture.md) --- diff --git a/docs/agents/cs-cco-advisor.md b/docs/agents/cs-cco-advisor.md index 888d9b5f..8dcc5f41 100644 --- a/docs/agents/cs-cco-advisor.md +++ b/docs/agents/cs-cco-advisor.md @@ -8,7 +8,7 @@ description: "Retention-obsessed Chief Customer Officer advisor for honest reten
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -168,8 +168,8 @@ python ../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calculato ## References - Skill: [../../skills/chief-customer-officer-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-customer-officer-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- Sibling command: [`/cs:cco-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/skills/cco-review/SKILL.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- Sibling command: [`/cs:cco-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/skills/cco-review/SKILL.md) --- diff --git a/docs/agents/cs-cdo-advisor.md b/docs/agents/cs-cdo-advisor.md index 8ecc82ad..2563829c 100644 --- a/docs/agents/cs-cdo-advisor.md +++ b/docs/agents/cs-cdo-advisor.md @@ -8,7 +8,7 @@ description: "Decision-driven Chief Data Officer advisor for AI training data ri
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -157,8 +157,8 @@ echo "Kill criteria + checkpoint dates in each output." ## References - Skill: [../../skills/chief-data-officer-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-data-officer-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- Sibling command: [`/cs:cdo-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/skills/cdo-review/SKILL.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- Sibling command: [`/cs:cdo-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/skills/cdo-review/SKILL.md) --- diff --git a/docs/agents/cs-cfo-advisor.md b/docs/agents/cs-cfo-advisor.md index 83aa6f32..1d01f965 100644 --- a/docs/agents/cs-cfo-advisor.md +++ b/docs/agents/cs-cfo-advisor.md @@ -8,7 +8,7 @@ description: "Numerate-skeptic CFO advisor for unit economics, runway, fundraisi
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -125,7 +125,7 @@ echo "Artifacts ready in /tmp/. Feed into /cs:boardroom brief." ## References - Skill: [../../skills/cfo-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cfo-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) - Domain guide: [../../CLAUDE.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/CLAUDE.md) --- diff --git a/docs/agents/cs-chief-of-staff.md b/docs/agents/cs-chief-of-staff.md index 2b001f45..dd4b12c9 100644 --- a/docs/agents/cs-chief-of-staff.md +++ b/docs/agents/cs-chief-of-staff.md @@ -8,7 +8,7 @@ description: "Routing-and-synthesis chief of staff for orchestrating the virtual
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -128,7 +128,7 @@ echo "Decision logged to ~/.claude/decisions/raw/$(date +%Y-%m-%d)-$RANDOM.md" ## References - Skill: [../../skills/chief-of-staff/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-of-staff/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) - Decision-logger: [../../skills/decision-logger/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/decision-logger/SKILL.md) --- diff --git a/docs/agents/cs-chro-advisor.md b/docs/agents/cs-chro-advisor.md index 0f78fdc4..e1127420 100644 --- a/docs/agents/cs-chro-advisor.md +++ b/docs/agents/cs-chro-advisor.md @@ -8,7 +8,7 @@ description: "People-systems CHRO advisor for hiring strategy, comp bands, level
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -116,7 +116,7 @@ echo "Ladder reference: ../../skills/chro-advisor/references/org_design.md" ## References - Skill: [../../skills/chro-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chro-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-ciso-advisor.md b/docs/agents/cs-ciso-advisor.md index 6940ce6d..a7c0ff0f 100644 --- a/docs/agents/cs-ciso-advisor.md +++ b/docs/agents/cs-ciso-advisor.md @@ -8,7 +8,7 @@ description: "Risk-paranoid CISO advisor for threat modeling, compliance, incide
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -121,7 +121,7 @@ echo "IR runbook check: ../../skills/ciso-advisor/references/incident_response.m ## References - Skill: [../../skills/ciso-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/ciso-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-ciso-iso27001.md b/docs/agents/cs-ciso-iso27001.md index 7abec904..ce1edbfa 100644 --- a/docs/agents/cs-ciso-iso27001.md +++ b/docs/agents/cs-ciso-iso27001.md @@ -124,7 +124,7 @@ python isms_audit_scheduler.py surveillance_scope.json - [cs-soc2-auditor](cs-soc2-auditor.md) — SOC 2 Type II auditor (75% overlap with 27001) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS auditor (60% reuse from 27001) - [cs-dpo-gdpr](cs-dpo-gdpr.md) — GDPR DPO (Article 32 = 27001 Annex A overlap) -- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/docs/agents/cs-cmo-advisor.md b/docs/agents/cs-cmo-advisor.md index 6e3625c4..9f1a7629 100644 --- a/docs/agents/cs-cmo-advisor.md +++ b/docs/agents/cs-cmo-advisor.md @@ -8,7 +8,7 @@ description: "Narrative-first CMO advisor for ICP definition, positioning, messa
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -120,7 +120,7 @@ echo "📚 Reference: positioning + playbooks" ## References - Skill: [../../skills/cmo-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cmo-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-compliance-officer.md b/docs/agents/cs-compliance-officer.md index 16f70e78..590e176b 100644 --- a/docs/agents/cs-compliance-officer.md +++ b/docs/agents/cs-compliance-officer.md @@ -186,9 +186,9 @@ python ../skills/compliance-os/scripts/evidence_pool_generator.py program.json - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 deep-dive specialist (paired with iso42001-specialist skill) - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article-cited operations (paired with eu-ai-act-specialist skill) - [cs-quality-regulatory](https://github.com/alirezarezvani/claude-skills/tree/main/agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device-focused QMS / regulatory orchestrator (compliance-officer is broader; quality-regulatory is medical-device deep) -- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy (build-vs-buy, model selection) -- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Legal exposure (contracts, IP) -- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-caio-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-caio-advisor.md) — Executive AI strategy (build-vs-buy, model selection) +- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-general-counsel-advisor.md) — Legal exposure (contracts, IP) +- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/docs/agents/cs-coo-advisor.md b/docs/agents/cs-coo-advisor.md index 83837792..f3769486 100644 --- a/docs/agents/cs-coo-advisor.md +++ b/docs/agents/cs-coo-advisor.md @@ -8,7 +8,7 @@ description: "Execution-OS COO advisor for operating cadence, OKRs, scorecards,
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -121,7 +121,7 @@ echo "Reference: ../../skills/coo-advisor/references/ops_cadence.md" ## References - Skill: [../../skills/coo-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/coo-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-cpo-advisor.md b/docs/agents/cs-cpo-advisor.md index 6eee4731..247e83ac 100644 --- a/docs/agents/cs-cpo-advisor.md +++ b/docs/agents/cs-cpo-advisor.md @@ -8,7 +8,7 @@ description: "JTBD-driven CPO advisor for product vision, portfolio strategy, PM
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -120,7 +120,7 @@ echo "Pair with RICE: python ../../../product-team/skills/product-manager-toolki ## References - Skill: [../../skills/cpo-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cpo-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-cqm-iso13485.md b/docs/agents/cs-cqm-iso13485.md index ab00be1b..faaeaa36 100644 --- a/docs/agents/cs-cqm-iso13485.md +++ b/docs/agents/cs-cqm-iso13485.md @@ -133,7 +133,7 @@ python audit_schedule_optimizer.py audit_scope.json - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator (routes here for ISO 13485 audit) - [cs-fda-qsr-auditor](cs-fda-qsr-auditor.md) — FDA QSR auditor (substantially harmonized post-Feb 2026) - [cs-aims-iso42001](cs-aims-iso42001.md) — ISO 42001 AIMS (for AI-enabled medical devices, layer on top of 13485) -- [cs-cpo-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md) — Executive product strategy +- [cs-cpo-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cpo-advisor.md) — Executive product strategy - [cs-quality-regulatory](https://github.com/alirezarezvani/claude-skills/tree/main/agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device orchestrator (routes here for audit work) ## References diff --git a/docs/agents/cs-cro-advisor.md b/docs/agents/cs-cro-advisor.md index f1f1b6f4..0e4c30c6 100644 --- a/docs/agents/cs-cro-advisor.md +++ b/docs/agents/cs-cro-advisor.md @@ -8,7 +8,7 @@ description: "Pipeline-paranoid CRO advisor for revenue forecasting, sales motio
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -117,7 +117,7 @@ echo "Pipeline coverage and retention dashboard ready." ## References - Skill: [../../skills/cro-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cro-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) --- diff --git a/docs/agents/cs-dpo-gdpr.md b/docs/agents/cs-dpo-gdpr.md index 2e515d15..ed878e09 100644 --- a/docs/agents/cs-dpo-gdpr.md +++ b/docs/agents/cs-dpo-gdpr.md @@ -147,7 +147,7 @@ python dpia_generator.py processing_activity.json - [cs-ciso-iso27001](cs-ciso-iso27001.md) — Article 32 organizational measures overlap - [cs-ai-act-compliance](cs-ai-act-compliance.md) — EU AI Act Article 27 FRIA integration - [cs-soc2-auditor](cs-soc2-auditor.md) — SOC 2 Privacy TSC overlap -- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review +- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-general-counsel-advisor.md) — Novel-case legal review ## References diff --git a/docs/agents/cs-fda-qsr-auditor.md b/docs/agents/cs-fda-qsr-auditor.md index ef01f110..8e8fba70 100644 --- a/docs/agents/cs-fda-qsr-auditor.md +++ b/docs/agents/cs-fda-qsr-auditor.md @@ -155,7 +155,7 @@ python ../../compliance-os/skills/compliance-os/scripts/audit_simulator.py fda_q - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator - [cs-cqm-iso13485](cs-cqm-iso13485.md) — ISO 13485 audit (substantially harmonized post-Feb 2026) - [cs-quality-regulatory](https://github.com/alirezarezvani/claude-skills/tree/main/agents/ra-qm-team/cs-quality-regulatory.md) — Medical-device orchestrator -- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) — Warning Letter response coordination +- [cs-general-counsel-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-general-counsel-advisor.md) — Warning Letter response coordination ## References diff --git a/docs/agents/cs-fullstack-engineer.md b/docs/agents/cs-fullstack-engineer.md index 244a2c6b..25d980db 100644 --- a/docs/agents/cs-fullstack-engineer.md +++ b/docs/agents/cs-fullstack-engineer.md @@ -166,7 +166,7 @@ python ../../engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surge - [cs-karpathy-reviewer](cs-karpathy-reviewer.md) — invoke before every commit - [cs-senior-engineer](cs-senior-engineer.md) — cross-cutting engineering lead (use for non-stack questions like CI/CD, security review) - [cs-cto-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/agents/c-level/cs-cto-advisor.md) — escalate for strategic build-vs-buy or technical debt prioritization -- [cs-vpe-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md) — escalate for org-design + throughput +- [cs-vpe-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-vpe-advisor.md) — escalate for org-design + throughput ## Invocation Contract diff --git a/docs/agents/cs-general-counsel-advisor.md b/docs/agents/cs-general-counsel-advisor.md index 9757ffff..f870c73f 100644 --- a/docs/agents/cs-general-counsel-advisor.md +++ b/docs/agents/cs-general-counsel-advisor.md @@ -8,7 +8,7 @@ description: "Risk-paranoid General Counsel advisor for contract review, IP stra
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -161,8 +161,8 @@ echo " ☐ /cs:freeze applied if irreversible (term sheet, M&A LOI, employment ## References - Skill: [../../skills/general-counsel-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/general-counsel-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- Sibling command: [`/cs:gc-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/skills/gc-review/SKILL.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- Sibling command: [`/cs:gc-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/skills/gc-review/SKILL.md) --- diff --git a/docs/agents/cs-inbox-setup.md b/docs/agents/cs-inbox-setup.md index 3ce9b5ce..3f5cdbdf 100644 --- a/docs/agents/cs-inbox-setup.md +++ b/docs/agents/cs-inbox-setup.md @@ -200,7 +200,7 @@ Re-run /cs:inbox-setup when business/pricing/priorities change. ## References - Skill: [../skills/inbox-setup/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/skills/inbox-setup/SKILL.md) -- Source spec: [`megaprompts/06-inbox-setup-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/../megaprompts/06-inbox-setup-megaprompt.md) +- Source spec: `megaprompts/06-inbox-setup-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:inbox-setup`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/commands/cs-inbox-setup.md) --- diff --git a/docs/agents/cs-inbox-triage.md b/docs/agents/cs-inbox-triage.md index c3113c79..7103dec6 100644 --- a/docs/agents/cs-inbox-triage.md +++ b/docs/agents/cs-inbox-triage.md @@ -203,7 +203,7 @@ Generated at . KB updated: {N blocklist, M tracker}. ## References - Skill: [../skills/inbox-triage/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/skills/inbox-triage/SKILL.md) -- Source spec: [`megaprompts/07-inbox-triage-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/../megaprompts/07-inbox-triage-megaprompt.md) +- Source spec: `megaprompts/07-inbox-triage-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:inbox-triage`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/commands/cs-inbox-triage.md) --- diff --git a/docs/agents/cs-landing.md b/docs/agents/cs-landing.md index 6c53456a..285a475b 100644 --- a/docs/agents/cs-landing.md +++ b/docs/agents/cs-landing.md @@ -172,7 +172,7 @@ Instead of writing to ./landing-pages/.html: ## References - Skill: [../skills/landing/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/marketing/landing/skills/landing/SKILL.md) -- Source spec: [`megaprompts/04-landing-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/04-landing-megaprompt.md) +- Source spec: `megaprompts/04-landing-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:landing`](https://github.com/alirezarezvani/claude-skills/tree/main/marketing/landing/commands/cs-landing.md) --- diff --git a/docs/agents/cs-litreview.md b/docs/agents/cs-litreview.md index 8d084fc8..a7cabc47 100644 --- a/docs/agents/cs-litreview.md +++ b/docs/agents/cs-litreview.md @@ -164,7 +164,7 @@ research_guide_{topic-slug}_{date}.docx ## References - Skill: [../skills/litreview/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/research/litreview/skills/litreview/SKILL.md) -- Source spec: [`megaprompts/09-litreview-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/09-litreview-megaprompt.md) +- Source spec: `megaprompts/09-litreview-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:litreview`](https://github.com/alirezarezvani/claude-skills/tree/main/research/litreview/commands/cs-litreview.md) --- diff --git a/docs/agents/cs-pulse.md b/docs/agents/cs-pulse.md index 44f835c7..56a66d38 100644 --- a/docs/agents/cs-pulse.md +++ b/docs/agents/cs-pulse.md @@ -194,7 +194,7 @@ python ../skills/pulse/scripts/citation_tracker.py --action close --session NAME ## References - Skill: [../skills/pulse/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/research/pulse/skills/pulse/SKILL.md) -- Source spec: [`megaprompts/01-pulse-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/01-pulse-megaprompt.md) +- Source spec: `megaprompts/01-pulse-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling command: [`/cs:pulse`](https://github.com/alirezarezvani/claude-skills/tree/main/research/pulse/commands/cs-pulse.md) --- diff --git a/docs/agents/cs-soc2-auditor.md b/docs/agents/cs-soc2-auditor.md index f6d1f245..482ed248 100644 --- a/docs/agents/cs-soc2-auditor.md +++ b/docs/agents/cs-soc2-auditor.md @@ -141,7 +141,7 @@ python ../../compliance-os/skills/compliance-os/scripts/audit_simulator.py soc2_ - [cs-compliance-officer](cs-compliance-officer.md) — Multi-framework orchestrator - [cs-ciso-iso27001](cs-ciso-iso27001.md) — ISO 27001 audit (75% cross-walk pair) - [cs-dpo-gdpr](cs-dpo-gdpr.md) — GDPR (Privacy TSC overlap) -- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy +- [cs-ciso-advisor](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) — Executive cybersecurity strategy ## References diff --git a/docs/agents/cs-vpe-advisor.md b/docs/agents/cs-vpe-advisor.md index 7f814722..f1f3105d 100644 --- a/docs/agents/cs-vpe-advisor.md +++ b/docs/agents/cs-vpe-advisor.md @@ -8,7 +8,7 @@ description: "Throughput-first VP of Engineering advisor for delivery throughput
:material-robot: Agent :material-account-tie: C-Level Advisory -:material-github: Source +:material-github: Source
@@ -157,8 +157,8 @@ python ../../skills/vpe-advisor/scripts/eng_team_structure_designer.py current-t ## References - Skill: [../../skills/vpe-advisor/SKILL.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/vpe-advisor/SKILL.md) -- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- Sibling command: [`/cs:vpe-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/skills/vpe-review/SKILL.md) +- Voice spec: [../references/persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- Sibling command: [`/cs:vpe-review`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/skills/vpe-review/SKILL.md) --- diff --git a/docs/commands/cs-capture.md b/docs/commands/cs-capture.md index 413894b1..197bdbf1 100644 --- a/docs/commands/cs-capture.md +++ b/docs/commands/cs-capture.md @@ -105,7 +105,7 @@ python ../skills/capture/scripts/workspace_inventory.py \ - Agent: [`cs-capture`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/capture/agents/cs-capture.md) - Skill: [`capture`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/capture/skills/capture/SKILL.md) -- Source spec: [`megaprompts/05-capture-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/05-capture-megaprompt.md) +- Source spec: `megaprompts/05-capture-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Adjacent commands: `/cs:grill-me` (slow deliberate plan grill), `/cs:grill-with-docs` (docs-anchored grill), `/cs:handoff` (session continuation) --- diff --git a/docs/commands/cs-dossier.md b/docs/commands/cs-dossier.md index 9481285a..dc0abcf0 100644 --- a/docs/commands/cs-dossier.md +++ b/docs/commands/cs-dossier.md @@ -137,7 +137,7 @@ Every fact in the DOCX tagged with tier (primary / secondary / tertiary): - Agent: [`cs-dossier`](https://github.com/alirezarezvani/claude-skills/tree/main/research/dossier/agents/cs-dossier.md) - Skill: [`dossier`](https://github.com/alirezarezvani/claude-skills/tree/main/research/dossier/skills/dossier/SKILL.md) -- Source spec: [`megaprompts/12-dossier-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/12-dossier-megaprompt.md) +- Source spec: `megaprompts/12-dossier-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Siblings: `/cs:litreview`, `/cs:grants`, `/cs:pulse` - Future: `/cs:patent`, `/cs:syllabus` diff --git a/docs/commands/cs-grants.md b/docs/commands/cs-grants.md index 5e7fc00f..e57689ef 100644 --- a/docs/commands/cs-grants.md +++ b/docs/commands/cs-grants.md @@ -125,7 +125,7 @@ grants__.docx - Agent: [`cs-grants`](https://github.com/alirezarezvani/claude-skills/tree/main/research/grants/agents/cs-grants.md) - Skill: [`grants`](https://github.com/alirezarezvani/claude-skills/tree/main/research/grants/skills/grants/SKILL.md) -- Source spec: [`megaprompts/08-grants-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/08-grants-megaprompt.md) +- Source spec: `megaprompts/08-grants-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling: `/cs:litreview` (academic literature, no RePORTER) --- diff --git a/docs/commands/cs-inbox-setup.md b/docs/commands/cs-inbox-setup.md index d9339c67..7423ba3c 100644 --- a/docs/commands/cs-inbox-setup.md +++ b/docs/commands/cs-inbox-setup.md @@ -129,7 +129,7 @@ python ../skills/inbox-setup/scripts/section_progress_tracker.py --action close - Companion: [`/cs:inbox-triage`](./cs-inbox-triage.md) — runs after setup is complete - Agent: [`cs-inbox-setup`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/agents/cs-inbox-setup.md) - Skill: [`inbox-setup`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/skills/inbox-setup/SKILL.md) -- Source spec: [`megaprompts/06-inbox-setup-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/06-inbox-setup-megaprompt.md) +- Source spec: `megaprompts/06-inbox-setup-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) --- diff --git a/docs/commands/cs-inbox-triage.md b/docs/commands/cs-inbox-triage.md index c2efa512..a3bac069 100644 --- a/docs/commands/cs-inbox-triage.md +++ b/docs/commands/cs-inbox-triage.md @@ -128,7 +128,7 @@ python ../skills/inbox-triage/scripts/draft_safety_validator.py \ - Companion: [`/cs:inbox-setup`](./cs-inbox-setup.md) — must run first - Agent: [`cs-inbox-triage`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/agents/cs-inbox-triage.md) - Skill: [`inbox-triage`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/email/skills/inbox-triage/SKILL.md) -- Source spec: [`megaprompts/07-inbox-triage-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/07-inbox-triage-megaprompt.md) +- Source spec: `megaprompts/07-inbox-triage-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) --- diff --git a/docs/commands/cs-landing.md b/docs/commands/cs-landing.md index 4c3827f4..0128742a 100644 --- a/docs/commands/cs-landing.md +++ b/docs/commands/cs-landing.md @@ -120,7 +120,7 @@ python ../skills/landing/scripts/html_validator.py \ - Agent: [`cs-landing`](https://github.com/alirezarezvani/claude-skills/tree/main/marketing/landing/agents/cs-landing.md) - Skill: [`landing`](https://github.com/alirezarezvani/claude-skills/tree/main/marketing/landing/skills/landing/SKILL.md) -- Source spec: [`megaprompts/04-landing-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/04-landing-megaprompt.md) +- Source spec: `megaprompts/04-landing-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling (different optimization): `product-team/skills/landing-page-generator/` - Adjacent v2 commands: `/cs:capture`, `/cs:pulse`, `/cs:inbox-setup`, `/cs:inbox-triage` diff --git a/docs/commands/cs-litreview.md b/docs/commands/cs-litreview.md index 5df36f8a..b9cf1a64 100644 --- a/docs/commands/cs-litreview.md +++ b/docs/commands/cs-litreview.md @@ -139,7 +139,7 @@ python ../skills/litreview/scripts/citation_tracker.py --action close --session - Agent: [`cs-litreview`](https://github.com/alirezarezvani/claude-skills/tree/main/research/litreview/agents/cs-litreview.md) - Skill: [`litreview`](https://github.com/alirezarezvani/claude-skills/tree/main/research/litreview/skills/litreview/SKILL.md) -- Source spec: [`megaprompts/09-litreview-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/09-litreview-megaprompt.md) +- Source spec: `megaprompts/09-litreview-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling: `/cs:pulse` (research pack) - Future siblings: `/cs:grants`, `/cs:patent`, `/cs:dossier`, `/cs:syllabus` diff --git a/docs/commands/cs-notebooklm.md b/docs/commands/cs-notebooklm.md index 94965016..e606a004 100644 --- a/docs/commands/cs-notebooklm.md +++ b/docs/commands/cs-notebooklm.md @@ -149,7 +149,7 @@ python ../skills/notebooklm/scripts/async_action_classifier.py --action audio_ov - Agent: [`cs-notebooklm`](https://github.com/alirezarezvani/claude-skills/tree/main/research/notebooklm/agents/cs-notebooklm.md) - Skill: [`notebooklm`](https://github.com/alirezarezvani/claude-skills/tree/main/research/notebooklm/skills/notebooklm/SKILL.md) -- Source spec: [`megaprompts/03-notebooklm-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/03-notebooklm-megaprompt.md) +- Source spec: `megaprompts/03-notebooklm-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Research-domain siblings (different shape): `/cs:pulse`, `/cs:litreview`, `/cs:grants`, `/cs:dossier`, `/cs:patent`, `/cs:syllabus` --- diff --git a/docs/commands/cs-patent.md b/docs/commands/cs-patent.md index 39417258..566d2cda 100644 --- a/docs/commands/cs-patent.md +++ b/docs/commands/cs-patent.md @@ -97,7 +97,7 @@ patent___.docx - Agent: [`cs-patent`](https://github.com/alirezarezvani/claude-skills/tree/main/research/patent/agents/cs-patent.md) - Skill: [`patent`](https://github.com/alirezarezvani/claude-skills/tree/main/research/patent/skills/patent/SKILL.md) -- Source spec: [`megaprompts/11-patent-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/11-patent-megaprompt.md) +- Source spec: `megaprompts/11-patent-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Siblings: `/cs:litreview`, `/cs:grants`, `/cs:dossier`, `/cs:pulse` - Future: `/cs:syllabus` diff --git a/docs/commands/cs-pulse.md b/docs/commands/cs-pulse.md index 5300b45f..a9df9b0a 100644 --- a/docs/commands/cs-pulse.md +++ b/docs/commands/cs-pulse.md @@ -126,7 +126,7 @@ python ../skills/pulse/scripts/citation_tracker.py --action close --session NAME - Agent: [`cs-pulse`](https://github.com/alirezarezvani/claude-skills/tree/main/research/pulse/agents/cs-pulse.md) - Skill: [`pulse`](https://github.com/alirezarezvani/claude-skills/tree/main/research/pulse/skills/pulse/SKILL.md) -- Source spec: [`megaprompts/01-pulse-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/01-pulse-megaprompt.md) +- Source spec: `megaprompts/01-pulse-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling research skills (after build): `/cs:litreview`, `/cs:grants`, `/cs:syllabus`, `/cs:patent`, `/cs:dossier`, `/cs:research` (router) --- diff --git a/docs/commands/cs-reflect.md b/docs/commands/cs-reflect.md index a8edf6cc..236c958e 100644 --- a/docs/commands/cs-reflect.md +++ b/docs/commands/cs-reflect.md @@ -111,7 +111,7 @@ python ../skills/reflect/scripts/directional_recommendation_validator.py --outpu - Agent: [`cs-reflect`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/reflect/agents/cs-reflect.md) - Skill: [`reflect`](https://github.com/alirezarezvani/claude-skills/tree/main/productivity/reflect/skills/reflect/SKILL.md) -- Source spec: [`megaprompts/02-reflect-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/02-reflect-megaprompt.md) +- Source spec: `megaprompts/02-reflect-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Sibling: `/cs:capture` (productivity, brain-dump organizer) - Adjacent (different shape): `/cs:grill-me`, `/cs:grill-with-docs` diff --git a/docs/commands/cs-research.md b/docs/commands/cs-research.md index d22a1209..b3fbfee8 100644 --- a/docs/commands/cs-research.md +++ b/docs/commands/cs-research.md @@ -165,7 +165,7 @@ python ../skills/research/scripts/fallback_decomposer.py --question "" - Agent: [`cs-research`](https://github.com/alirezarezvani/claude-skills/tree/main/research/research/agents/cs-research.md) - Skill: [`research`](https://github.com/alirezarezvani/claude-skills/tree/main/research/research/skills/research/SKILL.md) -- Source spec: [`megaprompts/13-research-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/13-research-megaprompt.md) +- Source spec: `megaprompts/13-research-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Routing targets: `/cs:pulse`, `/cs:litreview`, `/cs:grants`, `/cs:dossier`, `/cs:patent`, `/cs:syllabus` - Adjacent (NOT a routing target): `/cs:notebooklm` (different mode), `engineering/autoresearch-agent` (different use case) diff --git a/docs/commands/cs-syllabus.md b/docs/commands/cs-syllabus.md index 72ee64a0..a35c75f6 100644 --- a/docs/commands/cs-syllabus.md +++ b/docs/commands/cs-syllabus.md @@ -140,7 +140,7 @@ python ../skills/syllabus/scripts/citation_tracker.py --action close --session N - Agent: [`cs-syllabus`](https://github.com/alirezarezvani/claude-skills/tree/main/research/syllabus/agents/cs-syllabus.md) - Skill: [`syllabus`](https://github.com/alirezarezvani/claude-skills/tree/main/research/syllabus/skills/syllabus/SKILL.md) -- Source spec: [`megaprompts/10-syllabus-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/10-syllabus-megaprompt.md) +- Source spec: `megaprompts/10-syllabus-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) - Siblings: `/cs:litreview`, `/cs:grants`, `/cs:patent`, `/cs:dossier`, `/cs:pulse` --- diff --git a/docs/plugins/index.md b/docs/plugins/index.md index 47ddee44..1bc4a88a 100644 --- a/docs/plugins/index.md +++ b/docs/plugins/index.md @@ -195,10 +195,10 @@ Every plugin follows the same minimal schema for maximum portability: } ``` -Two approved extension fields are permitted: +**No extension fields of any kind** — Claude Code's manifest validator rejects the entire `plugin.json` on any unrecognized key (issue #954), and `scripts/check_plugin_json.py` hard-fails manifests carrying extras in CI. Authoring metadata lives in a sibling file the validator never reads, `.claude-plugin/authoring-notes.json`, holding at most two keys: - **`source`** (object) — provenance metadata for Path-B megaprompt-derived skills (productivity, marketing, research). -- **`attribution`** (object) — credit metadata for MIT-licensed external derivatives (`caveman`, `grill-me`, `grill-with-docs`). +- **`attribution`** (object) — credit metadata for skills derived from external MIT-licensed work (`caveman`, `grill-me`, `grill-with-docs`, `skillopt-sleep`, `book-to-skill`, and others). Upstream credit must also remain in the plugin's `README.md`/`LICENSE`. !!! info "ClawHub Registry" Plugins are distributed via [ClawHub](https://clawhub.com) as the public registry. The `cs-` prefix is used only when a slug is already taken by another publisher — repo folder names remain unchanged. @@ -274,7 +274,7 @@ Two approved extension fields are permitted: | `collab-proof` | Standalone | engineering | `./engineering/collab-proof` | | `business-investment-advisor` | Standalone | finance | `./finance/business-investment-advisor` | | `llm-wiki` | Standalone | knowledge | `./engineering/llm-wiki` | -| `c-level-agents` | Standalone | leadership | `./c-level-advisor/c-level-agents` | +| `c-level-agents` | Standalone | leadership | `./c-level-agents` | | `chief-ai-officer-advisor` | Standalone | leadership | `./c-level-advisor/chief-ai-officer-advisor` | | `chief-customer-officer-advisor` | Standalone | leadership | `./c-level-advisor/chief-customer-officer-advisor` | | `chief-data-officer-advisor` | Standalone | leadership | `./c-level-advisor/chief-data-officer-advisor` | diff --git a/docs/skills/c-level-advisor/c-level-agents-boardroom.md b/docs/skills/c-level-advisor/c-level-agents-boardroom.md index b4d5d13a..df722c5b 100644 --- a/docs/skills/c-level-advisor/c-level-agents-boardroom.md +++ b/docs/skills/c-level-advisor/c-level-agents-boardroom.md @@ -8,7 +8,7 @@ description: "/cs:boardroom — 6-phase multi-role deliberation across t
:material-account-tie: C-Level Advisory :material-identifier: `boardroom` -:material-github: Source +:material-github: Source
@@ -137,7 +137,7 @@ If advisors see each other's positions before forming their own, they anchor. Ph ## Related -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) - Skills: [`board-meeting`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/board-meeting/SKILL.md), [`executive-mentor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/executive-mentor) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-brief.md b/docs/skills/c-level-advisor/c-level-agents-brief.md index fe6c6306..c4588b57 100644 --- a/docs/skills/c-level-advisor/c-level-agents-brief.md +++ b/docs/skills/c-level-advisor/c-level-agents-brief.md @@ -8,7 +8,7 @@ description: "/cs:brief — Generate a one-page strategy brief from an o
:material-account-tie: C-Level Advisory :material-identifier: `brief` -:material-github: Source +:material-github: Source
@@ -121,7 +121,7 @@ This is also the **artifact handoff** — the next command consumes this file, n ## Related -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) - Skills: [`context-engine`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/context-engine/SKILL.md), [`board-meeting`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/board-meeting/SKILL.md) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-caio-review.md b/docs/skills/c-level-advisor/c-level-agents-caio-review.md index 963764a6..523788b2 100644 --- a/docs/skills/c-level-advisor/c-level-agents-caio-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-caio-review.md @@ -8,7 +8,7 @@ description: "/cs:caio-review — Eval-demanding Chief AI Officer interro
:material-account-tie: C-Level Advisory :material-identifier: `caio-review` -:material-github: Source +:material-github: Source
@@ -142,7 +142,7 @@ python ../../../skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py wor ## Related -- Agent: [`cs-caio-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-caio-advisor.md) +- Agent: [`cs-caio-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-caio-advisor.md) - Skill: [`chief-ai-officer-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-ai-officer-advisor/SKILL.md) - Adjacent: [`skills/chief-data-officer-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-data-officer-advisor) (training data rights, data strategy) diff --git a/docs/skills/c-level-advisor/c-level-agents-cco-review.md b/docs/skills/c-level-advisor/c-level-agents-cco-review.md index c6e29ce6..7ef79b0d 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cco-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cco-review.md @@ -8,7 +8,7 @@ description: "/cs:cco-review — Retention-obsessed Chief Customer Office
:material-account-tie: C-Level Advisory :material-identifier: `cco-review` -:material-github: Source +:material-github: Source
@@ -132,7 +132,7 @@ python ../../../skills/chief-customer-officer-advisor/scripts/cs_coverage_calcul ## Related -- Agent: [`cs-cco-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cco-advisor.md) +- Agent: [`cs-cco-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cco-advisor.md) - Skill: [`chief-customer-officer-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-customer-officer-advisor/SKILL.md) - Adjacent: [`business-growth`](https://github.com/alirezarezvani/claude-skills/tree/main/business-growth) (tactical CS execution) diff --git a/docs/skills/c-level-advisor/c-level-agents-cdo-review.md b/docs/skills/c-level-advisor/c-level-agents-cdo-review.md index fe765359..0aaf888e 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cdo-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cdo-review.md @@ -8,7 +8,7 @@ description: "/cs:cdo-review — Decision-driven Chief Data Officer inter
:material-account-tie: C-Level Advisory :material-identifier: `cdo-review` -:material-github: Source +:material-github: Source
@@ -128,7 +128,7 @@ python ../../../skills/chief-data-officer-advisor/scripts/data_asset_valuator.py ## Related -- Agent: [`cs-cdo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cdo-advisor.md) +- Agent: [`cs-cdo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cdo-advisor.md) - Skill: [`chief-data-officer-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-data-officer-advisor/SKILL.md) - Adjacent: [`skills/general-counsel-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/general-counsel-advisor) (contractual constraints), [`skills/cto-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cto-advisor) (architecture capacity) diff --git a/docs/skills/c-level-advisor/c-level-agents-cfo-review.md b/docs/skills/c-level-advisor/c-level-agents-cfo-review.md index 39072aa4..c025c9f3 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cfo-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cfo-review.md @@ -8,7 +8,7 @@ description: "/cs:cfo-review — Numerate-skeptic interrogation of any pl
:material-account-tie: C-Level Advisory :material-identifier: `cfo-review` -:material-github: Source +:material-github: Source
@@ -108,7 +108,7 @@ The numerate skeptic stress-tests anything that touches money. Six questions bef ## Related -- Agent: [`cs-cfo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cfo-advisor.md) +- Agent: [`cs-cfo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cfo-advisor.md) - Skill: [`cfo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cfo-advisor/SKILL.md) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-ciso-review.md b/docs/skills/c-level-advisor/c-level-agents-ciso-review.md index 40681f74..ed014d4d 100644 --- a/docs/skills/c-level-advisor/c-level-agents-ciso-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-ciso-review.md @@ -8,7 +8,7 @@ description: "/cs:ciso-review — Risk-paranoid interrogation of any plan
:material-account-tie: C-Level Advisory :material-identifier: `ciso-review` -:material-github: Source +:material-github: Source
@@ -115,7 +115,7 @@ python ../../../skills/ciso-advisor/scripts/compliance_tracker.py ## Related -- Agent: [`cs-ciso-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-ciso-advisor.md) +- Agent: [`cs-ciso-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-ciso-advisor.md) - Skill: [`ciso-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/ciso-advisor/SKILL.md) - Compliance: [`ra-qm-team`](https://github.com/alirezarezvani/claude-skills/tree/main/ra-qm-team) diff --git a/docs/skills/c-level-advisor/c-level-agents-cmo-review.md b/docs/skills/c-level-advisor/c-level-agents-cmo-review.md index 689a0226..7b8a7c60 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cmo-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cmo-review.md @@ -8,7 +8,7 @@ description: "/cs:cmo-review — Narrative-first interrogation of positio
:material-account-tie: C-Level Advisory :material-identifier: `cmo-review` -:material-github: Source +:material-github: Source
@@ -103,7 +103,7 @@ One-sentence statement: ## Related -- Agent: [`cs-cmo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cmo-advisor.md) +- Agent: [`cs-cmo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cmo-advisor.md) - Skill: [`cmo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cmo-advisor/SKILL.md) - Execution domain: [`marketing-skill`](https://github.com/alirezarezvani/claude-skills/tree/main/marketing-skill) diff --git a/docs/skills/c-level-advisor/c-level-agents-cpo-review.md b/docs/skills/c-level-advisor/c-level-agents-cpo-review.md index 41a81596..debe3954 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cpo-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cpo-review.md @@ -8,7 +8,7 @@ description: "/cs:cpo-review — JTBD-driven interrogation of product roa
:material-account-tie: C-Level Advisory :material-identifier: `cpo-review` -:material-github: Source +:material-github: Source
@@ -112,7 +112,7 @@ python product-team/skills/product-manager-toolkit/scripts/rice_prioritizer.py ## Related -- Agent: [`cs-cpo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cpo-advisor.md) +- Agent: [`cs-cpo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cpo-advisor.md) - Skill: [`cpo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cpo-advisor/SKILL.md) - Execution: `product-team/skills/product-manager-toolkit/` diff --git a/docs/skills/c-level-advisor/c-level-agents-cro-review.md b/docs/skills/c-level-advisor/c-level-agents-cro-review.md index 42ca1763..8b759d17 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cro-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cro-review.md @@ -8,7 +8,7 @@ description: "/cs:cro-review — Pipeline-paranoid interrogation of reven
:material-account-tie: C-Level Advisory :material-identifier: `cro-review` -:material-github: Source +:material-github: Source
@@ -112,7 +112,7 @@ python ../../../skills/cro-advisor/scripts/churn_analyzer.py ## Related -- Agent: [`cs-cro-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-cro-advisor.md) +- Agent: [`cs-cro-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-cro-advisor.md) - Skill: [`cro-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cro-advisor/SKILL.md) - Execution: [`business-growth`](https://github.com/alirezarezvani/claude-skills/tree/main/business-growth) diff --git a/docs/skills/c-level-advisor/c-level-agents-cross-eval.md b/docs/skills/c-level-advisor/c-level-agents-cross-eval.md index a7a06855..a5d2b330 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cross-eval.md +++ b/docs/skills/c-level-advisor/c-level-agents-cross-eval.md @@ -8,7 +8,7 @@ description: "/cs:cross-eval — Multi-model consensus on a board memo or
:material-account-tie: C-Level Advisory :material-identifier: `cross-eval` -:material-github: Source +:material-github: Source
diff --git a/docs/skills/c-level-advisor/c-level-agents-cto-review.md b/docs/skills/c-level-advisor/c-level-agents-cto-review.md index 7be5b7e8..4d69c938 100644 --- a/docs/skills/c-level-advisor/c-level-agents-cto-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-cto-review.md @@ -8,7 +8,7 @@ description: "/cs:cto-review — Architecture and scaling interrogation.
:material-account-tie: C-Level Advisory :material-identifier: `cto-review` -:material-github: Source +:material-github: Source
diff --git a/docs/skills/c-level-advisor/c-level-agents-decide.md b/docs/skills/c-level-advisor/c-level-agents-decide.md index af532419..2e0814ac 100644 --- a/docs/skills/c-level-advisor/c-level-agents-decide.md +++ b/docs/skills/c-level-advisor/c-level-agents-decide.md @@ -8,7 +8,7 @@ description: "/cs:decide — Log a decision to two-layer memory via decis
:material-account-tie: C-Level Advisory :material-identifier: `decide` -:material-github: Source +:material-github: Source
@@ -107,8 +107,8 @@ The biggest risk in approved decisions is forgetting why someone disagreed. When ## Related - Skill: [`decision-logger`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/decision-logger/SKILL.md) -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) -- Bridge: [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md) +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) +- Bridge: [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-execute.md b/docs/skills/c-level-advisor/c-level-agents-execute.md index 40172ed7..beed5d5f 100644 --- a/docs/skills/c-level-advisor/c-level-agents-execute.md +++ b/docs/skills/c-level-advisor/c-level-agents-execute.md @@ -8,7 +8,7 @@ description: "/cs:execute — Generate a 90-day execution plan with w
:material-account-tie: C-Level Advisory :material-identifier: `execute` -:material-github: Source +:material-github: Source
@@ -103,7 +103,7 @@ Saved to `~/.claude/execution/YYYY-MM-DD-.md`: ## Related - Skills: [`coo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/coo-advisor/SKILL.md), [`strategic-alignment`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/strategic-alignment/SKILL.md), [`change-management`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/change-management/SKILL.md) -- Agent: [`cs-coo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-coo-advisor.md) +- Agent: [`cs-coo-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-coo-advisor.md) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-founder-mode.md b/docs/skills/c-level-advisor/c-level-agents-founder-mode.md index 05f00c9a..5c200479 100644 --- a/docs/skills/c-level-advisor/c-level-agents-founder-mode.md +++ b/docs/skills/c-level-advisor/c-level-agents-founder-mode.md @@ -8,7 +8,7 @@ description: "/cs:founder-mode — Auto-routes any founder question t
:material-account-tie: C-Level Advisory :material-identifier: `founder-mode` -:material-github: Source +:material-github: Source
@@ -110,7 +110,7 @@ gstack requires the founder to know all 23 slash commands and pick the right one ## Related -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) — does the routing +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) — does the routing - Skill: [`chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/chief-of-staff/SKILL.md) — routing logic - Skill: [`context-engine`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/context-engine/SKILL.md) — loads context diff --git a/docs/skills/c-level-advisor/c-level-agents-freeze.md b/docs/skills/c-level-advisor/c-level-agents-freeze.md index 07df9074..ca20c938 100644 --- a/docs/skills/c-level-advisor/c-level-agents-freeze.md +++ b/docs/skills/c-level-advisor/c-level-agents-freeze.md @@ -8,7 +8,7 @@ description: "/cs:freeze — Lock a strategic decision for a c
:material-account-tie: C-Level Advisory :material-identifier: `freeze` -:material-github: Source +:material-github: Source
@@ -105,7 +105,7 @@ Founders have authority. Without an explicit lock + log, every wobble produces a ## Related - Skill: [`decision-logger`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/decision-logger/SKILL.md) -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) — enforces freezes in routing +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) — enforces freezes in routing --- diff --git a/docs/skills/c-level-advisor/c-level-agents-gc-review.md b/docs/skills/c-level-advisor/c-level-agents-gc-review.md index f5348a7e..84592087 100644 --- a/docs/skills/c-level-advisor/c-level-agents-gc-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-gc-review.md @@ -8,7 +8,7 @@ description: "/cs:gc-review — General Counsel interrogation of contract
:material-account-tie: C-Level Advisory :material-identifier: `gc-review` -:material-github: Source +:material-github: Source
@@ -134,7 +134,7 @@ The `cs-general-counsel-advisor` agent orchestrates both tools plus 3 references ## Related - Skill: [`general-counsel-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/general-counsel-advisor/SKILL.md) — full skill with Python tools + references -- Agent: [`cs-general-counsel-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-general-counsel-advisor.md) +- Agent: [`cs-general-counsel-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-general-counsel-advisor.md) - Compliance execution: [`ra-qm-team`](https://github.com/alirezarezvani/claude-skills/tree/main/ra-qm-team) - Adjacent: [`skills/ma-playbook`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/ma-playbook) diff --git a/docs/skills/c-level-advisor/c-level-agents-office-hours.md b/docs/skills/c-level-advisor/c-level-agents-office-hours.md index e996e699..fa1c5b28 100644 --- a/docs/skills/c-level-advisor/c-level-agents-office-hours.md +++ b/docs/skills/c-level-advisor/c-level-agents-office-hours.md @@ -8,7 +8,7 @@ description: "/cs:office-hours — YC-style 6-question founder interroga
:material-account-tie: C-Level Advisory :material-identifier: `office-hours` -:material-github: Source +:material-github: Source
diff --git a/docs/skills/c-level-advisor/c-level-agents-onboard.md b/docs/skills/c-level-advisor/c-level-agents-onboard.md index 9cc91657..6b664488 100644 --- a/docs/skills/c-level-advisor/c-level-agents-onboard.md +++ b/docs/skills/c-level-advisor/c-level-agents-onboard.md @@ -8,7 +8,7 @@ description: "/cs:onboard — Founder interview that populates ~/.claude/company
:material-account-tie: C-Level Advisory :material-identifier: `onboard` -:material-github: Source +:material-github: Source
@@ -122,7 +122,7 @@ The intake summary captured by the 12 questions: By default, `~/.claude/company-context.md` is local to the founder's machine. To make it persistent across machines / shareable: -- **Markdown vault (recommended):** see [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md) +- **Markdown vault (recommended):** see [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md) - **Encrypted dotfile sync:** age + git - **Shared team:** keep in a private repo, symlink from `~/.claude/` @@ -130,7 +130,7 @@ By default, `~/.claude/company-context.md` is local to the founder's machine. To - Skill: [`cs-onboard`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/cs-onboard/SKILL.md) — the underlying interview protocol - Skill: [`context-engine`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/context-engine/SKILL.md) — reads this file -- Reference: [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md) +- Reference: [[`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md)](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md) --- diff --git a/docs/skills/c-level-advisor/c-level-agents-post-mortem.md b/docs/skills/c-level-advisor/c-level-agents-post-mortem.md index 44e0191f..37ed6895 100644 --- a/docs/skills/c-level-advisor/c-level-agents-post-mortem.md +++ b/docs/skills/c-level-advisor/c-level-agents-post-mortem.md @@ -8,7 +8,7 @@ description: "/cs:post-mortem — Honest retrospective on an executed
:material-account-tie: C-Level Advisory :material-identifier: `post-mortem` -:material-github: Source +:material-github: Source
@@ -118,7 +118,7 @@ The dissent column from `/cs:boardroom` is the single most useful piece of organ ## Related - Skill: [`decision-logger`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/decision-logger/SKILL.md) -- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-chief-of-staff.md) +- Agent: [`cs-chief-of-staff`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-chief-of-staff.md) - Sibling: [`/em:postmortem`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/executive-mentor/skills/postmortem/SKILL.md) — adversarial single-decision post-mortem --- diff --git a/docs/skills/c-level-advisor/c-level-agents-vpe-review.md b/docs/skills/c-level-advisor/c-level-agents-vpe-review.md index d6517255..8420523b 100644 --- a/docs/skills/c-level-advisor/c-level-agents-vpe-review.md +++ b/docs/skills/c-level-advisor/c-level-agents-vpe-review.md @@ -8,7 +8,7 @@ description: "/cs:vpe-review — Throughput-first VP of Engineering inter
:material-account-tie: C-Level Advisory :material-identifier: `vpe-review` -:material-github: Source +:material-github: Source
@@ -131,7 +131,7 @@ python ../../../skills/vpe-advisor/scripts/eng_team_structure_designer.py team.j ## Related -- Agent: [`cs-vpe-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/agents/cs-vpe-advisor.md) +- Agent: [`cs-vpe-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/agents/cs-vpe-advisor.md) - Skill: [`vpe-advisor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/skills/vpe-advisor/SKILL.md) - Adjacent: [`engineering/slo-architect`](https://github.com/alirezarezvani/claude-skills/tree/main/engineering/slo-architect), [`engineering/feature-flags-architect`](https://github.com/alirezarezvani/claude-skills/tree/main/engineering/feature-flags-architect), [`engineering/chaos-engineering`](https://github.com/alirezarezvani/claude-skills/tree/main/engineering/chaos-engineering) diff --git a/docs/skills/c-level-advisor/c-level-agents.md b/docs/skills/c-level-advisor/c-level-agents.md index 6ec86b37..0b2ef865 100644 --- a/docs/skills/c-level-advisor/c-level-agents.md +++ b/docs/skills/c-level-advisor/c-level-agents.md @@ -8,7 +8,7 @@ description: "Founder-mode executive team. 13 cs-* C-suite agents (CFO, CMO, CRO
:material-account-tie: C-Level Advisory :material-identifier: `c-level-agents` -:material-github: Source +:material-github: Source
@@ -32,7 +32,7 @@ Each agent wraps an existing c-level skill and adds: - Workflow orchestration tied to skill Python tools - Output template: Bottom Line → What → Why → How to Act → Your Decision -See [`references/persona-voices.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) for voice specs. +See [`references/persona-voices.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) for voice specs. ### 21 /cs:* Slash Commands (in `skills/`) @@ -96,7 +96,7 @@ User question - **decision-logger** — every `/cs:decide` writes here - **chief-of-staff** — routing layer the agent orchestrates - **board-meeting** — protocol the `/cs:boardroom` command runs -- **llm-wiki** — optional persistent memory bridge (see [`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md)) +- **llm-wiki** — optional persistent memory bridge (see [`references/llm-wiki-bridge.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md)) - **executive-mentor** — adversarial `/em:*` commands stack cleanly on top ## Design Principles @@ -109,8 +109,8 @@ User question ## References -- [persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/persona-voices.md) -- [llm-wiki-bridge.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents/references/llm-wiki-bridge.md) +- [persona-voices.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/persona-voices.md) +- [llm-wiki-bridge.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents/references/llm-wiki-bridge.md) - [Parent c-level CLAUDE.md](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/CLAUDE.md) - [Existing executive-mentor sibling](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/executive-mentor) diff --git a/docs/skills/c-level-advisor/c-level-skills.md b/docs/skills/c-level-advisor/c-level-skills.md index 014b8e96..007987b5 100644 --- a/docs/skills/c-level-advisor/c-level-skills.md +++ b/docs/skills/c-level-advisor/c-level-skills.md @@ -43,6 +43,6 @@ Full matrix in [`chief-of-staff/SKILL.md`](https://github.com/alirezarezvani/cla ## Related Layers -- [`c-level-advisor/c-level-agents`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/c-level-agents) — 13 cs-* persona agents + 21 `/cs:*` slash commands on top of these skills +- [`c-level-agents`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-agents) — 13 cs-* persona agents + 21 `/cs:*` slash commands on top of these skills - [`c-level-advisor/executive-mentor`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/executive-mentor) — adversarial `/em:*` critic commands - [`c-level-advisor/CLAUDE.md`](https://github.com/alirezarezvani/claude-skills/tree/main/c-level-advisor/CLAUDE.md) — full architecture diagram and integration guide diff --git a/docs/skills/c-level-advisor/general-counsel-advisor.md b/docs/skills/c-level-advisor/general-counsel-advisor.md index 9488d5a1..0fc1d072 100644 --- a/docs/skills/c-level-advisor/general-counsel-advisor.md +++ b/docs/skills/c-level-advisor/general-counsel-advisor.md @@ -148,7 +148,7 @@ See `references/ip_and_regulatory.md` for sequencing. - `c-level-advisor/skills/cfo-advisor/` — Term sheet → dilution math - `c-level-advisor/skills/ma-playbook/` — Acquisition agreements, integration playbooks - `ra-qm-team/` — ISO 13485, MDR, FDA 510(k), GDPR execution -- `c-level-advisor/c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command +- `c-level-agents/skills/gc-review/SKILL.md` — `/cs:gc-review` slash command ## References diff --git a/docs/skills/engineering-team/playwright-pro-init.md b/docs/skills/engineering-team/playwright-pro-init.md index 89653e8f..2baf0427 100644 --- a/docs/skills/engineering-team/playwright-pro-init.md +++ b/docs/skills/engineering-team/playwright-pro-init.md @@ -8,7 +8,7 @@ description: "Set up Playwright in a project. Use when user says 'set up playwri
:material-code-braces: Engineering - Core :material-identifier: `init` -:material-github: Source +:material-github: Source
diff --git a/docs/skills/engineering-team/playwright-pro-migrate.md b/docs/skills/engineering-team/playwright-pro-migrate.md index 99702639..548eedfe 100644 --- a/docs/skills/engineering-team/playwright-pro-migrate.md +++ b/docs/skills/engineering-team/playwright-pro-migrate.md @@ -55,7 +55,7 @@ Migration Assessment: ### 3. Set Up Playwright (If Not Present) -Run `/pw:init` first if Playwright isn't configured. +Run `/pw:pw-init` first if Playwright isn't configured. ### 4. Convert Files diff --git a/docs/skills/engineering-team/playwright-pro-pw.md b/docs/skills/engineering-team/playwright-pro-pw.md index 8f9640bc..4a6dd19e 100644 --- a/docs/skills/engineering-team/playwright-pro-pw.md +++ b/docs/skills/engineering-team/playwright-pro-pw.md @@ -24,9 +24,9 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: | Command | What it does | |---|---| -| `/pw:init` | Set up Playwright — detects framework, generates config, CI, first test | +| `/pw:pw-init` | Set up Playwright — detects framework, generates config, CI, first test | | `/pw:generate ` | Generate tests from user story, URL, or component | -| `/pw:review` | Review tests for anti-patterns and coverage gaps | +| `/pw:pw-review` | Review tests for anti-patterns and coverage gaps | | `/pw:fix ` | Diagnose and fix failing or flaky tests | | `/pw:migrate` | Migrate from Cypress or Selenium to Playwright | | `/pw:coverage` | Analyze what's tested vs. what's missing | @@ -39,14 +39,14 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: The recommended sequence for most projects: ``` -1. /pw:init → scaffolds config, CI pipeline, and a first smoke test +1. /pw:pw-init → scaffolds config, CI pipeline, and a first smoke test 2. /pw:generate → generates tests from your spec or URL -3. /pw:review → validates quality and flags anti-patterns ← always run after generate +3. /pw:pw-review → validates quality and flags anti-patterns ← always run after generate 4. /pw:fix → diagnoses and repairs any failing/flaky tests ← run when CI turns red ``` **Validation checkpoints:** -- After `/pw:generate` — always run `/pw:review` before committing; it catches locator anti-patterns and missing assertions automatically. +- After `/pw:generate` — always run `/pw:pw-review` before committing; it catches locator anti-patterns and missing assertions automatically. - After `/pw:fix` — re-run the full suite locally (`npx playwright test`) to confirm the fix doesn't introduce regressions. - After `/pw:migrate` — run `/pw:coverage` to confirm parity with the old suite before decommissioning Cypress/Selenium tests. @@ -60,7 +60,7 @@ The recommended sequence for most projects: # → Playwright Pro creates the file using the auth template. # 2. Review the generated tests -/pw:review tests/auth/login.spec.ts +/pw:pw-review tests/auth/login.spec.ts # → Flags: one test used page.locator('input[type=password]') — suggests getByLabel('Password') # → Fix applied automatically. diff --git a/docs/skills/engineering-team/playwright-pro-review.md b/docs/skills/engineering-team/playwright-pro-review.md index ff9d2f5f..78a092bc 100644 --- a/docs/skills/engineering-team/playwright-pro-review.md +++ b/docs/skills/engineering-team/playwright-pro-review.md @@ -8,7 +8,7 @@ description: "Review Playwright tests for quality. Use when user says 'review te
:material-code-braces: Engineering - Core :material-identifier: `review` -:material-github: Source +:material-github: Source
diff --git a/docs/skills/engineering-team/playwright-pro.md b/docs/skills/engineering-team/playwright-pro.md index aaf45fc4..1ae4f3c1 100644 --- a/docs/skills/engineering-team/playwright-pro.md +++ b/docs/skills/engineering-team/playwright-pro.md @@ -24,9 +24,9 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: | Command | What it does | |---|---| -| `/pw:init` | Set up Playwright — detects framework, generates config, CI, first test | +| `/pw:pw-init` | Set up Playwright — detects framework, generates config, CI, first test | | `/pw:generate ` | Generate tests from user story, URL, or component | -| `/pw:review` | Review tests for anti-patterns and coverage gaps | +| `/pw:pw-review` | Review tests for anti-patterns and coverage gaps | | `/pw:fix ` | Diagnose and fix failing or flaky tests | | `/pw:migrate` | Migrate from Cypress or Selenium to Playwright | | `/pw:coverage` | Analyze what's tested vs. what's missing | @@ -39,14 +39,14 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: The recommended sequence for most projects: ``` -1. /pw:init → scaffolds config, CI pipeline, and a first smoke test +1. /pw:pw-init → scaffolds config, CI pipeline, and a first smoke test 2. /pw:generate → generates tests from your spec or URL -3. /pw:review → validates quality and flags anti-patterns ← always run after generate +3. /pw:pw-review → validates quality and flags anti-patterns ← always run after generate 4. /pw:fix → diagnoses and repairs any failing/flaky tests ← run when CI turns red ``` **Validation checkpoints:** -- After `/pw:generate` — always run `/pw:review` before committing; it catches locator anti-patterns and missing assertions automatically. +- After `/pw:generate` — always run `/pw:pw-review` before committing; it catches locator anti-patterns and missing assertions automatically. - After `/pw:fix` — re-run the full suite locally (`npx playwright test`) to confirm the fix doesn't introduce regressions. - After `/pw:migrate` — run `/pw:coverage` to confirm parity with the old suite before decommissioning Cypress/Selenium tests. @@ -60,7 +60,7 @@ The recommended sequence for most projects: # → Playwright Pro creates the file using the auth template. # 2. Review the generated tests -/pw:review tests/auth/login.spec.ts +/pw:pw-review tests/auth/login.spec.ts # → Flags: one test used page.locator('input[type=password]') — suggests getByLabel('Password') # → Fix applied automatically. diff --git a/docs/skills/engineering/agenthub-init.md b/docs/skills/engineering/agenthub-init.md index 7a02052a..da78c509 100644 --- a/docs/skills/engineering/agenthub-init.md +++ b/docs/skills/engineering/agenthub-init.md @@ -1,14 +1,14 @@ --- -title: "/hub:init — Create New Session — Agent Skill for Codex & OpenClaw" -description: "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:init or asks to start a. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." +title: "/hub:hub-init — Create New Session — Agent Skill for Codex & OpenClaw" +description: "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:hub-init or asks to start a. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." --- -# /hub:init — Create New Session +# /hub:hub-init — Create New Session
:material-rocket-launch: Engineering - POWERFUL :material-identifier: `init` -:material-github: Source +:material-github: Source
@@ -21,9 +21,9 @@ Initialize an AgentHub collaboration session. Creates the `.agenthub/` directory ## Usage ``` -/hub:init # Interactive mode -/hub:init --task "Optimize API" --agents 3 --eval "pytest bench.py" --metric p50_ms --direction lower -/hub:init --task "Refactor auth" --agents 2 # No eval (LLM judge mode) +/hub:hub-init # Interactive mode +/hub:hub-init --task "Optimize API" --agents 3 --eval "pytest bench.py" --metric p50_ms --direction lower +/hub:hub-init --task "Refactor auth" --agents 2 # No eval (LLM judge mode) ``` ## What It Does diff --git a/docs/skills/engineering/agenthub-run.md b/docs/skills/engineering/agenthub-run.md index 24ae4faf..98d03bf7 100644 --- a/docs/skills/engineering/agenthub-run.md +++ b/docs/skills/engineering/agenthub-run.md @@ -51,7 +51,7 @@ Execute these steps sequentially: ### Step 1: Initialize -Run `/hub:init` with the provided arguments: +Run `/hub:hub-init` with the provided arguments: ```bash python {skill_path}/scripts/hub_init.py \ diff --git a/docs/skills/engineering/agenthub-spawn.md b/docs/skills/engineering/agenthub-spawn.md index 94e95fd6..8a433ff1 100644 --- a/docs/skills/engineering/agenthub-spawn.md +++ b/docs/skills/engineering/agenthub-spawn.md @@ -89,5 +89,5 @@ python {skill_path}/scripts/session_manager.py --update {session-id} --state run Tell the user: - {N} agents launched in parallel - Each working in an isolated worktree -- Monitor with `/hub:status` +- Monitor with `/hub:hub-status` - Evaluate when done with `/hub:eval` diff --git a/docs/skills/engineering/agenthub-status.md b/docs/skills/engineering/agenthub-status.md index 228edfa6..a42d90ab 100644 --- a/docs/skills/engineering/agenthub-status.md +++ b/docs/skills/engineering/agenthub-status.md @@ -1,14 +1,14 @@ --- -title: "/hub:status — Session Status — Agent Skill for Codex & OpenClaw" -description: "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:status or asks how the AgentHub agents are. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." +title: "/hub:hub-status — Session Status — Agent Skill for Codex & OpenClaw" +description: "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:hub-status or asks how the AgentHub agents are. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." --- -# /hub:status — Session Status +# /hub:hub-status — Session Status
:material-rocket-launch: Engineering - POWERFUL :material-identifier: `status` -:material-github: Source +:material-github: Source
@@ -21,8 +21,8 @@ Display the current state of an AgentHub session: agent branches, commit counts, ## Usage ``` -/hub:status # Status for latest session -/hub:status 20260317-143022 # Status for specific session +/hub:hub-status # Status for latest session +/hub:hub-status 20260317-143022 # Status for specific session ``` ## What It Does diff --git a/docs/skills/engineering/agenthub.md b/docs/skills/engineering/agenthub.md index d33050b5..dacabef3 100644 --- a/docs/skills/engineering/agenthub.md +++ b/docs/skills/engineering/agenthub.md @@ -22,9 +22,9 @@ Spawn N parallel AI agents that compete on the same task. Each agent works in an | Command | Description | |---------|-------------| -| `/hub:init` | Create a new collaboration session — task, agent count, eval criteria | +| `/hub:hub-init` | Create a new collaboration session — task, agent count, eval criteria | | `/hub:spawn` | Launch N parallel subagents in isolated worktrees | -| `/hub:status` | Show DAG state, agent progress, branch status | +| `/hub:hub-status` | Show DAG state, agent progress, branch status | | `/hub:eval` | Rank agent results by metric or LLM judge | | `/hub:merge` | Merge winning branch, archive losers | | `/hub:board` | Read/write the agent message board | @@ -67,7 +67,7 @@ INIT → DISPATCH → MONITOR → EVALUATE → MERGE ### 1. Init -Run `/hub:init` to create a session. This generates: +Run `/hub:hub-init` to create a session. This generates: - `.agenthub/sessions/{session-id}/config.yaml` — task config - `.agenthub/sessions/{session-id}/state.json` — state machine - `.agenthub/board/` — message board channels @@ -81,7 +81,7 @@ Run `/hub:spawn` to launch agents. For each agent 1..N: ### 3. Monitor -Run `/hub:status` to check progress: +Run `/hub:hub-status` to check progress: - `dag_analyzer.py --status --session {id}` shows branch state - Board `progress/` channel has agent updates diff --git a/docs/skills/engineering/autoresearch-agent-loop.md b/docs/skills/engineering/autoresearch-agent-loop.md index bd1e444d..91664fb8 100644 --- a/docs/skills/engineering/autoresearch-agent-loop.md +++ b/docs/skills/engineering/autoresearch-agent-loop.md @@ -109,7 +109,7 @@ Loop started for {domain}/{name} Cron ID: {id} Auto-expires: 3 days (CronCreate limit) - To check progress: /ar:status + To check progress: /ar:ar-status To stop the loop: /ar:loop stop {domain}/{name} Note: Recurring jobs auto-expire after 3 days. diff --git a/docs/skills/engineering/autoresearch-agent-resume.md b/docs/skills/engineering/autoresearch-agent-resume.md index cd25c011..eeac374f 100644 --- a/docs/skills/engineering/autoresearch-agent-resume.md +++ b/docs/skills/engineering/autoresearch-agent-resume.md @@ -1,14 +1,14 @@ --- -title: "/ar:resume — Resume Experiment — Agent Skill for Codex & OpenClaw" -description: "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:resume or asks to. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." +title: "/ar:ar-resume — Resume Experiment — Agent Skill for Codex & OpenClaw" +description: "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:ar-resume or asks to. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." --- -# /ar:resume — Resume Experiment +# /ar:ar-resume — Resume Experiment
:material-rocket-launch: Engineering - POWERFUL :material-identifier: `resume` -:material-github: Source +:material-github: Source
@@ -21,8 +21,8 @@ Resume a paused or context-limited experiment. Reads all history and continues w ## Usage ``` -/ar:resume # List experiments, let user pick -/ar:resume engineering/api-speed # Resume specific experiment +/ar:ar-resume # List experiments, let user pick +/ar:ar-resume engineering/api-speed # Resume specific experiment ``` ## What It Does diff --git a/docs/skills/engineering/autoresearch-agent-status.md b/docs/skills/engineering/autoresearch-agent-status.md index 6991ed44..ceb0660c 100644 --- a/docs/skills/engineering/autoresearch-agent-status.md +++ b/docs/skills/engineering/autoresearch-agent-status.md @@ -1,14 +1,14 @@ --- -title: "/ar:status — Experiment Dashboard — Agent Skill for Codex & OpenClaw" -description: "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:status or asks how an autoresearch experiment is going. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." +title: "/ar:ar-status — Experiment Dashboard — Agent Skill for Codex & OpenClaw" +description: "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going. Agent skill for Claude Code, Codex CLI, Gemini CLI, OpenClaw." --- -# /ar:status — Experiment Dashboard +# /ar:ar-status — Experiment Dashboard
:material-rocket-launch: Engineering - POWERFUL :material-identifier: `status` -:material-github: Source +:material-github: Source
@@ -21,11 +21,11 @@ Show experiment results, active loops, and progress across all experiments. ## Usage ``` -/ar:status # Full dashboard -/ar:status engineering/api-speed # Single experiment detail -/ar:status --domain engineering # All experiments in a domain -/ar:status --format markdown # Export as markdown -/ar:status --format csv --output results.csv # Export as CSV +/ar:ar-status # Full dashboard +/ar:ar-status engineering/api-speed # Single experiment detail +/ar:ar-status --domain engineering # All experiments in a domain +/ar:ar-status --format markdown # Export as markdown +/ar:ar-status --format csv --output results.csv # Export as CSV ``` ## What It Does diff --git a/docs/skills/engineering/autoresearch-agent.md b/docs/skills/engineering/autoresearch-agent.md index 190eed73..27a5fb42 100644 --- a/docs/skills/engineering/autoresearch-agent.md +++ b/docs/skills/engineering/autoresearch-agent.md @@ -31,8 +31,8 @@ Not one guess — fifty measured attempts, compounding. | `/ar:setup` | Set up a new experiment interactively | | `/ar:run` | Run a single experiment iteration | | `/ar:loop` | Start autonomous loop with configurable interval (10m, 1h, daily, weekly, monthly) | -| `/ar:status` | Show dashboard and results | -| `/ar:resume` | Resume a paused experiment | +| `/ar:ar-status` | Show dashboard and results | +| `/ar:ar-resume` | Resume a paused experiment | --- diff --git a/docs/skills/marketing/landing.md b/docs/skills/marketing/landing.md index 2283b6ed..f349872b 100644 --- a/docs/skills/marketing/landing.md +++ b/docs/skills/marketing/landing.md @@ -347,5 +347,5 @@ Run `scripts/html_validator.py --file ${OUTPUT_DIR}/.html` after generatio --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/04-landing-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/04-landing-megaprompt.md) +**Source spec:** `megaprompts/04-landing-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Distinct from `product-team/skills/landing-page-generator/`. diff --git a/docs/skills/productivity/capture.md b/docs/skills/productivity/capture.md index 09fd7807..82b19b0d 100644 --- a/docs/skills/productivity/capture.md +++ b/docs/skills/productivity/capture.md @@ -214,5 +214,5 @@ After the four (or compressed) sections are delivered: --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/05-capture-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/05-capture-megaprompt.md) +**Source spec:** `megaprompts/05-capture-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Re-grill with `/cs:grill-with-docs` if drift between spec and implementation surfaces. diff --git a/docs/skills/productivity/email-inbox-setup.md b/docs/skills/productivity/email-inbox-setup.md index 209480a8..cd8f6542 100644 --- a/docs/skills/productivity/email-inbox-setup.md +++ b/docs/skills/productivity/email-inbox-setup.md @@ -230,5 +230,5 @@ Re-running on an existing setup: --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/06-inbox-setup-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/06-inbox-setup-megaprompt.md) +**Source spec:** `megaprompts/06-inbox-setup-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Paired with `inbox-triage`. diff --git a/docs/skills/productivity/email-inbox-triage.md b/docs/skills/productivity/email-inbox-triage.md index 4e22e401..24cbb1af 100644 --- a/docs/skills/productivity/email-inbox-triage.md +++ b/docs/skills/productivity/email-inbox-triage.md @@ -313,5 +313,5 @@ Skip Steps 3–6 entirely on empty inbox. --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/07-inbox-triage-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/07-inbox-triage-megaprompt.md) +**Source spec:** `megaprompts/07-inbox-triage-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Paired with `inbox-setup`. diff --git a/docs/skills/productivity/reflect.md b/docs/skills/productivity/reflect.md index c30577b6..dbbfa83a 100644 --- a/docs/skills/productivity/reflect.md +++ b/docs/skills/productivity/reflect.md @@ -184,5 +184,5 @@ The closing is always specific — never "you should think more about this" or " --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/02-reflect-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/02-reflect-megaprompt.md) +**Source spec:** `megaprompts/02-reflect-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Productivity light-prompt-flow sibling of capture. diff --git a/docs/skills/research/dossier.md b/docs/skills/research/dossier.md index 9e19d3b4..ebea79c4 100644 --- a/docs/skills/research/dossier.md +++ b/docs/skills/research/dossier.md @@ -319,5 +319,5 @@ new ExternalHyperlink({ --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/12-dossier-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/12-dossier-megaprompt.md) +**Source spec:** `megaprompts/12-dossier-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Research-pack sibling, hypothesis-testing variant. diff --git a/docs/skills/research/grants.md b/docs/skills/research/grants.md index aca38b50..9868c2c8 100644 --- a/docs/skills/research/grants.md +++ b/docs/skills/research/grants.md @@ -287,5 +287,5 @@ This is the single most valuable advice for any applicant. Never skip. --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/08-grants-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/08-grants-megaprompt.md) +**Source spec:** `megaprompts/08-grants-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Research-pack sibling of pulse + litreview. diff --git a/docs/skills/research/litreview.md b/docs/skills/research/litreview.md index 0e57b221..bf4f8da6 100644 --- a/docs/skills/research/litreview.md +++ b/docs/skills/research/litreview.md @@ -252,5 +252,5 @@ Plus: --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/09-litreview-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/09-litreview-megaprompt.md) +**Source spec:** `megaprompts/09-litreview-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Sibling of `pulse` (research-pack shape). diff --git a/docs/skills/research/notebooklm.md b/docs/skills/research/notebooklm.md index d50a0248..20797922 100644 --- a/docs/skills/research/notebooklm.md +++ b/docs/skills/research/notebooklm.md @@ -299,5 +299,5 @@ After completing any action: --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/03-notebooklm-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/03-notebooklm-megaprompt.md) +**Source spec:** `megaprompts/03-notebooklm-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Browser-automation shape — distinct from research-pack convention. diff --git a/docs/skills/research/patent.md b/docs/skills/research/patent.md index 619ae86b..cf57cc35 100644 --- a/docs/skills/research/patent.md +++ b/docs/skills/research/patent.md @@ -288,5 +288,5 @@ Surface the **legally-relevant date** per sub-use-case: --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/11-patent-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/11-patent-megaprompt.md) +**Source spec:** `megaprompts/11-patent-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Research-pack sibling, sub-use-case routing variant. diff --git a/docs/skills/research/pulse.md b/docs/skills/research/pulse.md index 7b843b44..16105ac5 100644 --- a/docs/skills/research/pulse.md +++ b/docs/skills/research/pulse.md @@ -259,5 +259,5 @@ Sources received: M. Sources cited: K. Training knowledge: 0 ([Background] exclu --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/01-pulse-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/01-pulse-megaprompt.md) +**Source spec:** `megaprompts/01-pulse-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Re-grill with `/cs:grill-with-docs` if drift between spec and implementation surfaces. diff --git a/docs/skills/research/research.md b/docs/skills/research/research.md index a0735d3c..28e34946 100644 --- a/docs/skills/research/research.md +++ b/docs/skills/research/research.md @@ -326,5 +326,5 @@ All routing decisions + overrides also logged to `~/.research_sessions/ --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/13-research-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/13-research-megaprompt.md) +**Source spec:** `megaprompts/13-research-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion) diff --git a/docs/skills/research/syllabus.md b/docs/skills/research/syllabus.md index cb3f9f0c..d11d1d52 100644 --- a/docs/skills/research/syllabus.md +++ b/docs/skills/research/syllabus.md @@ -294,5 +294,5 @@ See [`references/bundled_script_pattern.md`](https://github.com/alirezarezvani/c --- **Version:** 1.0.0 -**Source spec:** [`megaprompts/10-syllabus-megaprompt.md`](https://github.com/alirezarezvani/claude-skills/tree/main/megaprompts/10-syllabus-megaprompt.md) +**Source spec:** `megaprompts/10-syllabus-megaprompt.md` (maintainer-local draft spec — gitignored, not in the public repo) **Build pattern:** Path B (direct conversion). Bundled-JS-DOCX-generator variant. diff --git a/engineering-team/TEAM_STRUCTURE_GUIDE.md b/engineering-team/TEAM_STRUCTURE_GUIDE.md index e22343fc..136f11e6 100644 --- a/engineering-team/TEAM_STRUCTURE_GUIDE.md +++ b/engineering-team/TEAM_STRUCTURE_GUIDE.md @@ -341,7 +341,7 @@ python scripts/model_deployment_pipeline.py --train --config model_config.yaml # 4. Optimize prompts cd ../senior-prompt-engineer -python scripts/prompt_optimizer.py --model gpt-4 --task classification +python scripts/prompt_optimizer.py classification_prompt.txt --analyze --model claude # 5. Deploy with DevOps cd ../senior-devops diff --git a/engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py b/engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py index 89d3c0f7..6ad7cc21 100644 --- a/engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py +++ b/engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py @@ -16,12 +16,14 @@ Usage: python3 gws_recipe_runner.py --search "email" python3 gws_recipe_runner.py --describe standup-report python3 gws_recipe_runner.py --run standup-report --dry-run + python3 gws_recipe_runner.py --run standup-report --yes python3 gws_recipe_runner.py --persona pm --list python3 gws_recipe_runner.py --list --json """ import argparse import json +import shlex import subprocess import sys from dataclasses import dataclass, field, asdict @@ -308,7 +310,7 @@ def describe_recipe(name: str, output_json: bool): print(f"\n{'='*60}\n") -def run_recipe(name: str, dry_run: bool): +def run_recipe(name: str, dry_run: bool, confirmed: bool): """Execute a recipe (or print commands in dry-run mode).""" recipe = RECIPES.get(name) if not recipe: @@ -323,6 +325,14 @@ def run_recipe(name: str, dry_run: bool): print(f"\n (No commands executed)") return + if not confirmed: + print(f"\n Refusing to execute recipe '{recipe.name}' without --yes.") + print(f" These commands may have real, irreversible side effects (sending mail,") + print(f" deleting files, sharing data, etc). Preview first with --dry-run, then") + print(f" re-run with: --run {recipe.name} --yes") + print(f"\n {TEMPLATE_NOTE}") + sys.exit(1) + print(f"\n Executing recipe: {recipe.name}") print(f" {TEMPLATE_NOTE}\n") for cmd in recipe.commands: @@ -331,7 +341,14 @@ def run_recipe(name: str, dry_run: bool): continue print(f" $ {cmd}") try: - result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30) + argv = shlex.split(cmd, comments=True) + except ValueError as e: + print(f" Could not parse command: {e}") + continue + if not argv: + continue + try: + result = subprocess.run(argv, shell=False, capture_output=True, text=True, timeout=30) if result.stdout: print(result.stdout) if result.returncode != 0 and result.stderr: @@ -369,6 +386,7 @@ Examples: %(prog)s --search "email" # Search by keyword %(prog)s --describe standup-report # Full recipe details %(prog)s --run standup-report --dry-run # Preview recipe commands + %(prog)s --run standup-report --yes # Actually execute a recipe %(prog)s --personas # List all 10 personas %(prog)s --list --json # JSON output """, @@ -378,6 +396,8 @@ Examples: parser.add_argument("--describe", help="Show full details for a recipe") parser.add_argument("--run", help="Execute a recipe") parser.add_argument("--dry-run", action="store_true", help="Print commands without executing") + parser.add_argument("--yes", action="store_true", + help="Confirm execution of a real (non-dry-run) recipe; required to actually run commands") parser.add_argument("--persona", help="Filter recipes by persona") parser.add_argument("--personas", action="store_true", help="List all personas") parser.add_argument("--json", action="store_true", help="Output JSON") @@ -404,7 +424,7 @@ Examples: return if args.run: - run_recipe(args.run, args.dry_run) + run_recipe(args.run, args.dry_run, args.yes) return diff --git a/engineering-team/playwright-pro/CLAUDE.md b/engineering-team/playwright-pro/CLAUDE.md index 2bb253b4..9fbb21ee 100644 --- a/engineering-team/playwright-pro/CLAUDE.md +++ b/engineering-team/playwright-pro/CLAUDE.md @@ -68,7 +68,7 @@ Leverage Claude Code's built-in capabilities: - **Large migrations**: Use `/batch` for parallel file-by-file conversion - **Post-generation cleanup**: Use `/simplify` after generating a test suite - **Debugging sessions**: Use `/debug` alongside `/pw:fix` for trace analysis -- **Code review**: Use `/review` for general code quality, `/pw:review` for Playwright-specific +- **Code review**: Use `/review` for general code quality, `/pw:pw-review` for Playwright-specific ### Integrations diff --git a/engineering-team/playwright-pro/README.md b/engineering-team/playwright-pro/README.md index 6f5dc036..3e31f2d3 100644 --- a/engineering-team/playwright-pro/README.md +++ b/engineering-team/playwright-pro/README.md @@ -18,9 +18,9 @@ claude --plugin-dir ./engineering-team/playwright-pro | Command | What it does | |---|---| -| `/pw:init` | Set up Playwright in your project — detects framework, generates config, CI, first test | +| `/pw:pw-init` | Set up Playwright in your project — detects framework, generates config, CI, first test | | `/pw:generate ` | Generate tests from a user story, URL, or component name | -| `/pw:review` | Review existing tests for anti-patterns and coverage gaps | +| `/pw:pw-review` | Review existing tests for anti-patterns and coverage gaps | | `/pw:fix ` | Diagnose and fix a failing or flaky test | | `/pw:migrate` | Migrate from Cypress or Selenium to Playwright | | `/pw:coverage` | Analyze what's tested vs. what's missing | @@ -32,7 +32,7 @@ claude --plugin-dir ./engineering-team/playwright-pro ```bash # In Claude Code: -/pw:init # Set up Playwright +/pw:pw-init # Set up Playwright /pw:generate "user can log in" # Generate your first test # Tests are auto-validated by hooks — no extra steps ``` @@ -116,7 +116,7 @@ Playwright Pro doesn't reinvent what your AI agent already does. It orchestrates - `/pw:generate` uses Claude's `Explore` subagent to understand your codebase before generating tests - `/pw:migrate` uses `/batch` for parallel file-by-file conversion on large test suites - `/pw:fix` uses `/debug` for trace analysis alongside Playwright-specific diagnostics -- `/pw:review` extends `/review` with Playwright anti-pattern detection +- `/pw:pw-review` extends `/review` with Playwright anti-pattern detection ## Reference diff --git a/engineering-team/playwright-pro/hooks/hooks.json b/engineering-team/playwright-pro/hooks/hooks.json index aede756d..38f5c9d3 100644 --- a/engineering-team/playwright-pro/hooks/hooks.json +++ b/engineering-team/playwright-pro/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/validate-test.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/validate-test.sh\"" } ] } @@ -16,7 +16,7 @@ "hooks": [ { "type": "command", - "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/detect-playwright.sh" + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/detect-playwright.sh\"" } ] } diff --git a/engineering-team/playwright-pro/skills/migrate/SKILL.md b/engineering-team/playwright-pro/skills/migrate/SKILL.md index f704570b..7ad3dcb4 100644 --- a/engineering-team/playwright-pro/skills/migrate/SKILL.md +++ b/engineering-team/playwright-pro/skills/migrate/SKILL.md @@ -47,7 +47,7 @@ Migration Assessment: ### 3. Set Up Playwright (If Not Present) -Run `/pw:init` first if Playwright isn't configured. +Run `/pw:pw-init` first if Playwright isn't configured. ### 4. Convert Files diff --git a/engineering-team/playwright-pro/skills/init/SKILL.md b/engineering-team/playwright-pro/skills/pw-init/SKILL.md similarity index 99% rename from engineering-team/playwright-pro/skills/init/SKILL.md rename to engineering-team/playwright-pro/skills/pw-init/SKILL.md index 606aef9b..683bd20c 100644 --- a/engineering-team/playwright-pro/skills/init/SKILL.md +++ b/engineering-team/playwright-pro/skills/pw-init/SKILL.md @@ -1,5 +1,5 @@ --- -name: "init" +name: "pw-init" description: >- Set up Playwright in a project. Use when user says "set up playwright", "add e2e tests", "configure playwright", "testing setup", "init playwright", diff --git a/engineering-team/playwright-pro/skills/review/SKILL.md b/engineering-team/playwright-pro/skills/pw-review/SKILL.md similarity index 99% rename from engineering-team/playwright-pro/skills/review/SKILL.md rename to engineering-team/playwright-pro/skills/pw-review/SKILL.md index f5dab9bf..d34b22e8 100644 --- a/engineering-team/playwright-pro/skills/review/SKILL.md +++ b/engineering-team/playwright-pro/skills/pw-review/SKILL.md @@ -1,5 +1,5 @@ --- -name: "review" +name: "pw-review" description: >- Review Playwright tests for quality. Use when user says "review tests", "check test quality", "audit tests", "improve tests", "test code review", diff --git a/engineering-team/playwright-pro/skills/review/anti-patterns.md b/engineering-team/playwright-pro/skills/pw-review/anti-patterns.md similarity index 100% rename from engineering-team/playwright-pro/skills/review/anti-patterns.md rename to engineering-team/playwright-pro/skills/pw-review/anti-patterns.md diff --git a/engineering-team/playwright-pro/skills/pw/SKILL.md b/engineering-team/playwright-pro/skills/pw/SKILL.md index 7b771107..3647e875 100644 --- a/engineering-team/playwright-pro/skills/pw/SKILL.md +++ b/engineering-team/playwright-pro/skills/pw/SKILL.md @@ -13,9 +13,9 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: | Command | What it does | |---|---| -| `/pw:init` | Set up Playwright — detects framework, generates config, CI, first test | +| `/pw:pw-init` | Set up Playwright — detects framework, generates config, CI, first test | | `/pw:generate ` | Generate tests from user story, URL, or component | -| `/pw:review` | Review tests for anti-patterns and coverage gaps | +| `/pw:pw-review` | Review tests for anti-patterns and coverage gaps | | `/pw:fix ` | Diagnose and fix failing or flaky tests | | `/pw:migrate` | Migrate from Cypress or Selenium to Playwright | | `/pw:coverage` | Analyze what's tested vs. what's missing | @@ -28,14 +28,14 @@ When installed as a Claude Code plugin, these are available as `/pw:` commands: The recommended sequence for most projects: ``` -1. /pw:init → scaffolds config, CI pipeline, and a first smoke test +1. /pw:pw-init → scaffolds config, CI pipeline, and a first smoke test 2. /pw:generate → generates tests from your spec or URL -3. /pw:review → validates quality and flags anti-patterns ← always run after generate +3. /pw:pw-review → validates quality and flags anti-patterns ← always run after generate 4. /pw:fix → diagnoses and repairs any failing/flaky tests ← run when CI turns red ``` **Validation checkpoints:** -- After `/pw:generate` — always run `/pw:review` before committing; it catches locator anti-patterns and missing assertions automatically. +- After `/pw:generate` — always run `/pw:pw-review` before committing; it catches locator anti-patterns and missing assertions automatically. - After `/pw:fix` — re-run the full suite locally (`npx playwright test`) to confirm the fix doesn't introduce regressions. - After `/pw:migrate` — run `/pw:coverage` to confirm parity with the old suite before decommissioning Cypress/Selenium tests. @@ -49,7 +49,7 @@ The recommended sequence for most projects: # → Playwright Pro creates the file using the auth template. # 2. Review the generated tests -/pw:review tests/auth/login.spec.ts +/pw:pw-review tests/auth/login.spec.ts # → Flags: one test used page.locator('input[type=password]') — suggests getByLabel('Password') # → Fix applied automatically. diff --git a/engineering-team/self-improving-agent/hooks/hooks.json b/engineering-team/self-improving-agent/hooks/hooks.json index d9195c5b..71fe0814 100644 --- a/engineering-team/self-improving-agent/hooks/hooks.json +++ b/engineering-team/self-improving-agent/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/error-capture.sh" + "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/error-capture.sh\"" } ] } diff --git a/engineering-team/self-improving-agent/settings.json b/engineering-team/self-improving-agent/settings.json index 1b708583..403cb977 100644 --- a/engineering-team/self-improving-agent/settings.json +++ b/engineering-team/self-improving-agent/settings.json @@ -18,7 +18,7 @@ }, "hooks": { "PostToolUse": { - "Bash": "${CLAUDE_PLUGIN_ROOT}/hooks/error-capture.sh" + "Bash": "\"${CLAUDE_PLUGIN_ROOT}/hooks/error-capture.sh\"" } }, "agents": [ diff --git a/engineering-team/skills/aws-solution-architect/references/service_selection.md b/engineering-team/skills/aws-solution-architect/references/service_selection.md index a81bed2d..75d8b681 100644 --- a/engineering-team/skills/aws-solution-architect/references/service_selection.md +++ b/engineering-team/skills/aws-solution-architect/references/service_selection.md @@ -119,7 +119,7 @@ Limits: - GSI: 20 per table Pricing: -- On-demand: $1.25 per million writes, $0.25 per million reads +- On-demand: $0.625 per million writes, $0.125 per million strongly consistent reads (us-east-1, after the Nov 2024 50% price cut) - Provisioned: Per RCU/WCU ``` diff --git a/engineering-team/skills/embedded-iot-mentor/SKILL.md b/engineering-team/skills/embedded-iot-mentor/SKILL.md new file mode 100644 index 00000000..2c1f67e4 --- /dev/null +++ b/engineering-team/skills/embedded-iot-mentor/SKILL.md @@ -0,0 +1,141 @@ +--- +name: "embedded-iot-mentor" +description: Mentor for embedded and IoT hardware projects. Helps select MCUs, dev boards, and toolchains, decides where sensor readings end up (phone, PC, dashboard, or alert), and gives time/cost estimates and a phased build plan from breadboard MVP to production PCB. Use when the user mentions embedded, IoT, microcontroller, ESP32, STM32, Arduino, Raspberry Pi Pico, firmware, PCB, KiCad, EasyEDA, PlatformIO, MQTT, Home Assistant, ESPHome, Grafana, an IoT dashboard, seeing sensor data on a phone, or asks for hardware tool recommendations, project planning, or cost/time estimates for an electronics project. +--- + +# Embedded / IoT Mentor + +## Overview + +Act as an experienced embedded-systems and IoT mentor. Guide from idea to a working breadboard MVP first — later stages (engineering prototype, production) only on explicit request. Always adapt to the user's stated experience, budget, timeline, and production intent. + +Most embedded advice fails in one of two directions: a parts list with no plan, or a production roadmap for someone who hasn't blinked an LED yet. Ask what the user has actually built before, then answer at that level. + +## Core style rules + +- **Simple language.** Avoid jargon. If a term is needed, give a one-line plain explanation. +- **MVP first.** Stop at a working breadboard/MVP unless the user asks for later stages. Say later stages are available when they're ready. +- **Primary + one alternative** for every major choice, with the trade-off in a clause. A second alternative only when it wins in a genuinely different situation. +- Separate the hardware path from the software/firmware path. +- Call out the 2-4 biggest risks (power, supply, debug, certification, learning curve). +- Never assume the user owns tools or already knows a platform. +- **Buy-ability is regional.** Once the user's country is known, judge parts and boards against what they can actually order. +- **Firmware that already exists beats firmware to be written.** Check for a maintained ready-made project before proposing any code. Writing firmware is a cost the user pays, not a deliverable they receive. +- **Say what a sensor really measures.** If a part infers the quantity the user asked for rather than sensing it, name the gap and build the project around what *is* measurable. + +## When called with no project details + +1. Ask a short set of clarifying questions (below), one at a time — a wall of ten questions turns people away. +2. Offer a simple decision tree so the user can self-place their experience level. +3. Give 2-3 concrete example projects matched to that level. +4. Use the answers to improve later recommendations. + +### Clarifying questions (ask only what is still missing) + +1. **Goal** — what should the device do when it is "done"? +2. **Experience** — ask as two separate axes, never one: how much *code* have they written, and how much *hardware* have they built (soldered, breadboarded, read a datasheet)? Strong on one and new to the other is the common case. +3. **Budget** — parts only, or tools + PCB runs too? +4. **Timeline** — weekend / a few weeks / months / product launch? +5. **Location** — which country do they buy parts and boards from? Drives availability, fab choice, and shipping time. +6. **Power** — battery, USB, mains, or harvesting? +7. **Environment** — indoors, outdoors, wet, dusty, temperature extremes? Outdoors makes the enclosure real design work, not an afterthought. +8. **Connectivity** — none, BLE, Wi-Fi, LoRa, cellular, wired? For anything spread out, ask how many sensing points and how far the furthest one is. +9. **Viewing** — who looks at the readings, from where, and do they want a live number, a history, or an alert? +10. **Volume** — one-off, tens, hundreds, thousands? +11. **Hard limits** — size, cost target, language preference, open-source only, existing parts? + +## Recommendation process + +Datasheet-level facts behind the tables below (per-family power figures, PIO, toolchains, power-budget arithmetic) live in `references/hardware-selection.md` — cite it when a recommendation gets a "why that board?" follow-up. + +### 1. MCU / platform + +Choose the simplest platform that meets requirements. + +| Situation | Primary | Good alternatives | +|-----------|---------|-------------------| +| Beginner or fast PoC | ESP32 DevKit | Pico W, Arduino Nano | +| Low power / battery | nRF52 / STM32L | ESP32-C3 with care | +| Rich peripherals / pro debug | STM32 Nucleo | ESP32-S3 | +| Tiny / cheap at volume | Evaluate after MVP | — | + +### 2. Hardware path (stop after MVP unless asked) + +**MVP (the default end of the plan):** official or well-known dev board + breadboard + jumper wires + common breakouts; modules with built-in USB, regulator, and antenna (if RF). + +Only if the user asks for later stages: perfboard or a first cheap 2-layer PCB (JLCPCB / PCBWay / local), then a proper schematic, DFM check, and enclosure. Tools (free by default): KiCad (primary) or EasyEDA (fast order). + +### 3. Software / toolchain + +Ask first whether any code has to be written at all. For a common job — a sensor into a dashboard, a mesh of radios, a smart plug — a maintained ready-made firmware usually exists, and several flash from a browser page with nothing installed. + +| User background | Prefer | +|-----------------|--------| +| Does not write code, or doesn't want to | Ready-made firmware: ESPHome, Meshtastic, Tasmota, WLED. Web flasher where there is one | +| Beginner | Arduino IDE or Arduino core in PlatformIO | +| Wants structure | PlatformIO + VS Code (default for most) | +| Vendor / advanced debug | STM32CubeIDE, ESP-IDF, nRF Connect SDK | +| Prefers scripting | MicroPython / CircuitPython when well supported | + +Where code *is* written, cover: serial console, a debugger (USB-UART, ST-Link, CMSIS-DAP), basic project layout, and version control. Where it is not, skip all four. + +### 4. Where the data is seen + +Firmware that reads a sensor is half the job; the reading still has to reach a person. Ask who looks, from where, and whether they want a live number, a history, or an alert — most people asking for a dashboard actually want the alert. + +| Situation | Primary | Alternative | +|---|---|---| +| Home network + an always-on box | Home Assistant + ESPHome | MQTT + Node-RED when other systems must be fed | +| One device, live values, no history | The page the device serves itself | BLE and an existing phone app | +| No always-on box | Hosted dashboard on its free tier | SD-card log collected by hand | +| Long history, many nodes, real charts | InfluxDB + Grafana | The hosted dashboard's own history, within its tier | + +Two things to flag before they get built in: "on my phone" is not "from anywhere" — away from home means a VPN, a tunnel, or a hosted service, never a port forward — and a custom mobile app is the most expensive answer here, rarely the MVP one. + +### 5. Time & cost snapshot + +Give ranges only, sourced from LCSC / Digi-Key / local stores. Flag certification (FCC/CE) as a cost/risk call-out, not a full guide. A deployed device also has a running cost: batteries × node count × replacements per year, plus any subscription or gateway — quote it whenever the build is deployed rather than demonstrated. + +### 6. Phased plan (MVP only by default) + +1. **MVP (breadboard)** — minimum features that prove the idea. List key hardware choices, software milestones, and exit criteria. + +Later phases (engineering prototype, pre-production, production) are supplied only on request. + +## Output format (project answers) + +| Section | Cap | Drop it when | +|---|---|---| +| Understanding | 1 line | The brief was already unambiguous | +| Recommended stack | 1 table: primary + alternative + why | — | +| Where the data is seen | 1 line, or one row in the stack table | The device is its own display, or the user already named the dashboard | +| Time & cost | 1 small table | Neither money nor schedule is in play | +| MVP plan | 3-5 numbered steps, one line each, with exit criteria | — | +| Next actions | 3 bullets | They restate the MVP steps | +| Risks | 2-4 bullets, one line each | — | + +Three solid sections beat six thin ones. A narrow question ("which regulator?") gets answered directly — no project breakdown, no MVP plan, no cost table. + +## Worked mini-example + +Request: "I want to know when my greenhouse gets too cold at night, on my phone." +- Sensor truth: "too cold" = air temperature at plant height — a $2 DS18B20 or SHT31, not a soil probe. +- Reuse first: SHT31 is in ESPHome's component list, so firmware cost is a 20-line YAML file, not C code. +- Board: ESP32 devkit — Wi-Fi reaches the house, and Home Assistant gives the phone notification for free. +- "On my phone" away from home means Home Assistant behind a tunnel (Nabu Casa or a VPN) — never a port forward. +- Power: mains adapter if an outlet is within reach; otherwise the duty-cycle arithmetic in `references/hardware-selection.md` decides the battery. +- Stop at breadboard MVP: one night of data proves the alert threshold before any enclosure or PCB talk. + +## Anti-Patterns + +- **Handing a production roadmap to a beginner, or a beginner's MVP plan to a professional.** Match the reply to the stated experience level; unwanted structure reads as condescension either way. +- **Recommending a part the user can't source.** Buy-ability is regional — check against what they can actually order before naming it. +- **Writing firmware from scratch before checking for a maintained ready-made project.** Custom firmware is a cost the user pays, not a deliverable they receive. +- **Quietly substituting a proxy measurement.** If a cheap sensor infers a quantity rather than sensing it (e.g. a "soil NPK" probe reading conductivity), say so — never let the user believe they got what they asked for. +- **Skipping the running cost of a deployed device.** Battery replacements and subscriptions across many nodes often decide the design more than the parts list does. +- **Treating "see it on my phone" as solved by a port forward.** Away-from-home access needs a VPN, tunnel, or hosted service. + +## Cross-References + +- `engineering-team/skills/tech-stack-evaluator` — for software-stack TCO/migration analysis once the project has firmware and needs a backend or cloud comparison. +- `engineering-team/skills/senior-architect` — for architecture decisions once the project graduates past MVP into a larger system. diff --git a/engineering-team/skills/embedded-iot-mentor/references/hardware-selection.md b/engineering-team/skills/embedded-iot-mentor/references/hardware-selection.md new file mode 100644 index 00000000..115c11d3 --- /dev/null +++ b/engineering-team/skills/embedded-iot-mentor/references/hardware-selection.md @@ -0,0 +1,39 @@ +# Hardware selection — datasheet-anchored notes behind the MCU table + +The SKILL.md decision table is the fast path. This reference carries the +datasheet-level facts behind it, so recommendations survive a "why that board?" +follow-up and stay checkable against primary sources. + +## MCU families — what actually differentiates them + +| Family | Anchor facts (from vendor docs) | Pick it when | +|---|---|---| +| **ESP32 family** (ESP32, -S3, -C3) | Wi-Fi + BLE on chip; -S3 adds vector instructions for edge inference; -C3 is RISC-V single-core for cost-down. Deep-sleep current ~10 µA class (ESP32-S3 datasheet §Electrical Characteristics). First-class ESPHome/Arduino/ESP-IDF support. | Wi-Fi-connected sensing/actuation, Home Assistant integration, fastest firmware-reuse path. | +| **Raspberry Pi Pico W** (RP2040 + CYW43439) | Dual M0+ @133 MHz, 264 KB SRAM, PIO state machines for cycle-accurate custom I/O (RP2040 datasheet ch. 3). No hardware crypto acceleration. MicroPython/C SDK. | Custom protocol bit-banging (PIO), education, tight-budget Wi-Fi nodes. | +| **STM32 series** (F0/F4/L4/H7 …) | Broadest peripheral + package range; L-series shutdown current down to ~30 nA class (STM32L4 datasheet); mature HAL/LL + CubeMX codegen; industrial temperature grades. | Battery-first designs, motor control, anything headed to a certified/industrial product. | +| **nRF52 / nRF53** (Nordic) | BLE 5.x leader; sub-µA system-off retention current (nRF52840 PS §Power); SoftDevice/Zephyr stacks; strong DFU story. | BLE-first wearables/beacons, coin-cell budgets, Thread/Matter-over-Thread experiments. | + +## Toolchain notes + +- **ESPHome / Tasmota / WLED / Meshtastic** — configuration-first firmware; the reuse-first doctrine's step 1. ESPHome docs list supported sensors; if the sensor is listed, firmware cost ≈ zero. +- **PlatformIO** — one build system across all four families; pins toolchain versions in `platformio.ini`, which is what makes a hobby repo reproducible a year later. +- **Zephyr RTOS** — Nordic's first-class path and the vendor-neutral industrial default; steeper ramp, pays off at product stage. + +## Power-budget arithmetic (the part most projects skip) + +Battery life ≈ capacity (mAh) ÷ average current (mA). Average current for a +duty-cycled sensor node = (t_active × I_active + t_sleep × I_sleep) ÷ period. +A 2500 mAh cell with 5 s @ 80 mA every 10 min and ~10 µA sleep averages +≈ 0.68 mA → roughly 5 months. Radio choice dominates I_active; sleep current +dominates everything past ~15-minute reporting intervals — which is why the +deep-sleep figures in the table above, not CPU speed, decide battery designs. + +## Sources + +1. Espressif — *ESP32-S3 Series Datasheet* and *ESP-IDF Programming Guide* (docs.espressif.com) — radio/power figures and supported-peripheral matrix. +2. Raspberry Pi — *RP2040 Datasheet* (datasheets.raspberrypi.com), ch. 3 "PIO" — the programmable-I/O capability the Pico row leans on. +3. STMicroelectronics — *STM32L4 Series Datasheet* + AN4746 low-power application note (st.com) — stop/shutdown-mode current classes and wake latency. +4. Nordic Semiconductor — *nRF52840 Product Specification* (infocenter.nordicsemi.com) — system-off retention currents and BLE stack architecture. +5. ESPHome documentation (esphome.io) — the supported-components index used by the firmware-reuse-first step. +6. PlatformIO documentation (docs.platformio.org) — cross-family builds and version pinning. +7. Zephyr Project documentation (docs.zephyrproject.org) — supported-boards catalog and power-management subsystem. diff --git a/engineering-team/skills/senior-ml-engineer/SKILL.md b/engineering-team/skills/senior-ml-engineer/SKILL.md index 59943690..6205ef1f 100644 --- a/engineering-team/skills/senior-ml-engineer/SKILL.md +++ b/engineering-team/skills/senior-ml-engineer/SKILL.md @@ -149,12 +149,23 @@ def call_llm_with_retry(provider: LLMProvider, prompt: str) -> str: ### Cost Management -| Provider | Input Cost | Output Cost | -|----------|------------|-------------| -| GPT-4 | $0.03/1K | $0.06/1K | -| GPT-3.5 | $0.0005/1K | $0.0015/1K | -| Claude 3 Opus | $0.015/1K | $0.075/1K | -| Claude 3 Haiku | $0.00025/1K | $0.00125/1K | +Do not hardcode prices, and do not trust a price table you find in a document +(including this one). Providers reprice several times a year, and a stale +figure produces a confidently wrong business case. + +Work in tiers and look the current numbers up at request time: + +| Tier | Typical use | Relative cost | +|------|-------------|---------------| +| Small | Classification, extraction, routing, short output | 1x baseline | +| Mid | Summarisation, structured output, moderate reasoning | ~10-25x small | +| Large | Multi-step reasoning, code generation, long context | ~50-100x small | + +Read the live rate from your provider's pricing page and pass it in, the way +`engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py` +takes `--price-per-mtok`. +The ratios between tiers are far more stable than the absolute prices, so +build the model-routing decision on the ratio. --- diff --git a/engineering-team/skills/senior-ml-engineer/references/llm_integration_guide.md b/engineering-team/skills/senior-ml-engineer/references/llm_integration_guide.md index 6e715ab1..0cd90c0e 100644 --- a/engineering-team/skills/senior-ml-engineer/references/llm_integration_guide.md +++ b/engineering-team/skills/senior-ml-engineer/references/llm_integration_guide.md @@ -34,7 +34,9 @@ class LLMProvider(ABC): pass class OpenAIProvider(LLMProvider): - def __init__(self, api_key: str, model: str = "gpt-4"): + # No default model: a hardcoded default is the thing that goes stale. + # Pass the model your deployment is pinned to, from config. + def __init__(self, api_key: str, model: str): self.client = OpenAI(api_key=api_key) self.model = model @@ -47,7 +49,7 @@ class OpenAIProvider(LLMProvider): return response.choices[0].text class AnthropicProvider(LLMProvider): - def __init__(self, api_key: str, model: str = "claude-3-opus"): + def __init__(self, api_key: str, model: str = "claude-opus-5"): self.client = Anthropic(api_key=api_key) self.model = model @@ -158,14 +160,19 @@ def create_chat_messages(user_query: str, context: str) -> List[Dict]: ```python import tiktoken -def count_tokens(text: str, model: str = "gpt-4") -> int: - """Count tokens for a given text and model.""" - encoding = tiktoken.encoding_for_model(model) +def count_tokens(text: str, encoding_name: str = "cl100k_base") -> int: + """Count tokens for a given text. + + Takes an encoding name rather than a model name: encodings change far more + slowly than model IDs, and tiktoken.encoding_for_model() raises KeyError on + any model it has not shipped a mapping for yet. + """ + encoding = tiktoken.get_encoding(encoding_name) return len(encoding.encode(text)) -def truncate_to_token_limit(text: str, max_tokens: int, model: str = "gpt-4") -> str: +def truncate_to_token_limit(text: str, max_tokens: int, encoding_name: str = "cl100k_base") -> str: """Truncate text to fit within token limit.""" - encoding = tiktoken.encoding_for_model(model) + encoding = tiktoken.get_encoding(encoding_name) tokens = encoding.encode(text) if len(tokens) <= max_tokens: @@ -176,12 +183,13 @@ def truncate_to_token_limit(text: str, max_tokens: int, model: str = "gpt-4") -> ### Context Window Management -| Model | Context Window | Effective Limit | -|-------|----------------|-----------------| -| GPT-4 | 8,192 | ~6,000 (leave room for response) | -| GPT-4-32k | 32,768 | ~28,000 | -| Claude 3 | 200,000 | ~180,000 | -| Llama 3 | 8,192 | ~6,000 | +Query the model's advertised context window at runtime rather than table it +here; every fixed number in this position has gone stale within a year. + +The rule that does not change: reserve headroom for the response. Budget +roughly 75-90% of the window for input and leave the remainder for output, +then cap output explicitly with `max_tokens` so a runaway generation cannot +overflow the window or the bill. ### Chunking Strategy @@ -206,12 +214,9 @@ def chunk_text(text: str, chunk_size: int = 1000, overlap: int = 100) -> List[st ### Cost Calculation -| Provider | Input Cost | Output Cost | Example (1K tokens) | -|----------|------------|-------------|---------------------| -| GPT-4 | $0.03/1K | $0.06/1K | $0.09 | -| GPT-3.5 | $0.0005/1K | $0.0015/1K | $0.002 | -| Claude 3 Opus | $0.015/1K | $0.075/1K | $0.09 | -| Claude 3 Haiku | $0.00025/1K | $0.00125/1K | $0.0015 | +Prices move several times a year, so this guide does not carry a rate table. +Pull the current per-million-token input and output prices from your +provider's pricing page and inject them as configuration. ### Cost Tracking @@ -229,26 +234,24 @@ class LLMUsage: def calculate_cost( input_tokens: int, output_tokens: int, - model: str + input_price_per_mtok: float, + output_price_per_mtok: float, ) -> float: - """Calculate cost based on token usage.""" - PRICING = { - "gpt-4": {"input": 0.03, "output": 0.06}, - "gpt-3.5-turbo": {"input": 0.0005, "output": 0.0015}, - "claude-3-opus": {"input": 0.015, "output": 0.075}, - } + """Calculate cost from caller-supplied rates (USD per million tokens). - prices = PRICING.get(model, {"input": 0.01, "output": 0.03}) - - input_cost = (input_tokens / 1000) * prices["input"] - output_cost = (output_tokens / 1000) * prices["output"] + Rates are parameters, not constants. A hardcoded price table is wrong + within a year and silently produces a confidently incorrect business case. + Load these from config so they can be updated without a code change. + """ + input_cost = (input_tokens / 1_000_000) * input_price_per_mtok + output_cost = (output_tokens / 1_000_000) * output_price_per_mtok return input_cost + output_cost ``` ### Cost Optimization Strategies -1. **Use smaller models for simple tasks** - GPT-3.5 for classification, GPT-4 for reasoning +1. **Use smaller models for simple tasks** - small tier for classification, large tier for reasoning 2. **Cache common responses** - Store results for repeated queries 3. **Batch requests** - Combine multiple items in single prompt 4. **Truncate context** - Only include relevant information diff --git a/engineering/agent-harness/skills/agent-harness/assets/harnesses/c-level-advisor.json b/engineering/agent-harness/skills/agent-harness/assets/harnesses/c-level-advisor.json index 82e72951..7368e894 100644 --- a/engineering/agent-harness/skills/agent-harness/assets/harnesses/c-level-advisor.json +++ b/engineering/agent-harness/skills/agent-harness/assets/harnesses/c-level-advisor.json @@ -85,7 +85,7 @@ }, { "name": "boardroom", - "path": "c-level-advisor/c-level-agents/skills/boardroom", + "path": "c-level-agents/skills/boardroom", "description": "/cs:boardroom \u2014 6-phase multi-role deliberation across the C-suite with Phase 2 isolation, critic pre-screen, and synthesis. Outputs a board memo. Use when a decision spans multiple executive domains \u2014 e.g. a pricing change touching finance, positioning, and product, or a raise-vs-cut runway call.", "tools": [], "agentic_signals": { @@ -99,7 +99,7 @@ }, { "name": "brief", - "path": "c-level-advisor/c-level-agents/skills/brief", + "path": "c-level-agents/skills/brief", "description": "/cs:brief \u2014 Generate a one-page strategy brief from an office-hours intake. First step in the strategic sprint pipeline. Use when a strategic question needs to be framed before boardroom deliberation \u2014 e.g. locking options, assumptions, and success criteria for a pricing change or a market-entry decision.", "tools": [], "agentic_signals": { @@ -113,7 +113,7 @@ }, { "name": "c-level-agents", - "path": "c-level-advisor/c-level-agents/skills/c-level-agents", + "path": "c-level-agents/skills/c-level-agents", "description": "Founder-mode executive team. 13 cs-* C-suite agents (CFO, CMO, CRO, CPO, COO, CHRO, CISO, GC, CDO, CAIO, CCO, VPE, Chief of Staff) and 21 /cs:* slash commands for forcing-question office hours, multi-role boardroom deliberation, strategic sprint pipeline, and meta routing. Use when the founder needs a virtual executive team, when invoking /cs:* commands, or when orchestrating multi-role decisions.", "tools": [], "agentic_signals": { @@ -127,7 +127,7 @@ }, { "name": "caio-review", - "path": "c-level-advisor/c-level-agents/skills/caio-review", + "path": "c-level-agents/skills/caio-review", "description": "/cs:caio-review \u2014 Eval-demanding Chief AI Officer interrogation of any plan that involves AI: model selection, risk classification, cost economics, or AI hiring. Use when shipping an AI feature without an eval set, choosing between API, fine-tune, and self-hosted, or classifying a use case under the EU AI Act.", "tools": [], "agentic_signals": { @@ -141,7 +141,7 @@ }, { "name": "cco-review", - "path": "c-level-advisor/c-level-agents/skills/cco-review", + "path": "c-level-agents/skills/cco-review", "description": "/cs:cco-review \u2014 Retention-obsessed Chief Customer Officer interrogation of any plan that touches customer retention, segmentation, CS team sizing, or CS team hiring. Use when gross retention is slipping, before approving CSM headcount, or when deciding which customer segments to keep or fire.", "tools": [], "agentic_signals": { @@ -155,7 +155,7 @@ }, { "name": "cdo-review", - "path": "c-level-advisor/c-level-agents/skills/cdo-review", + "path": "c-level-agents/skills/cdo-review", "description": "/cs:cdo-review \u2014 Decision-driven Chief Data Officer interrogation of any plan that touches training data, data architecture, data productization, or data team hiring. Use when validating training-data rights before model work, choosing warehouse vs lakehouse vs mesh, or valuing data assets for productization or M&A.", "tools": [], "agentic_signals": { @@ -169,7 +169,7 @@ }, { "name": "cfo-review", - "path": "c-level-advisor/c-level-agents/skills/cfo-review", + "path": "c-level-agents/skills/cfo-review", "description": "/cs:cfo-review \u2014 Numerate-skeptic interrogation of any plan that touches money. Unit economics, runway, dilution, capital allocation. Use when a plan commits meaningful spend \u2014 e.g. a hiring wave, a fundraise decision, or a new channel budget.", "tools": [], "agentic_signals": { @@ -183,7 +183,7 @@ }, { "name": "ciso-review", - "path": "c-level-advisor/c-level-agents/skills/ciso-review", + "path": "c-level-agents/skills/ciso-review", "description": "/cs:ciso-review \u2014 Risk-paranoid interrogation of any plan that touches data, compliance, or production access. Use when launching features that handle customer data, before a SOC 2 / ISO audit, or after any incident or near-miss.", "tools": [], "agentic_signals": { @@ -197,7 +197,7 @@ }, { "name": "cmo-review", - "path": "c-level-advisor/c-level-agents/skills/cmo-review", + "path": "c-level-agents/skills/cmo-review", "description": "/cs:cmo-review \u2014 Narrative-first interrogation of positioning, ICP, message house, and channel mix. Use when launching a campaign or repositioning, or when CAC is rising and the one-sentence positioning test fails.", "tools": [], "agentic_signals": { @@ -211,7 +211,7 @@ }, { "name": "cpo-review", - "path": "c-level-advisor/c-level-agents/skills/cpo-review", + "path": "c-level-agents/skills/cpo-review", "description": "/cs:cpo-review \u2014 JTBD-driven interrogation of product roadmap, PMF signal, and portfolio focus. Use when committing a quarter's roadmap, deciding whether to kill a feature, or claiming PMF without a retention curve.", "tools": [], "agentic_signals": { @@ -225,7 +225,7 @@ }, { "name": "cro-review", - "path": "c-level-advisor/c-level-agents/skills/cro-review", + "path": "c-level-agents/skills/cro-review", "description": "/cs:cro-review \u2014 Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time. Use when the forecast misses pipeline coverage, win rates drop, or before scaling the sales team.", "tools": [], "agentic_signals": { @@ -239,7 +239,7 @@ }, { "name": "cross-eval", - "path": "c-level-advisor/c-level-agents/skills/cross-eval", + "path": "c-level-agents/skills/cross-eval", "description": "/cs:cross-eval \u2014 Multi-model consensus on a board memo or strategy brief. Claude + Codex + Gemini cross-review with graceful degradation. Use when a high-stakes memo needs an independent sanity check before the boardroom \u2014 e.g. a bet-the-company pivot or fundraise terms.", "tools": [], "agentic_signals": { @@ -253,7 +253,7 @@ }, { "name": "cto-review", - "path": "c-level-advisor/c-level-agents/skills/cto-review", + "path": "c-level-agents/skills/cto-review", "description": "/cs:cto-review \u2014 Architecture and scaling interrogation. Tech debt, scaling cliffs, team scaling, build-vs-buy. Use when committing to an architecture, planning for 10x load, or weighing a rebuild against a vendor.", "tools": [], "agentic_signals": { @@ -267,7 +267,7 @@ }, { "name": "decide", - "path": "c-level-advisor/c-level-agents/skills/decide", + "path": "c-level-agents/skills/decide", "description": "/cs:decide \u2014 Log a decision to two-layer memory via decision-logger. Approved memo becomes durable; raw transcripts kept for reference. Use when the founder has approved a boardroom memo and the decision must become durable company memory \u2014 e.g. right after /cs:boardroom concludes.", "tools": [], "agentic_signals": { @@ -281,7 +281,7 @@ }, { "name": "execute", - "path": "c-level-advisor/c-level-agents/skills/execute", + "path": "c-level-agents/skills/execute", "description": "/cs:execute \u2014 Generate a 90-day execution plan with weekly milestones, DRIs, and check-in cadence from an approved decision. Use when a logged decision needs to become an operating plan \u2014 e.g. turning an approved market-entry call into weekly milestones with DRIs.", "tools": [], "agentic_signals": { @@ -295,7 +295,7 @@ }, { "name": "founder-mode", - "path": "c-level-advisor/c-level-agents/skills/founder-mode", + "path": "c-level-agents/skills/founder-mode", "description": "/cs:founder-mode \u2014 Auto-routes any founder question to the right C-role advisor or to /cs:boardroom for multi-role topics. The single-command entry point. Use when a founder asks any strategic question without knowing which advisor or command fits \u2014 e.g. 'runway pressure' routes to the CFO, 'gross retention dropped' routes to the CCO.", "tools": [], "agentic_signals": { @@ -309,7 +309,7 @@ }, { "name": "freeze", - "path": "c-level-advisor/c-level-agents/skills/freeze", + "path": "c-level-agents/skills/freeze", "description": "/cs:freeze \u2014 Lock a strategic decision for a cooldown period to prevent impulse reversal. Mirrors gstack's safety primitives for the business layer. Use when an irreversible decision was made under pressure \u2014 e.g. a layoff plan or multi-year contract \u2014 and deserves a cooling-off lock before execution.", "tools": [], "agentic_signals": { @@ -323,7 +323,7 @@ }, { "name": "gc-review", - "path": "c-level-advisor/c-level-agents/skills/gc-review", + "path": "c-level-agents/skills/gc-review", "description": "/cs:gc-review \u2014 General Counsel interrogation of contracts, IP, regulatory, term sheets, and employment-law surface. Use when reviewing a term sheet before signing, redlining a customer MSA, or checking IP assignment and regulatory exposure on a new product.", "tools": [], "agentic_signals": { @@ -337,7 +337,7 @@ }, { "name": "office-hours", - "path": "c-level-advisor/c-level-agents/skills/office-hours", + "path": "c-level-agents/skills/office-hours", "description": "/cs:office-hours \u2014 YC-style 6-question founder interrogation before any advice. Forces clarity on problem, customer, distribution, defensibility, capital, and founder fit. Use when a founder question is too vague to route \u2014 e.g. 'should we grow faster?' \u2014 or before drafting a strategy brief.", "tools": [], "agentic_signals": { @@ -351,7 +351,7 @@ }, { "name": "onboard", - "path": "c-level-advisor/c-level-agents/skills/onboard", + "path": "c-level-agents/skills/onboard", "description": "/cs:onboard \u2014 Founder interview that populates ~/.claude/company-context.md using the canonical 7-dimension cs-onboard schema. The first command to run when starting with c-level-agents. Use when setting up the virtual C-suite for a new company, or when advisors lack company context \u2014 e.g. before a first /cs:boardroom or after a fundraise changes the numbers.", "tools": [], "agentic_signals": { @@ -365,7 +365,7 @@ }, { "name": "post-mortem", - "path": "c-level-advisor/c-level-agents/skills/post-mortem", + "path": "c-level-agents/skills/post-mortem", "description": "/cs:post-mortem \u2014 Honest retrospective on an executed decision, scored against original assumptions and dissent. Closes the strategic sprint loop. Use when a decision hits its 90-day review checkpoint or its kill criteria trigger \u2014 e.g. scoring last quarter's pricing change against its pre-committed success metrics.", "tools": [], "agentic_signals": { @@ -379,7 +379,7 @@ }, { "name": "vpe-review", - "path": "c-level-advisor/c-level-agents/skills/vpe-review", + "path": "c-level-agents/skills/vpe-review", "description": "/cs:vpe-review \u2014 Throughput-first VP of Engineering interrogation of any plan that touches delivery, eng hiring, team structure, or production discipline. Use when cycle time balloons, DORA metrics slide, or before committing to an eng hiring wave or a reorg.", "tools": [], "agentic_signals": { diff --git a/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering-team.json b/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering-team.json index 2bc775cb..d4dc5a79 100644 --- a/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering-team.json +++ b/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering-team.json @@ -204,7 +204,7 @@ }, { "name": "init", - "path": "engineering-team/playwright-pro/skills/init", + "path": "engineering-team/playwright-pro/skills/pw-init", "description": ">- Set up Playwright in a project. Use when user says \"set up playwright\", \"add e2e tests\", \"configure playwright\", \"testing setup\", \"init playwright\", or \"add test infrastructure\".", "tools": [], "agentic_signals": { @@ -260,7 +260,7 @@ }, { "name": "review", - "path": "engineering-team/playwright-pro/skills/review", + "path": "engineering-team/playwright-pro/skills/pw-review", "description": ">- Review Playwright tests for quality. Use when user says \"review tests\", \"check test quality\", \"audit tests\", \"improve tests\", \"test code review\", or \"playwright best practices check\".", "tools": [], "agentic_signals": { diff --git a/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering.json b/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering.json index 930bd191..95b3995a 100644 --- a/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering.json +++ b/engineering/agent-harness/skills/agent-harness/assets/harnesses/engineering.json @@ -204,8 +204,8 @@ }, { "name": "init", - "path": "engineering/agenthub/skills/init", - "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:init or asks to start a multi-agent competition on a task.", + "path": "engineering/agenthub/skills/hub-init", + "description": "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:hub-init or asks to start a multi-agent competition on a task.", "tools": [], "agentic_signals": { "goal_intake": false, @@ -260,8 +260,8 @@ }, { "name": "status", - "path": "engineering/agenthub/skills/status", - "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:status or asks how the AgentHub agents are doing.", + "path": "engineering/agenthub/skills/hub-status", + "description": "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:hub-status or asks how the AgentHub agents are doing.", "tools": [], "agentic_signals": { "goal_intake": false, @@ -342,8 +342,8 @@ }, { "name": "resume", - "path": "engineering/autoresearch-agent/skills/resume", - "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:resume or asks to pick up a previously started autoresearch experiment.", + "path": "engineering/autoresearch-agent/skills/ar-resume", + "description": "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:ar-resume or asks to pick up a previously started autoresearch experiment.", "tools": [], "agentic_signals": { "goal_intake": false, @@ -384,8 +384,8 @@ }, { "name": "status", - "path": "engineering/autoresearch-agent/skills/status", - "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:status or asks how an autoresearch experiment is going.", + "path": "engineering/autoresearch-agent/skills/ar-status", + "description": "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going.", "tools": [], "agentic_signals": { "goal_intake": false, diff --git a/engineering/agenthub/CLAUDE.md b/engineering/agenthub/CLAUDE.md index 2aeed9c3..00eef771 100644 --- a/engineering/agenthub/CLAUDE.md +++ b/engineering/agenthub/CLAUDE.md @@ -6,9 +6,9 @@ This plugin enables multi-agent collaboration. Spawn N parallel subagents that c Use the `/hub:` namespace for all commands: -- `/hub:init` — Create a new collaboration session (task, agent count, eval criteria) +- `/hub:hub-init` — Create a new collaboration session (task, agent count, eval criteria) - `/hub:spawn` — Launch N parallel subagents in isolated worktrees (supports `--template`) -- `/hub:status` — Show DAG state, agent progress, and branch status +- `/hub:hub-status` — Show DAG state, agent progress, and branch status - `/hub:eval` — Rank agent results by metric or LLM judge - `/hub:merge` — Merge the winning branch, archive losers - `/hub:board` — Read/write the agent message board @@ -18,7 +18,7 @@ Use the `/hub:` namespace for all commands: You (the coordinator) orchestrate N subagents working in parallel: -1. `/hub:init` — define the task, number of agents, and evaluation criteria +1. `/hub:hub-init` — define the task, number of agents, and evaluation criteria 2. `/hub:spawn` — launch all agents simultaneously via the Agent tool with `isolation: "worktree"` 3. Each agent works independently in its own git worktree, commits results, writes to the board 4. `/hub:eval` — compare results (run eval command per worktree, or LLM-judge diffs) diff --git a/engineering/agenthub/README.md b/engineering/agenthub/README.md index af2b0788..6de97b9b 100644 --- a/engineering/agenthub/README.md +++ b/engineering/agenthub/README.md @@ -15,14 +15,14 @@ Or step by step: ```bash # 1. Initialize a session — define the task, agent count, and evaluation criteria -/hub:init --task "Reduce API p50 latency" --agents 3 \ +/hub:hub-init --task "Reduce API p50 latency" --agents 3 \ --eval "pytest bench.py --json" --metric p50_ms --direction lower # 2. Spawn agents — launches 3 parallel agents in isolated worktrees /hub:spawn --template optimizer # 3. Check progress -/hub:status +/hub:hub-status # 4. Evaluate — rank agents by metric /hub:eval @@ -35,9 +35,9 @@ Or step by step: | Command | Purpose | Example | |---------|---------|---------| -| `/hub:init` | Create session with task, agents, eval criteria | `/hub:init --task "Optimize DB queries" --agents 4 --eval "python bench.py" --metric query_ms --direction lower` | +| `/hub:hub-init` | Create session with task, agents, eval criteria | `/hub:hub-init --task "Optimize DB queries" --agents 4 --eval "python bench.py" --metric query_ms --direction lower` | | `/hub:spawn` | Launch all agents in parallel worktrees | `/hub:spawn` (uses latest session) | -| `/hub:status` | Show DAG state, branches, progress posts | `/hub:status` | +| `/hub:hub-status` | Show DAG state, branches, progress posts | `/hub:hub-status` | | `/hub:eval` | Rank results by metric or LLM judge | `/hub:eval --judge` (LLM judge mode) | | `/hub:merge` | Merge winner, archive losers, cleanup | `/hub:merge --agent agent-2` (force pick) | | `/hub:board` | Read/write the message board | `/hub:board --read progress` | @@ -212,7 +212,7 @@ openclaw install agenthub ### Session Model -Each `/hub:init` creates a session with a timestamp-based ID (`YYYYMMDD-HHMMSS`). Sessions progress through states: +Each `/hub:hub-init` creates a session with a timestamp-based ID (`YYYYMMDD-HHMMSS`). Sessions progress through states: ``` init → running → evaluating → merged diff --git a/engineering/agenthub/settings.json b/engineering/agenthub/settings.json index 6bf2356b..e0d4e28a 100644 --- a/engineering/agenthub/settings.json +++ b/engineering/agenthub/settings.json @@ -10,9 +10,9 @@ "tags": ["multi-agent", "collaboration", "parallel", "git-dag", "orchestration", "competition", "content-generation", "research", "optimization"], "repository": "https://github.com/alirezarezvani/claude-skills", "commands": { - "init": "/hub:init", + "init": "/hub:hub-init", "spawn": "/hub:spawn", - "status": "/hub:status", + "status": "/hub:hub-status", "eval": "/hub:eval", "merge": "/hub:merge", "board": "/hub:board", diff --git a/engineering/agenthub/skills/agenthub/SKILL.md b/engineering/agenthub/skills/agenthub/SKILL.md index b8613a99..11e49205 100644 --- a/engineering/agenthub/skills/agenthub/SKILL.md +++ b/engineering/agenthub/skills/agenthub/SKILL.md @@ -17,9 +17,9 @@ Spawn N parallel AI agents that compete on the same task. Each agent works in an | Command | Description | |---------|-------------| -| `/hub:init` | Create a new collaboration session — task, agent count, eval criteria | +| `/hub:hub-init` | Create a new collaboration session — task, agent count, eval criteria | | `/hub:spawn` | Launch N parallel subagents in isolated worktrees | -| `/hub:status` | Show DAG state, agent progress, branch status | +| `/hub:hub-status` | Show DAG state, agent progress, branch status | | `/hub:eval` | Rank agent results by metric or LLM judge | | `/hub:merge` | Merge winning branch, archive losers | | `/hub:board` | Read/write the agent message board | @@ -62,7 +62,7 @@ INIT → DISPATCH → MONITOR → EVALUATE → MERGE ### 1. Init -Run `/hub:init` to create a session. This generates: +Run `/hub:hub-init` to create a session. This generates: - `.agenthub/sessions/{session-id}/config.yaml` — task config - `.agenthub/sessions/{session-id}/state.json` — state machine - `.agenthub/board/` — message board channels @@ -76,7 +76,7 @@ Run `/hub:spawn` to launch agents. For each agent 1..N: ### 3. Monitor -Run `/hub:status` to check progress: +Run `/hub:hub-status` to check progress: - `dag_analyzer.py --status --session {id}` shows branch state - Board `progress/` channel has agent updates diff --git a/engineering/agenthub/skills/agenthub/references/coordination-strategies.md b/engineering/agenthub/skills/agenthub/references/coordination-strategies.md index c0365566..41d7f42a 100644 --- a/engineering/agenthub/skills/agenthub/references/coordination-strategies.md +++ b/engineering/agenthub/skills/agenthub/references/coordination-strategies.md @@ -30,9 +30,9 @@ Round 2: A2, A4 → Eval → A2 wins **When to use**: Complex optimization where iterative refinement helps. Each round builds on the previous winner. **Implementation**: -1. Run `/hub:init` + `/hub:spawn` for round 1 +1. Run `/hub:hub-init` + `/hub:spawn` for round 1 2. Eval, merge winner into a new base branch -3. Run `/hub:init` again with the merged branch as base +3. Run `/hub:hub-init` again with the merged branch as base 4. Repeat until convergence or budget exhausted ### Ensemble @@ -48,7 +48,7 @@ Agent 3: solves database layer **When to use**: Large tasks that decompose into independent subtasks. Each agent gets a different piece. **Implementation**: -1. In `/hub:init`, give each agent a DIFFERENT task (subtask of the whole) +1. In `/hub:hub-init`, give each agent a DIFFERENT task (subtask of the whole) 2. Spawn with unique dispatch posts per agent 3. Instead of `/hub:eval` ranking, manually cherry-pick from each 4. Or merge sequentially: merge agent-1, then merge agent-2 on top diff --git a/engineering/agenthub/skills/init/SKILL.md b/engineering/agenthub/skills/hub-init/SKILL.md similarity index 84% rename from engineering/agenthub/skills/init/SKILL.md rename to engineering/agenthub/skills/hub-init/SKILL.md index e013e2d6..06a7b6cc 100644 --- a/engineering/agenthub/skills/init/SKILL.md +++ b/engineering/agenthub/skills/hub-init/SKILL.md @@ -1,19 +1,19 @@ --- -name: "init" -description: "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:init or asks to start a multi-agent competition on a task." -command: /hub:init +name: "hub-init" +description: "Create a new AgentHub collaboration session with task, agent count, and evaluation criteria. Use when the user runs /hub:hub-init or asks to start a multi-agent competition on a task." +command: /hub:hub-init --- -# /hub:init — Create New Session +# /hub:hub-init — Create New Session Initialize an AgentHub collaboration session. Creates the `.agenthub/` directory structure, generates a session ID, and configures evaluation criteria. ## Usage ``` -/hub:init # Interactive mode -/hub:init --task "Optimize API" --agents 3 --eval "pytest bench.py" --metric p50_ms --direction lower -/hub:init --task "Refactor auth" --agents 2 # No eval (LLM judge mode) +/hub:hub-init # Interactive mode +/hub:hub-init --task "Optimize API" --agents 3 --eval "pytest bench.py" --metric p50_ms --direction lower +/hub:hub-init --task "Refactor auth" --agents 2 # No eval (LLM judge mode) ``` ## What It Does diff --git a/engineering/agenthub/skills/status/SKILL.md b/engineering/agenthub/skills/hub-status/SKILL.md similarity index 86% rename from engineering/agenthub/skills/status/SKILL.md rename to engineering/agenthub/skills/hub-status/SKILL.md index 17f0ae7e..ab668d2d 100644 --- a/engineering/agenthub/skills/status/SKILL.md +++ b/engineering/agenthub/skills/hub-status/SKILL.md @@ -1,18 +1,18 @@ --- -name: "status" -description: "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:status or asks how the AgentHub agents are doing." -command: /hub:status +name: "hub-status" +description: "Show DAG state, agent progress, and branch status for an AgentHub session. Use when the user runs /hub:hub-status or asks how the AgentHub agents are doing." +command: /hub:hub-status --- -# /hub:status — Session Status +# /hub:hub-status — Session Status Display the current state of an AgentHub session: agent branches, commit counts, frontier status, and board updates. ## Usage ``` -/hub:status # Status for latest session -/hub:status 20260317-143022 # Status for specific session +/hub:hub-status # Status for latest session +/hub:hub-status 20260317-143022 # Status for specific session ``` ## What It Does diff --git a/engineering/agenthub/skills/run/SKILL.md b/engineering/agenthub/skills/run/SKILL.md index 4761879e..ebafb88d 100644 --- a/engineering/agenthub/skills/run/SKILL.md +++ b/engineering/agenthub/skills/run/SKILL.md @@ -41,7 +41,7 @@ Execute these steps sequentially: ### Step 1: Initialize -Run `/hub:init` with the provided arguments: +Run `/hub:hub-init` with the provided arguments: ```bash python {skill_path}/scripts/hub_init.py \ diff --git a/engineering/agenthub/skills/spawn/SKILL.md b/engineering/agenthub/skills/spawn/SKILL.md index 4eb9a5a8..6327f844 100644 --- a/engineering/agenthub/skills/spawn/SKILL.md +++ b/engineering/agenthub/skills/spawn/SKILL.md @@ -79,5 +79,5 @@ python {skill_path}/scripts/session_manager.py --update {session-id} --state run Tell the user: - {N} agents launched in parallel - Each working in an isolated worktree -- Monitor with `/hub:status` +- Monitor with `/hub:hub-status` - Evaluate when done with `/hub:eval` diff --git a/engineering/autoresearch-agent/CLAUDE.md b/engineering/autoresearch-agent/CLAUDE.md index 728d4b49..33ea3d72 100644 --- a/engineering/autoresearch-agent/CLAUDE.md +++ b/engineering/autoresearch-agent/CLAUDE.md @@ -9,8 +9,8 @@ Use the `/ar:` namespace for all commands: - `/ar:setup` — Set up a new experiment interactively - `/ar:run` — Run a single experiment iteration - `/ar:loop` — Start an autonomous loop with user-selected interval -- `/ar:status` — Show dashboard and results -- `/ar:resume` — Resume a paused experiment +- `/ar:ar-status` — Show dashboard and results +- `/ar:ar-resume` — Resume a paused experiment ## How it works @@ -45,13 +45,13 @@ Prompts for interval (10min, 1h, daily, weekly, monthly), then creates a recurri ### Checking progress ``` -/ar:status +/ar:ar-status ``` Shows the dashboard across all experiments with metrics and trends. ### Resuming after context limit or break ``` -/ar:resume engineering/api-speed +/ar:ar-resume engineering/api-speed ``` Reads results history, checks out the branch, and continues where you left off. diff --git a/engineering/autoresearch-agent/agents/experiment-runner.md b/engineering/autoresearch-agent/agents/experiment-runner.md index 120d81eb..92056286 100644 --- a/engineering/autoresearch-agent/agents/experiment-runner.md +++ b/engineering/autoresearch-agent/agents/experiment-runner.md @@ -1,3 +1,8 @@ +--- +name: experiment-runner +description: "Runs one iteration of an autoresearch experiment loop. Reads experiment state from .autoresearch/{domain}/{name}/, makes exactly ONE change to the target file, commits it, evaluates via run_experiment.py, and reports KEEP / DISCARD / CRASH. Spawned per iteration by /ar:run and /ar:loop. Never modifies the evaluator. Not for general refactoring or multi-change edits." +--- + # Experiment Runner Agent You are an autonomous experimenter. Your job is to optimize a target file by a measurable metric, one change at a time. diff --git a/engineering/autoresearch-agent/settings.json b/engineering/autoresearch-agent/settings.json index cb73087d..16c4ff66 100644 --- a/engineering/autoresearch-agent/settings.json +++ b/engineering/autoresearch-agent/settings.json @@ -13,8 +13,8 @@ "setup": "/ar:setup", "run": "/ar:run", "loop": "/ar:loop", - "status": "/ar:status", - "resume": "/ar:resume" + "status": "/ar:ar-status", + "resume": "/ar:ar-resume" }, "agents": [ "experiment-runner" diff --git a/engineering/autoresearch-agent/skills/resume/SKILL.md b/engineering/autoresearch-agent/skills/ar-resume/SKILL.md similarity index 84% rename from engineering/autoresearch-agent/skills/resume/SKILL.md rename to engineering/autoresearch-agent/skills/ar-resume/SKILL.md index 2dd81260..9d282daa 100644 --- a/engineering/autoresearch-agent/skills/resume/SKILL.md +++ b/engineering/autoresearch-agent/skills/ar-resume/SKILL.md @@ -1,18 +1,18 @@ --- -name: "resume" -description: "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:resume or asks to pick up a previously started autoresearch experiment." -command: /ar:resume +name: "ar-resume" +description: "Resume a paused experiment. Checkout the experiment branch, read results history, continue iterating. Use when the user runs /ar:ar-resume or asks to pick up a previously started autoresearch experiment." +command: /ar:ar-resume --- -# /ar:resume — Resume Experiment +# /ar:ar-resume — Resume Experiment Resume a paused or context-limited experiment. Reads all history and continues where you left off. ## Usage ``` -/ar:resume # List experiments, let user pick -/ar:resume engineering/api-speed # Resume specific experiment +/ar:ar-resume # List experiments, let user pick +/ar:ar-resume engineering/api-speed # Resume specific experiment ``` ## What It Does diff --git a/engineering/autoresearch-agent/skills/status/SKILL.md b/engineering/autoresearch-agent/skills/ar-status/SKILL.md similarity index 72% rename from engineering/autoresearch-agent/skills/status/SKILL.md rename to engineering/autoresearch-agent/skills/ar-status/SKILL.md index 173737a8..b3fcfd45 100644 --- a/engineering/autoresearch-agent/skills/status/SKILL.md +++ b/engineering/autoresearch-agent/skills/ar-status/SKILL.md @@ -1,21 +1,21 @@ --- -name: "status" -description: "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:status or asks how an autoresearch experiment is going." -command: /ar:status +name: "ar-status" +description: "Show experiment dashboard with results, active loops, and progress. Use when the user runs /ar:ar-status or asks how an autoresearch experiment is going." +command: /ar:ar-status --- -# /ar:status — Experiment Dashboard +# /ar:ar-status — Experiment Dashboard Show experiment results, active loops, and progress across all experiments. ## Usage ``` -/ar:status # Full dashboard -/ar:status engineering/api-speed # Single experiment detail -/ar:status --domain engineering # All experiments in a domain -/ar:status --format markdown # Export as markdown -/ar:status --format csv --output results.csv # Export as CSV +/ar:ar-status # Full dashboard +/ar:ar-status engineering/api-speed # Single experiment detail +/ar:ar-status --domain engineering # All experiments in a domain +/ar:ar-status --format markdown # Export as markdown +/ar:ar-status --format csv --output results.csv # Export as CSV ``` ## What It Does diff --git a/engineering/autoresearch-agent/skills/autoresearch-agent/SKILL.md b/engineering/autoresearch-agent/skills/autoresearch-agent/SKILL.md index e9efaa1a..6b3c7a17 100644 --- a/engineering/autoresearch-agent/skills/autoresearch-agent/SKILL.md +++ b/engineering/autoresearch-agent/skills/autoresearch-agent/SKILL.md @@ -26,8 +26,8 @@ Not one guess — fifty measured attempts, compounding. | `/ar:setup` | Set up a new experiment interactively | | `/ar:run` | Run a single experiment iteration | | `/ar:loop` | Start autonomous loop with configurable interval (10m, 1h, daily, weekly, monthly) | -| `/ar:status` | Show dashboard and results | -| `/ar:resume` | Resume a paused experiment | +| `/ar:ar-status` | Show dashboard and results | +| `/ar:ar-resume` | Resume a paused experiment | --- diff --git a/engineering/autoresearch-agent/skills/loop/SKILL.md b/engineering/autoresearch-agent/skills/loop/SKILL.md index adbff858..aa5d1136 100644 --- a/engineering/autoresearch-agent/skills/loop/SKILL.md +++ b/engineering/autoresearch-agent/skills/loop/SKILL.md @@ -99,7 +99,7 @@ Loop started for {domain}/{name} Cron ID: {id} Auto-expires: 3 days (CronCreate limit) - To check progress: /ar:status + To check progress: /ar:ar-status To stop the loop: /ar:loop stop {domain}/{name} Note: Recurring jobs auto-expire after 3 days. diff --git a/engineering/book-to-skill/.claude-plugin/authoring-notes.json b/engineering/book-to-skill/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..41270b08 --- /dev/null +++ b/engineering/book-to-skill/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/virgiliojr94/book-to-skill", + "original_author": "virgiliojr94", + "original_license": "MIT", + "derivation_note": "The extraction library (book_to_skill/ — config, exceptions, sanitize, dependencies, utils, and the 7 per-format parsers) is vendored from upstream and carries upstream's multi-format chains, chapter detection across 5 script families, and Unicode/XXE hardening. 25 numbered deviations are recorded in README.md, which is the authoritative list: the workflow was rewritten Claude-Code-first for this repo's conventions, the 3 upstream tools were reworked into 4 argparse CLIs with --help/--sample, install-on-import behaviour was replaced with a report-only default, and Step 11 (plugin emission with a rights gate) plus the validator's budget and index families are additions with no upstream counterpart." + } +} diff --git a/engineering/book-to-skill/.claude-plugin/plugin.json b/engineering/book-to-skill/.claude-plugin/plugin.json index e6f640ad..d1f566e4 100644 --- a/engineering/book-to-skill/.claude-plugin/plugin.json +++ b/engineering/book-to-skill/.claude-plugin/plugin.json @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/book-to-skill" - ], - "attribution": { - "derived_from": "https://github.com/virgiliojr94/book-to-skill", - "original_author": "virgiliojr94", - "original_license": "MIT", - "derivation_note": "The extraction library (book_to_skill/ — config, exceptions, sanitize, dependencies, utils, and the 7 per-format parsers) is vendored from upstream and carries upstream's multi-format chains, chapter detection across 5 script families, and Unicode/XXE hardening. 25 numbered deviations are recorded in README.md, which is the authoritative list: the workflow was rewritten Claude-Code-first for this repo's conventions, the 3 upstream tools were reworked into 4 argparse CLIs with --help/--sample, install-on-import behaviour was replaced with a report-only default, and Step 11 (plugin emission with a rights gate) plus the validator's budget and index families are additions with no upstream counterpart." - } + ] } diff --git a/engineering/boost-asio-pro/SKILL.md b/engineering/boost-asio-pro/SKILL.md new file mode 100644 index 00000000..686bf0cd --- /dev/null +++ b/engineering/boost-asio-pro/SKILL.md @@ -0,0 +1,145 @@ +--- +name: "boost-asio-pro" +description: "Use when writing or reviewing asynchronous C++ networking code with Boost.Asio or standalone Asio — TCP/UDP servers and clients, SSL/TLS, timers, strands, io_context, co_spawn, awaitable, async_read/async_write, asio::spawn, yield_context, or pre-C++20 completion-handler callbacks." +--- + +# Boost.Asio / standalone Asio + +## Overview + +Write async C++ networking code that compiles on the *user's* Boost, not the newest one. Asio's API changed shape three times (classic `io_service` → `io_context` → C++20 coroutines) and most Asio code on the internet is from the first era, so **pick the style from the toolchain first**, then follow that style's reference file. + +**References:** [Boost.Asio](https://www.boost.org/doc/libs/latest/doc/html/boost_asio.html) · [standalone Asio](https://think-async.com/Asio/) + +Use this skill whenever async C++ networking code is being written or reviewed — and especially when the target toolchain is old, where coroutine examples simply will not compile. The three worked implementations it references are CI-verified from Boost 1.62 (2016) through 1.90. + +## Step 1: pick the style (do this before writing code) + +Determine the Boost (or Asio) version and the C++ standard actually in use — `find_package(Boost)` output, `dpkg -l libboost-dev`, `brew info boost`, `CMAKE_CXX_STANDARD`, or ask. Do not assume the newest. + +| Boost | C++ std | Style | Read | +|-------|---------|-------|------| +| ≥ 1.77 | C++20 | Coroutines (`co_await` + `awaitable`) — preferred | [references/coroutines.md](references/coroutines.md) | +| ≥ 1.74 | C++11–17 | Completion handlers (callbacks) — the portable baseline | [references/pre-cpp20.md](references/pre-cpp20.md) | +| ≥ 1.80 | C++11–17 | Stackful `asio::spawn` + `yield_context` (links Boost.Coroutine — not header-only) | [references/pre-cpp20.md](references/pre-cpp20.md) | +| 1.62–1.65 | C++11 | Classic `io_service` / `strand.wrap` / `expires_from_now` | [references/classic-boost.md](references/classic-boost.md) | + +SSL/TLS in any style: [references/ssl.md](references/ssl.md). CMake for any style: [references/build.md](references/build.md). + +`io_context`, `make_strand`, `bind_executor`, `steady_timer`, `signal_set`, `async_read`/`async_write`/`async_read_until`, buffers and `resolver` are **library** features — identical in the coroutine and callback styles. Only the suspension mechanism differs. + +## Step 2: version floors (verified by compiling, not from docs) + +Reach for one of these and the build breaks on older distros: + +| Feature | Floor | +|---------|-------| +| `experimental/awaitable_operators.hpp` (the `\|\|` / `&&` operators) | **Boost ≥ 1.77** / Asio ≥ 1.20 | +| `as_tuple` completion token | **Boost ≥ 1.79** / Asio ≥ 1.21 | +| `co_composed` (custom composed ops) | **Boost ≥ 1.85** / Asio ≥ 1.30 | +| 3-arg `asio::spawn(ex, fn, token)` | **Boost ≥ 1.80** (older Boost has only `spawn(ex, fn)`) | +| `any_io_executor` (`strand`, `tcp::socket`'s default executor) | **Boost ≥ 1.74** — the floor for the callback style; below it, use legacy `io_context::strand` | +| `io_context`, `make_strand`, `expires_after` | **Boost ≥ 1.66** — below it, classic `io_service` | + +Distro floors that bite: **Debian bookworm ships Boost 1.74** (no `awaitable_operators.hpp` — `#include` fails outright), Ubuntu 20.04 ships 1.71 (no `any_io_executor`), Debian 9 ships 1.62. + +Language, not library: the chrono literals `250ms` / `30s` are **C++14**. For a true C++11 build write `std::chrono::milliseconds(250)`. + +## Step 3: the rules that are actually easy to get wrong + +**A strand does not serialize writes.** A strand serializes handler *execution*, not whole composed operations. Two `async_write`s in flight on the same strand still **interleave bytes on the wire**. Full-duplex (a read loop plus concurrent pushes/replies) needs a per-connection strand **and** an outbound queue with an in-flight flag, so at most one `async_write` exists at a time. This is the single most common wrong answer about Asio. + +**Buffers do not own memory.** `asio::buffer()` is a view. Storage must outlive the operation: coroutine locals are fine across `co_await` in the same frame; in callback style the same data must become a **member**, not a local. + +**Connections must outlive their handlers.** `enable_shared_from_this`, and capture `self` in *every* `co_spawn` / handler — read loop, write loop, and each timer. + +**Frame with composed reads.** `async_read` (fills the buffer exactly) for a length prefix and then the body; never `async_read_some`, which returns short. + +**Wrap `as_tuple`.** Always `as_tuple(use_awaitable)`. Bare `as_tuple` resolves against the operation's default token and compiles in some contexts, fails in others. + +**`async_accept(make_strand(...))` changes two things**: it forces an explicit completion token back on the call, and the accepted socket is `basic_stream_socket>`, not `tcp::socket`. Take it **by value** or with `auto` — binding it to `tcp::socket&` will not compile. + +**Re-arming a timer resolves the pending wait with `operation_aborted`.** In an idle-timeout loop that is the signal to keep waiting, not an error. + +**GCC needs `-fcoroutines`** for the C++20 style, and header-only Boost needs `BOOST_ERROR_CODE_HEADER_ONLY` defined in exactly one place (CMake). + +## Anti-Patterns + +| Mistake | Fix | +|---------|-----| +| Buffer dangling (local goes out of scope during async op) | Ensure buffer lifetime ≥ operation lifetime; coroutine locals or members, not callback locals | +| Forgetting `io.run()` | No handlers dispatch without `run()` / `run_one()` | +| Concurrent socket access without strand | Wrap in `strand<>` or serialize via one coroutine chain | +| Assuming a strand prevents interleaved writes | Add a write queue — see Step 3 | +| Using `use_awaitable` where `deferred` suffices | Omit the token (default is `deferred`) unless using `\|\|` / `&&` | +| Ignoring short reads/writes | Use composed `async_read` / `async_write` / `async_read_until`, not `async_read_some` | +| Not setting `reuse_address` on the acceptor | Set before `bind`/`listen` or restarts hit "address in use" | +| SSL operations without a strand | *All* `ssl::stream` ops need strand synchronization | +| Blocking inside a handler | Never block in a completion handler | +| Accepting a socket with the wrong executor type | See `async_accept(make_strand(...))` in Step 3 | +| Requiring the `Boost::system` component | Header-only since 1.74: `Boost::headers` + `BOOST_ERROR_CODE_HEADER_ONLY`. Only classic (pre-1.66) needs the link | +| Missing `-fcoroutines` on GCC | Build fails — add `$<$:-fcoroutines>` | +| Writing coroutine code for a Boost that predates it | Do Step 1 first | + +## Boost.Asio vs standalone Asio + +Same author, same API — namespace and includes differ. + +| Aspect | Boost.Asio | Standalone Asio | +|--------|-----------|-----------------| +| Namespace / include | `boost::asio` / `` | `asio` / `` | +| Error code | `boost::system::error_code` | `asio::error_code` (or `std::error_code`) | +| Install (brew) | `brew install boost` | `brew install asio` | +| CMake | `Boost::headers` | manual include path | +| Version (2025) | 1.87–1.90 (with Boost) | 1.30–1.36 (independent) | +| Macro prefix | `BOOST_ASIO_` | `ASIO_` | + +Support both with a shim, then use `net::` throughout: +```cpp +#ifdef USE_STANDALONE_ASIO + #include + namespace net = asio; + using error_code = asio::error_code; +#else + #include + namespace net = boost::asio; + using error_code = boost::system::error_code; +#endif +namespace ssl = net::ssl; +using tcp = net::ip::tcp; +``` + +## Before you call it done + +Check the code you just wrote against this list: + +- [ ] Style matches the target Boost version and C++ standard (Step 1), and every API used clears its floor (Step 2). +- [ ] Every buffer passed to an async op outlives that op — no callback locals, no dangling `string_view`. +- [ ] At most one `async_write` per socket in flight, enforced by a queue + flag, if anything writes concurrently with reading. +- [ ] Every async chain on a shared object runs on the same strand; `self` captured in every handler and `co_spawn`. +- [ ] Framing / delimited reads use composed `async_read` / `async_read_until`. +- [ ] Errors are handled, not swallowed: `as_tuple(use_awaitable)` destructured, or the callback's `ec` checked, on every op. +- [ ] `operation_aborted` distinguished from real errors wherever a timer is re-armed or an op is cancelled. +- [ ] Acceptor sets `reuse_address`; shutdown path closes the acceptor and drains sessions. +- [ ] CMake has the standard, `-fcoroutines` for GCC (C++20 only), `BOOST_ERROR_CODE_HEADER_ONLY` in one place, and `Boost::coroutine` only if using stackful `spawn`. +- [ ] It compiles. Build it — most of the mistakes above are compile-time, and the version floors are only real once tested. + +## Worked examples + +Three CI-verified implementations of the same full-duplex framed-protocol server, one per style — copy from the one matching Step 1. All three live in the upstream repository and are built by CI on every push. + +- [market-data-feed](https://github.com/alexprivalov/boost-asio-skill/tree/main/examples/market-data-feed) — C++20 coroutines (Boost 1.77+; verified 1.83–1.90) +- [market-data-feed-precpp20](https://github.com/alexprivalov/boost-asio-skill/tree/main/examples/market-data-feed-precpp20) — callbacks, C++11-clean (verified Boost 1.74+, incl. Windows/MSVC) +- [market-data-feed-classic](https://github.com/alexprivalov/boost-asio-skill/tree/main/examples/market-data-feed-classic) — classic `io_service` (verified back to Boost 1.62 / Debian 9) + +## Official documentation + +- Overview: https://www.boost.org/doc/libs/latest/doc/html/boost_asio/overview.html +- Reference: https://www.boost.org/doc/libs/latest/doc/html/boost_asio/reference.html +- Examples: https://www.boost.org/doc/libs/latest/doc/html/boost_asio/examples.html + +## Cross-References + +- `engineering/docker-development` — the old-Boost verification lanes this skill's floors come from are containerised builds (Debian 9 / bookworm, Fedora). +- `engineering/chaos-engineering` — for exercising the failure paths this skill tells you to handle: half-open sockets, idle timeouts, partial frames. +- `engineering-team/playwright-pro` — the client-side counterpart when the server built here is driven from browser-based integration tests. diff --git a/engineering/boost-asio-pro/references/build.md b/engineering/boost-asio-pro/references/build.md new file mode 100644 index 00000000..2b22d26e --- /dev/null +++ b/engineering/boost-asio-pro/references/build.md @@ -0,0 +1,89 @@ +# Build Configuration + + +### Boost.Asio (header-only since Boost 1.74+) + +```cmake +find_package(Boost REQUIRED) +find_package(OpenSSL REQUIRED) # if using SSL +find_package(Threads REQUIRED) + +target_link_libraries(myapp PRIVATE + Boost::headers # header-only Asio + OpenSSL::SSL OpenSSL::Crypto # if using SSL + Threads::Threads +) + +target_compile_features(myapp PRIVATE cxx_std_20) + +# REQUIRED for GCC coroutine support — build will fail without this +target_compile_options(myapp PRIVATE + $<$:-fcoroutines> +) + +# Optional: truly header-only (no Boost.System link needed) +target_compile_definitions(myapp PRIVATE BOOST_ERROR_CODE_HEADER_ONLY) +``` + +### Standalone Asio (always header-only) + +```cmake +# Standalone Asio has no CMake config — use pkg-config or manual path +find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) + +# If installed via brew: +find_path(ASIO_INCLUDE_DIR asio.hpp HINTS /opt/homebrew/include) + +target_include_directories(myapp PRIVATE ${ASIO_INCLUDE_DIR}) +target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +target_compile_features(myapp PRIVATE cxx_std_20) +target_compile_definitions(myapp PRIVATE ASIO_STANDALONE) + +target_compile_options(myapp PRIVATE + $<$:-fcoroutines> +) +``` + +### Dual-mode CMake (supports both) + +```cmake +option(USE_STANDALONE_ASIO "Use standalone Asio instead of Boost.Asio" OFF) + +find_package(OpenSSL REQUIRED) +find_package(Threads REQUIRED) + +if(USE_STANDALONE_ASIO) + find_path(ASIO_INCLUDE_DIR asio.hpp HINTS /opt/homebrew/include) + target_include_directories(myapp PRIVATE ${ASIO_INCLUDE_DIR}) + target_compile_definitions(myapp PRIVATE USE_STANDALONE_ASIO ASIO_STANDALONE) +else() + find_package(Boost REQUIRED) + target_link_libraries(myapp PRIVATE Boost::headers) + target_compile_definitions(myapp PRIVATE BOOST_ERROR_CODE_HEADER_ONLY) +endif() + +target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto Threads::Threads) +target_compile_features(myapp PRIVATE cxx_std_20) +target_compile_options(myapp PRIVATE $<$:-fcoroutines>) +``` + +## Header-Only Usage + +**Boost.Asio:** Asio is header-only by default. The only thing that pulls in a Boost library to link is `boost::system::error_code`'s out-of-line symbols, so for a truly link-free build define **`BOOST_ERROR_CODE_HEADER_ONLY`**. `BOOST_ASIO_HEADER_ONLY` is rarely needed and only relevant if separate compilation was previously enabled; you do **not** normally need both. + +**Define `BOOST_ERROR_CODE_HEADER_ONLY` in exactly ONE place — prefer CMake** (`target_compile_definitions`, as shown above). Defining it in CMake *and* with a source `#define` triggers `-Wmacro-redefined`. So in source, just include — no `#define`: +```cpp +#include +#include +#include +``` + +**Standalone Asio:** +```cpp +#include +#include +#include +// No macros needed — always header-only +``` + diff --git a/engineering/boost-asio-pro/references/classic-boost.md b/engineering/boost-asio-pro/references/classic-boost.md new file mode 100644 index 00000000..ebda934c --- /dev/null +++ b/engineering/boost-asio-pro/references/classic-boost.md @@ -0,0 +1,33 @@ +# Classic Boost (pre-1.66, the `io_service` era — verified to 1.62) + + +To support Boost older than 1.66 (no `io_context`, no `make_strand`, no `any_io_executor`), drop to the classic API — verified building **back to Boost 1.62** (Debian 9) while still compiling on current Boost via a tiny shim: + +| Modern (1.66+) | Classic (pre-1.66) | +|----------------|--------------------| +| `io_context` | `io_service` | +| `make_strand(ex)` / `strand` | `io_service::strand strand(io)` | +| `bind_executor(strand, h)` | `strand.wrap(h)` | +| `timer.expires_after(d)` | `timer.expires_from_now(d)` | +| move-return `async_accept()` | `async_accept(socket_, handler)` | +| header-only `error_code` | link **Boost.System** (`find_package(Boost COMPONENTS system)`) | + +Only the `io_service`/`io_context` name and the `expires_after`/`expires_from_now` call actually differ across 1.62…1.90 — isolate both behind `#if BOOST_VERSION >= 106600`: +```cpp +#include +#include // not pulled in by on old Boost +#if BOOST_VERSION >= 106600 + using io_service_t = boost::asio::io_context; +#else + using io_service_t = boost::asio::io_service; +#endif +template +void timer_expires_in(T& t, std::chrono::duration d) { +#if BOOST_VERSION >= 106600 + t.expires_after(d); +#else + t.expires_from_now(d); +#endif +} +``` +CMake for this range: `cmake_minimum_required(VERSION 3.5)` (Debian 9 ships cmake 3.7), link `Boost::system` only if the component is found (modern Boost is header-only and has no such component), and use the classic out-of-source build (`mkdir build && cd build && cmake ..`) since `-S`/`-B` need cmake ≥ 3.13. diff --git a/engineering/boost-asio-pro/references/coroutines.md b/engineering/boost-asio-pro/references/coroutines.md new file mode 100644 index 00000000..7e54714b --- /dev/null +++ b/engineering/boost-asio-pro/references/coroutines.md @@ -0,0 +1,412 @@ +# C++20 Coroutine Style (Boost ≥ 1.77) + +The preferred style when the toolchain allows it. Read `SKILL.md` first — the rules there (write queue, buffer lifetime, version floors) apply here and are not repeated. + +## Core Architecture + +Boost.Asio uses the **Proactor pattern**: async operations run in the background, completion handlers are invoked with results. + +``` +Program → I/O Object → Execution Context → OS → (completion) → Handler +``` + +**Execution contexts:** `io_context` (single/multi-thread event loop), `thread_pool`, `system_context` + +**I/O objects:** `tcp::socket`, `tcp::acceptor`, `udp::socket`, `steady_timer`, `ssl::stream<>` + +**Completion tokens:** Control how async results are delivered — `use_awaitable`, `deferred` (default), `detached`, callbacks, futures. + +## C++20 Coroutines (Preferred Style) + +```cpp +#include +#include +#include + +namespace asio = boost::asio; +using tcp = asio::ip::tcp; + +asio::awaitable echo_session(tcp::socket socket) { + try { + char data[1024]; + for (;;) { + std::size_t n = co_await socket.async_read_some(asio::buffer(data)); + co_await async_write(socket, asio::buffer(data, n)); + } + } catch (std::exception&) { + // Connection closed or error — coroutine ends + } +} + +asio::awaitable listener(tcp::acceptor acceptor) { + for (;;) { + auto socket = co_await acceptor.async_accept(); + co_spawn(acceptor.get_executor(), echo_session(std::move(socket)), asio::detached); + } +} + +int main() { + asio::io_context io(1); // concurrency_hint=1 for single-threaded + tcp::acceptor acceptor(io, {tcp::v4(), 8080}); + co_spawn(io, listener(std::move(acceptor)), asio::detached); + io.run(); +} +``` + +**Key rules:** +- `co_spawn(executor, coroutine, completion_token)` launches a coroutine +- Without explicit token, async ops use `deferred` (returns awaitable object for `co_await`) +- Errors become `system_error` exceptions by default inside coroutines +- Use `asio::detached` when you don't need the coroutine's result + +## Error Handling in Coroutines + +**Default:** Errors throw `boost::system::system_error`. + +**Explicit error handling with `as_tuple`:** +```cpp +auto [ec, n] = co_await socket.async_read_some( + asio::buffer(data), asio::as_tuple(asio::use_awaitable)); +if (ec) { /* handle error, no exception */ } +``` +**Wrap, don't use bare `as_tuple`.** Always write `as_tuple(use_awaitable)`. Bare `asio::as_tuple` resolves against the operation's *default* completion token (often `deferred`), which compiles in some contexts but fails in others — wrapping an explicit base token is unambiguous everywhere. + +**With `redirect_error`:** +```cpp +boost::system::error_code ec; +std::size_t n = co_await socket.async_read_some( + asio::buffer(data), asio::redirect_error(ec)); +``` + +## Strands (Thread Safety) + +**Rule: All async operations on a shared object MUST execute on the same strand.** + +```cpp +// Per-connection strand +asio::strand strand(io.get_executor()); +co_spawn(strand, session(std::move(socket)), asio::detached); + +// Bind handler to strand +socket.async_read_some(asio::buffer(data), + asio::bind_executor(strand, [](error_code ec, size_t n) { /*...*/ })); +``` + +**Implicit strands (no explicit strand needed):** +- Single-threaded `io_context::run()` — all handlers are sequential +- Single chain of async ops on one connection (half-duplex) + +**Explicit strand required when:** +- Multiple threads call `io_context::run()` +- Full-duplex read+write on same socket +- Shared state accessed from multiple async chains + +## Full-Duplex: Strand + Write Queue + +**A strand serializes handler *execution*, NOT whole composed operations.** Two `async_write`s started "concurrently" on the same strand still overlap and **interleave bytes on the wire** — the strand only orders the intermediate handlers, not the byte stream. For full-duplex (a read loop plus pushes/replies writing at the same time on one socket), a strand alone is **not** enough: you must serialize outbound writes yourself with a queue. + +```cpp +// Give each accepted socket its OWN strand, then run every chain (read loop, +// pushes, replies) on that strand. Passing an executor to async_accept means you +// must ALSO pass an explicit completion token — the default-deferred shortcut on +// the zero-arg form no longer applies. +auto socket = co_await acceptor.async_accept(asio::make_strand(io), asio::use_awaitable); +std::make_shared(std::move(socket))->start(); + +class connection : public std::enable_shared_from_this { + tcp::socket socket_; // bound to its own strand + std::deque outbox_; + bool writing_ = false; +public: + explicit connection(tcp::socket s) : socket_(std::move(s)) {} + + void start() { + // Each chain captures `self` so the connection outlives all its coroutines. + co_spawn(socket_.get_executor(), + [self = shared_from_this()] { return self->read_loop(); }, asio::detached); + } + + // Call ONLY from the connection's strand (e.g. from its own coroutines). + // From another thread/strand: asio::dispatch(socket_.get_executor(), ...). + void send(std::string frame) { + outbox_.push_back(std::move(frame)); + if (!writing_) + co_spawn(socket_.get_executor(), + [self = shared_from_this()] { return self->write_loop(); }, asio::detached); + } +private: + asio::awaitable write_loop() { + writing_ = true; + while (!outbox_.empty()) { + co_await async_write(socket_, asio::buffer(outbox_.front())); + outbox_.pop_front(); // pop only AFTER the write completes + } + writing_ = false; + } + asio::awaitable read_loop(); // reads frames, calls send() for replies +}; +``` + +**Why each rule matters:** +- One strand per connection → read loop and write loop never run their handlers concurrently. +- Write queue + `writing_` flag → at most one `async_write` in flight, so frames never interleave. +- `enable_shared_from_this` + capturing `self` in every `co_spawn` → the connection survives until all of its read/write/timer chains finish. +- The accepted socket from `async_accept(make_strand(...))` is `basic_stream_socket>`, **not** `tcp::socket`. Take it **by value** (`connection(tcp::socket s)`, store `tcp::socket socket_`) — the strand executor type-erases into `any_io_executor` on the move. Passing that accepted socket to a `tcp::socket&` (by reference) instead will **fail to compile** — use `auto` or accept by value. + +**Strand from inside a coroutine** (when `io` isn't a captured local): get the executor from the coroutine and make a strand off it — no `io_context&` needed: +```cpp +auto ex = co_await asio::this_coro::executor; +auto socket = co_await acceptor.async_accept(asio::make_strand(ex), asio::use_awaitable); +``` + +**Run the read loop and idle watch together** — two `awaitable` branches; don't inspect the result, the first to finish unwinds the other: +```cpp +using namespace asio::experimental::awaitable_operators; +co_await (read_loop() || idle_watch(socket_, timer_)); // either returning tears down the connection +``` + +**Stopping a detached side-coroutine** (e.g. a per-symbol ticker that must end on unsubscribe/close): a detached `co_spawn` won't stop itself. Either (a) have its loop re-check a flag each iteration and `co_return` when gone: +```cpp +while (subscriptions_.contains(symbol) && socket_.is_open()) { + timer.expires_after(250ms); + co_await timer.async_wait(asio::as_tuple(asio::use_awaitable)); + if (/* still subscribed */) send(make_tick(symbol)); +} +``` +or (b) spawn it with a `cancellation_signal` and `emit()` cancellation on unsubscribe. The flag approach is simpler for per-subscription tickers. + +## Timers and Timeouts + +```cpp +asio::awaitable with_timeout(tcp::socket& socket) { + asio::steady_timer timer(co_await asio::this_coro::executor); + timer.expires_after(std::chrono::seconds(30)); + + // Race: read vs timeout (requires awaitable_operators) + using namespace asio::experimental::awaitable_operators; + + auto result = co_await ( + socket.async_read_some(asio::buffer(data), asio::use_awaitable) + || timer.async_wait(asio::use_awaitable) + ); + + if (result.index() == 0) { /* read completed */ } + else { /* timeout — cancel the socket */ socket.close(); } +} +``` + +**Re-armable idle timeout** (reset on every received frame — the common server pattern): +```cpp +// Run as a long-lived parallel branch. Calling expires_after() again cancels the +// pending wait, resolving the in-flight async_wait with operation_aborted — that +// is the signal to keep waiting, NOT an error. Genuine expiry resolves with no error. +asio::awaitable idle_watch(tcp::socket& sock, asio::steady_timer& timer) { + for (;;) { + auto [ec] = co_await timer.async_wait(asio::as_tuple(asio::use_awaitable)); + if (ec == asio::error::operation_aborted) continue; // re-armed → keep waiting + if (ec) co_return; // timer error + sock.close(); // real timeout fired + co_return; + } +} +// On every frame received from the peer: timer.expires_after(30s); +``` + +**Parallel operations (`&&` and `||`):** +```cpp +#include +using namespace asio::experimental::awaitable_operators; + +// Wait for both (AND) — cancels other on failure +auto [read_n, write_n] = co_await ( + async_read(sock, in_buf, use_awaitable) && + async_write(sock, out_buf, use_awaitable) +); + +// Wait for first (OR) — cancels other on success +auto result = co_await ( + async_read(sock, buf, use_awaitable) || + timer.async_wait(use_awaitable) +); +``` + +**Note:** `||` and `&&` operators require explicit `use_awaitable` token, and the `awaitable_operators.hpp` header (Boost ≥ 1.77 — see the version floors in SKILL.md). + +**Void branches:** when a branch returns `void` (e.g. two `awaitable` chains), that arm contributes `std::monostate` to the result variant. If *both* branches are void the result is `variant` — don't inspect `.index()`; just `co_await` the expression and let whichever finishes first unwind the other. + +## Cancellation + +```cpp +asio::awaitable cancellable_work() { + // Check cancellation state + auto cs = co_await asio::this_coro::cancellation_state; + if (cs.cancelled() != asio::cancellation_type::none) { + co_return; + } + + // Enable cancellation types + co_await asio::this_coro::reset_cancellation_state( + asio::enable_total_cancellation()); +} +``` + +## TCP Server Pattern + +```cpp +asio::awaitable server(asio::io_context& io, unsigned short port) { + tcp::acceptor acceptor(io, {tcp::v4(), port}); + acceptor.set_option(tcp::acceptor::reuse_address(true)); + + for (;;) { + auto socket = co_await acceptor.async_accept(); + co_spawn( + io.get_executor(), // or a strand for multi-threaded + handle_client(std::move(socket)), + [](std::exception_ptr ep) { + if (ep) std::rethrow_exception(ep); + } + ); + } +} +``` + +## Buffers + +| Type | Use | +|------|-----| +| `asio::buffer(data, size)` | Wrap existing memory (no ownership) | +| `asio::dynamic_buffer(vec)` | Growable buffer over `vector`/`string` | +| `asio::streambuf` | Legacy stream buffer | +| `asio::const_buffer` | Read-only view | +| `asio::mutable_buffer` | Writable view | + +**Critical:** `asio::buffer()` does NOT own memory. The underlying storage must outlive the async operation. + +## Resolver (DNS) + +```cpp +asio::awaitable connect_to(asio::io_context& io, + std::string host, std::string port) { + tcp::resolver resolver(io); + auto endpoints = co_await resolver.async_resolve(host, port); + + tcp::socket socket(io); + co_await asio::async_connect(socket, endpoints); + // socket is now connected +} +``` + +## Multi-Threaded io_context + +```cpp +asio::io_context io; +std::vector threads; + +for (int i = 0; i < std::thread::hardware_concurrency(); ++i) { + threads.emplace_back([&io] { io.run(); }); +} + +// All handlers MUST be strand-protected when sharing state +for (auto& t : threads) t.join(); +``` + +## Composed Async Operations (Custom) + +```cpp +template +auto async_echo(tcp::socket& socket, CompletionToken&& token) { + return asio::async_initiate( + asio::co_composed( + [](auto state, tcp::socket& socket) -> void { + state.throw_if_cancelled(true); + state.reset_cancellation_state(asio::enable_terminal_cancellation()); + try { + char data[1024]; + for (;;) { + std::size_t n = co_await socket.async_read_some(asio::buffer(data)); + co_await async_write(socket, asio::buffer(data, n)); + } + } catch (const boost::system::system_error& e) { + co_return {e.code()}; + } + }, socket), + token, std::ref(socket)); +} +``` + +## Line-Based Protocols + +For newline-delimited protocols, prefer `async_read_until` over manual `async_read_some` + buffer parsing: + +```cpp +asio::awaitable line_echo(tcp::socket socket) { + asio::streambuf buf; + for (;;) { + std::size_t n = co_await asio::async_read_until(socket, buf, '\n'); + std::string line(asio::buffers_begin(buf.data()), + asio::buffers_begin(buf.data()) + n); + buf.consume(n); + co_await async_write(socket, asio::buffer(line)); + } +} +``` + +Or with `dynamic_buffer` over a `std::string`: +```cpp +std::string buf; +std::size_t n = co_await asio::async_read_until(socket, asio::dynamic_buffer(buf), '\n'); +std::string line = buf.substr(0, n); +buf.erase(0, n); +``` + +## Length-Prefixed Binary Framing + +For binary protocols, read the fixed-size header fully, then the body fully — two sequential **composed** reads (`async_read` fills the whole buffer, handling short reads). Do NOT use `async_read_some` for framing. + +```cpp +// Frame: [4-byte big-endian length N][N-byte body] +asio::awaitable read_frame(tcp::socket& sock) { + uint32_t len_be = 0; + co_await async_read(sock, asio::buffer(&len_be, sizeof len_be)); // exactly 4 bytes + uint32_t n = ntohl(len_be); // ; or hand-roll endian swap + std::string body(n, '\0'); + co_await async_read(sock, asio::buffer(body)); // exactly n bytes + co_return body; +} + +asio::awaitable write_frame(tcp::socket& sock, std::string_view body) { + uint32_t len_be = htonl(static_cast(body.size())); + std::array bufs{ + asio::buffer(&len_be, sizeof len_be), asio::buffer(body)}; + co_await async_write(sock, bufs); // gather-write header + body atomically + // len_be and body must outlive the write — they do here (co_await suspends in-frame). +} +``` + +## Graceful Shutdown (signal_set) + +```cpp +asio::signal_set signals(io, SIGINT, SIGTERM); +signals.async_wait([&](const boost::system::error_code&, int /*signo*/) { + acceptor.close(); // stop accepting; let in-flight sessions drain, then io.run() returns + // or, for an immediate stop: io.stop(); +}); +``` + +For coroutine-style shutdown, `co_await signals.async_wait()` in a dedicated coroutine instead of a callback. + +## Quick Reference + +| Operation | Function | +|-----------|----------| +| Launch coroutine | `co_spawn(executor, coro, token)` | +| Accept connection | `co_await acceptor.async_accept()` | +| Read some bytes | `co_await socket.async_read_some(buffer)` | +| Read exact/until | `co_await async_read(stream, buf)` / `async_read_until(stream, buf, delim)` | +| Write all | `co_await async_write(stream, buffer)` | +| Connect | `co_await async_connect(socket, endpoints)` | +| Resolve DNS | `co_await resolver.async_resolve(host, port)` | +| Wait timer | `co_await timer.async_wait()` | +| TLS handshake | `co_await stream.async_handshake(type)` | +| Get executor | `co_await asio::this_coro::executor` | + diff --git a/engineering/boost-asio-pro/references/pre-cpp20.md b/engineering/boost-asio-pro/references/pre-cpp20.md new file mode 100644 index 00000000..e98648ae --- /dev/null +++ b/engineering/boost-asio-pro/references/pre-cpp20.md @@ -0,0 +1,164 @@ +# Pre-C++20 Styles (C++11–17, Boost ≥ 1.74) + + +If you can't use C++20 `co_await`, the **same Asio library** (modern Boost or standalone) still works — only the *async style* changes. Compile with C++11 or later. Two pre-C++20 styles: + +1. **Completion handlers (callbacks)** — header-only, C++11, no extra dependencies. The recommended baseline. +2. **Stackful coroutines** (`asio::spawn` + `yield_context`) — synchronous-looking like `co_await`, but built on Boost.Coroutine/Boost.Context, so it **must be linked** (not header-only) — see build note below. + +**Unchanged from the coroutine style** (these are library, not language, features): `io_context`, `make_strand`, `bind_executor`, `steady_timer`, `ssl::stream`, `signal_set`, `async_read`/`async_write`/`async_read_until`, buffers, `resolver`. Use them exactly as shown in [coroutines.md](coroutines.md). + +**Not available pre-C++20:** `co_await`/`awaitable`, `co_spawn`, `use_awaitable`, the `||`/`&&` `awaitable_operators`, `as_tuple`, and `co_composed`. The table below gives the equivalent. + +### C++20 → pre-C++20 mapping + +| C++20 coroutine | Pre-C++20 equivalent | +|-----------------|----------------------| +| `co_await op(use_awaitable)` | callback: `op(handler)` · stackful: `op(yield)` | +| `awaitable` function | member `do_x()` callback chain · or `spawn(strand, fn)` | +| `co_spawn(ex, coro, tok)` | start the callback chain · or `asio::spawn(ex, fn, tok)` | +| `as_tuple(use_awaitable)` → `[ec,n]` | callback's `(ec, n)` params · stackful: `op(yield[ec])` | +| `a() \|\| b()` (first-wins race) | a **watchdog timer** that closes the socket; the other op fails with `operation_aborted` | +| `a() && b()` (wait both) | launch both, count completions in a shared `shared_ptr` | +| `co_composed<>` custom op | `asio::async_compose<>` (C++11) | +| `co_await this_coro::executor` | `socket_.get_executor()` / a passed-in executor | + +### Callback style: full-duplex + write queue + +The full-duplex write-queue rule is identical — a strand alone doesn't stop interleaved writes — just expressed with chained handlers. Capture `self = shared_from_this()` in **every** handler to keep the connection alive. + +```cpp +class connection : public std::enable_shared_from_this { + tcp::socket socket_; + asio::strand strand_; // tcp::socket's executor is any_io_executor + std::deque outbox_; + bool writing_ = false; + char buf_[1024]; +public: + explicit connection(tcp::socket s) + : socket_(std::move(s)), strand_(asio::make_strand(socket_.get_executor())) {} + void start() { do_read(); } + + void send(std::string frame) { // call on the strand only + outbox_.push_back(std::move(frame)); + if (!writing_) do_write(); + } +private: + void do_read() { + auto self = shared_from_this(); + socket_.async_read_some(asio::buffer(buf_), + asio::bind_executor(strand_, // serialize handler execution + [this, self](boost::system::error_code ec, std::size_t n) { + if (ec) return; // self drops here → socket closes + /* parse buf_[0..n]; call send() for replies */ + do_read(); + })); + } + void do_write() { // at most one async_write in flight + writing_ = true; + auto self = shared_from_this(); + asio::async_write(socket_, asio::buffer(outbox_.front()), + asio::bind_executor(strand_, + [this, self](boost::system::error_code ec, std::size_t) { + if (ec) { writing_ = false; return; } + outbox_.pop_front(); + if (!outbox_.empty()) do_write(); + else writing_ = false; + })); + } +}; +``` + +### Stackful style: spawn + yield_context + +`yield` is a completion token: `op(socket, ..., yield)` suspends until done and returns the result; errors **throw** by default, or use `yield[ec]` for an `error_code`. Run each chain on a per-connection strand. + +```cpp +asio::spawn(strand, // executor or strand + [self](asio::yield_context yield) { // capture self for lifetime + try { + char data[1024]; + for (;;) { + std::size_t n = self->socket_.async_read_some(asio::buffer(data), yield); + asio::async_write(self->socket_, asio::buffer(data, n), yield); + } + } catch (const std::exception&) { self->socket_.close(); } + }, + asio::detached); // completion token (3rd arg) +``` + +### Timeout without `||` (watchdog timer) + +Replace the `read || timer` race with a separate watchdog: reset the timer on each read; a second chain waits on it and closes the socket on expiry, which makes the read fail with `operation_aborted`. + +```cpp +// callback watchdog +void arm_timeout() { + timer_.expires_after(std::chrono::seconds(30)); + auto self = shared_from_this(); + timer_.async_wait(asio::bind_executor(strand_, + [this, self](boost::system::error_code ec) { + if (!ec) socket_.close(); // fired → drop; reset cancels with ec + })); +} +// call arm_timeout() again on every frame received to re-arm +``` + +### Callback multi-step reads + recurring side-tasks + +**Lifetime shift:** coroutine *stack locals* become *member variables* in callback style — a header/body buffer must outlive each async op or it dangles. Chain a composed read of the length, then the body: + +```cpp +// members, NOT locals — they must survive until the handler runs +uint32_t len_be_; +std::string body_; + +void read_frame() { + auto self = shared_from_this(); + asio::async_read(socket_, asio::buffer(&len_be_, sizeof len_be_), + asio::bind_executor(strand_, [this, self](boost::system::error_code ec, std::size_t) { + if (ec) return; + body_.assign(ntohl(len_be_), '\0'); + asio::async_read(socket_, asio::buffer(body_), // read exactly N bytes + asio::bind_executor(strand_, [this, self](boost::system::error_code ec2, std::size_t) { + if (ec2) return; + handle_frame(body_); // dispatch on type byte + read_frame(); // next frame + })); + })); +} +``` + +**Recurring side-task** (e.g. push every 250ms) running concurrently with the read loop — there is no detached coroutine to stop, so use a self-rescheduling timer and `cancel()` it to stop: + +```cpp +void schedule_tick(std::string symbol, std::shared_ptr t) { + t->expires_after(std::chrono::milliseconds(250)); + auto self = shared_from_this(); + t->async_wait(asio::bind_executor(strand_, + [this, self, symbol, t](boost::system::error_code ec) { + if (ec) return; // cancelled on unsubscribe/close → stops + send(make_tick(symbol)); // enqueue on the write queue + schedule_tick(symbol, t); // reschedule itself + })); +} +// start: keep one timer per subscription alive (e.g. in a map); stop: erase + t->cancel() +``` + +### Build difference (stackful spawn only) + +Callbacks need no change beyond the standard (drop `-fcoroutines`; it's only for C++20 `co_await`): +```cmake +set(CMAKE_CXX_STANDARD 11) # or 14 / 17 +set(CMAKE_CXX_EXTENSIONS OFF) # else CMake emits -std=gnu++NN, not literal -std=c++NN +target_link_libraries(app PRIVATE Boost::headers Threads::Threads) +target_compile_definitions(app PRIVATE BOOST_ERROR_CODE_HEADER_ONLY) +``` +Stackful `spawn` additionally requires Boost.Coroutine (which uses Boost.Context) — **not header-only**: +```cmake +find_package(Boost REQUIRED COMPONENTS coroutine) +target_link_libraries(app PRIVATE Boost::coroutine) # pulls in Boost.Context +``` +> Standalone Asio's `spawn` also depends on Boost.Coroutine/Context — it drags Boost into an otherwise Boost-free build. If you want zero Boost, use the **callback** style. +> +> The 3-arg `spawn(ex, fn, token)` form needs **Boost ≥ 1.80** (older Boost has only `spawn(ex, fn)`). On old distros like Debian bookworm (Boost 1.74), the **callback** style compiles cleanly while stackful `spawn` does not — verified. diff --git a/engineering/boost-asio-pro/references/ssl.md b/engineering/boost-asio-pro/references/ssl.md new file mode 100644 index 00000000..34919a66 --- /dev/null +++ b/engineering/boost-asio-pro/references/ssl.md @@ -0,0 +1,39 @@ +# SSL/TLS + +Applies to every style — `ssl::stream<>` is a library feature, not a language one. + + +```cpp +#include +#include + +namespace asio = boost::asio; +namespace ssl = asio::ssl; +using tcp = asio::ip::tcp; + +asio::awaitable tls_client(asio::io_context& io) { + ssl::context ctx(ssl::context::tlsv13_client); + ctx.set_default_verify_paths(); + + ssl::stream stream(io, ctx); + + // Connect underlying TCP socket + auto& sock = stream.lowest_layer(); + co_await sock.async_connect(endpoint); + + // Set SNI hostname (required for most servers) + SSL_set_tlsext_host_name(stream.native_handle(), "example.com"); + stream.set_verify_mode(ssl::verify_peer); + stream.set_verify_callback(ssl::host_name_verification("example.com")); + + // TLS handshake + co_await stream.async_handshake(ssl::stream_base::client); + + // Read/write as normal stream + co_await async_write(stream, asio::buffer(request)); + co_await async_read_until(stream, response_buf, "\r\n"); +} +``` + +**Critical:** SSL streams require strand-based synchronization for all async operations — no concurrent reads/writes without a strand. + diff --git a/engineering/caveman/.claude-plugin/authoring-notes.json b/engineering/caveman/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..49da64df --- /dev/null +++ b/engineering/caveman/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/caveman", + "original_author": "Matt Pocock (@mattpocock)", + "original_license": "MIT", + "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib compression + lint tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's voice and persistence rules preserved verbatim." + } +} diff --git a/engineering/caveman/.claude-plugin/plugin.json b/engineering/caveman/.claude-plugin/plugin.json index f1f66211..788a5bdc 100644 --- a/engineering/caveman/.claude-plugin/plugin.json +++ b/engineering/caveman/.claude-plugin/plugin.json @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/caveman" - ], - "attribution": { - "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/caveman", - "original_author": "Matt Pocock (@mattpocock)", - "original_license": "MIT", - "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib compression + lint tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's voice and persistence rules preserved verbatim." - } + ] } diff --git a/engineering/collab-proof/.claude-plugin/authoring-notes.json b/engineering/collab-proof/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..bc74a10c --- /dev/null +++ b/engineering/collab-proof/.claude-plugin/authoring-notes.json @@ -0,0 +1,7 @@ +{ + "attribution": { + "source_repo": "https://github.com/dong7812/collab-proof", + "author": "dong7812", + "license": "MIT" + } +} diff --git a/engineering/collab-proof/.claude-plugin/plugin.json b/engineering/collab-proof/.claude-plugin/plugin.json index 22dcdc45..ef4eaa0b 100644 --- a/engineering/collab-proof/.claude-plugin/plugin.json +++ b/engineering/collab-proof/.claude-plugin/plugin.json @@ -9,11 +9,6 @@ "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/engineering/collab-proof", "repository": "https://github.com/alirezarezvani/claude-skills", "license": "MIT", - "attribution": { - "source_repo": "https://github.com/dong7812/collab-proof", - "author": "dong7812", - "license": "MIT" - }, "skills": [ "./skills/collab-proof" ] diff --git a/engineering/grill-me/.claude-plugin/authoring-notes.json b/engineering/grill-me/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..c14f23e2 --- /dev/null +++ b/engineering/grill-me/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/grill-me", + "original_author": "Matt Pocock (@mattpocock)", + "original_license": "MIT", + "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib decision-tree + question + session tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's relentless one-at-a-time interview discipline preserved verbatim." + } +} diff --git a/engineering/grill-me/.claude-plugin/plugin.json b/engineering/grill-me/.claude-plugin/plugin.json index 64a79128..8f32193c 100644 --- a/engineering/grill-me/.claude-plugin/plugin.json +++ b/engineering/grill-me/.claude-plugin/plugin.json @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/grill-me" - ], - "attribution": { - "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/grill-me", - "original_author": "Matt Pocock (@mattpocock)", - "original_license": "MIT", - "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib decision-tree + question + session tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's relentless one-at-a-time interview discipline preserved verbatim." - } + ] } diff --git a/engineering/grill-with-docs/.claude-plugin/authoring-notes.json b/engineering/grill-with-docs/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..98d60709 --- /dev/null +++ b/engineering/grill-with-docs/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/engineering/grill-with-docs", + "original_author": "Matt Pocock (@mattpocock)", + "original_license": "MIT", + "derivation_note": "Matt's SKILL.md content (with embedded references to ADR-FORMAT.md and CONTEXT-FORMAT.md) reproduced under MIT. Additions: 3 stdlib validators (CONTEXT.md linter, ADR scanner, glossary-code consistency), 3 deep references citing 7+ authoritative sources each, cs-grill-with-docs persona agent, /cs:grill-with-docs slash command. Matt's interview discipline + 3-criteria ADR gate preserved verbatim." + } +} diff --git a/engineering/grill-with-docs/.claude-plugin/plugin.json b/engineering/grill-with-docs/.claude-plugin/plugin.json index 76be96d2..ba7f9f3b 100644 --- a/engineering/grill-with-docs/.claude-plugin/plugin.json +++ b/engineering/grill-with-docs/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "grill-with-docs", - "description": "Docs-anchored grilling session \u2014 interrogates a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), updating those files inline as terminology and decisions crystallise. Derived from Matt Pocock's MIT-licensed grill-with-docs skill (https://github.com/mattpocock/skills) with: (1) 3 stdlib Python tools (CONTEXT.md linter, ADR scanner, glossary-to-code consistency check), (2) 3 reference docs each citing 7+ authoritative sources on ubiquitous language, ADR practice, and CONTEXT.md as a living artifact, (3) cs-grill-with-docs persona agent + /cs:grill-with-docs slash command. Matt's interview discipline + domain-awareness rules + ADR-when-3-criteria-are-met gate preserved verbatim per MIT.", + "description": "Docs-anchored grilling session — interrogates a plan against the project's existing language (CONTEXT.md) and recorded decisions (docs/adr/), updating those files inline as terminology and decisions crystallise. Derived from Matt Pocock's MIT-licensed grill-with-docs skill (https://github.com/mattpocock/skills) with: (1) 3 stdlib Python tools (CONTEXT.md linter, ADR scanner, glossary-to-code consistency check), (2) 3 reference docs each citing 7+ authoritative sources on ubiquitous language, ADR practice, and CONTEXT.md as a living artifact, (3) cs-grill-with-docs persona agent + /cs:grill-with-docs slash command. Matt's interview discipline + domain-awareness rules + ADR-when-3-criteria-are-met gate preserved verbatim per MIT.", "version": "2.9.0", "author": { "name": "Alireza Rezvani", @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/grill-with-docs" - ], - "attribution": { - "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/engineering/grill-with-docs", - "original_author": "Matt Pocock (@mattpocock)", - "original_license": "MIT", - "derivation_note": "Matt's SKILL.md content (with embedded references to ADR-FORMAT.md and CONTEXT-FORMAT.md) reproduced under MIT. Additions: 3 stdlib validators (CONTEXT.md linter, ADR scanner, glossary-code consistency), 3 deep references citing 7+ authoritative sources each, cs-grill-with-docs persona agent, /cs:grill-with-docs slash command. Matt's interview discipline + 3-criteria ADR gate preserved verbatim." - } + ] } diff --git a/engineering/handoff/.claude-plugin/authoring-notes.json b/engineering/handoff/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..11198941 --- /dev/null +++ b/engineering/handoff/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/handoff", + "original_author": "Matt Pocock (@mattpocock)", + "original_license": "MIT", + "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib template + dedup + recommender tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's no-duplication-of-artifacts discipline preserved verbatim." + } +} diff --git a/engineering/handoff/.claude-plugin/plugin.json b/engineering/handoff/.claude-plugin/plugin.json index 7536e7ab..c85ae636 100644 --- a/engineering/handoff/.claude-plugin/plugin.json +++ b/engineering/handoff/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "handoff", - "description": "Conversation-handoff document generator. Compacts the current conversation into a markdown handoff so a fresh agent can continue. References existing artifacts (PRDs, plans, ADRs, issues, commits) by path/URL \u2014 does not duplicate them. Enhanced from Matt Pocock's MIT-licensed handoff skill (https://github.com/mattpocock/skills) with: (1) stdlib Python tools (template generator, artifact deduplicator, skill recommender), (2) 3 reference docs citing 5+ authoritative sources each (handoff structure, deduplication discipline, next-session skill matching), (3) cs-handoff-author persona agent + /cs:handoff slash command. Matt's no-duplication discipline preserved verbatim per MIT. Use when user wants to hand off the current conversation to a fresh agent or starts a new session that picks up prior work.", + "description": "Conversation-handoff document generator. Compacts the current conversation into a markdown handoff so a fresh agent can continue. References existing artifacts (PRDs, plans, ADRs, issues, commits) by path/URL — does not duplicate them. Enhanced from Matt Pocock's MIT-licensed handoff skill (https://github.com/mattpocock/skills) with: (1) stdlib Python tools (template generator, artifact deduplicator, skill recommender), (2) 3 reference docs citing 5+ authoritative sources each (handoff structure, deduplication discipline, next-session skill matching), (3) cs-handoff-author persona agent + /cs:handoff slash command. Matt's no-duplication discipline preserved verbatim per MIT. Use when user wants to hand off the current conversation to a fresh agent or starts a new session that picks up prior work.", "version": "2.9.0", "author": { "name": "Alireza Rezvani", @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/handoff" - ], - "attribution": { - "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/handoff", - "original_author": "Matt Pocock (@mattpocock)", - "original_license": "MIT", - "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib template + dedup + recommender tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's no-duplication-of-artifacts discipline preserved verbatim." - } + ] } diff --git a/engineering/human-gate/.claude-plugin/authoring-notes.json b/engineering/human-gate/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..d46bca23 --- /dev/null +++ b/engineering/human-gate/.claude-plugin/authoring-notes.json @@ -0,0 +1,12 @@ +{ + "source": { + "build_pattern": "Conceptual derivation, not a code vendor -- the batched-review pattern from petergyang/human-review rebuilt as three stdlib-only Python tools (review page builder, sidecar parser, gate state machine) under this repo's no-dependency conventions, with a closing gate and loop discipline upstream does not have. Audit record: audit/human-review-2026-08/AUDIT.md", + "distinct_from": "engineering/agent-harness (machine verification and loop control -- human-gate is the human lane it lacks; pair them); markdown-html/md-review (renders a code review TO html, one-way, no feedback channel -- use when YOU are the reviewer, human-gate when someone else is); engineering/grill-me (interrogates a plan through conversation, before an artifact exists); engineering/ship-gate (pre-production technical audit, not human sign-off); marketing-skill/content-humanizer and engineering/behuman (make AI text sound human -- human APPROVAL, not human VOICE, despite the name)" + }, + "attribution": { + "upstream": "https://github.com/petergyang/human-review", + "upstream_author": "Peter Yang", + "upstream_license": "MIT", + "derivation_note": "CONCEPTUAL derivation -- no upstream source code is copied or vendored. Upstream is a ~5,200 LOC Node application (Node >= 20, npm dependency 'marked', detached local HTTP server, browser chrome UI); this repo's conventions are stdlib-Python-only with no build system and no dependencies, which is the same test that kept the heavier skillopt package out in v2.11.2. What was taken is the pattern: human feedback as a batched, anchored, machine-parseable artifact rather than chat prose, and the verbatim-edit rule (a reviewer's `after` text is carried across exactly, applied to the generating source as well as the rendered artifact). What was deliberately built differently, and why, is recorded per-finding in audit/human-review-2026-08/AUDIT.md: no unpinned `npx -y` execution (F1 -- upstream instructs the agent to auto-fetch and run the latest published version on every invocation); no blocking poll and an explicit headless guard plus round cap with escalation (F2 -- upstream tells the agent not to end its turn and to re-poll indefinitely on timeout, with no terminating condition on a browserless host); no local HTTP server or socket at all, so the partially-ungated-route question does not arise (F3); no writes to user-global agent config as an install side effect (F4); no silent in-place overwrite of the reviewed file (F5); no third-party parser in the trust path (F6). Added beyond upstream: a closing gate (G1-G7) that refuses to report done without a collected round, a named reviewer, and resolved blocking items, with explicit recorded waivers. G7 was added during PR review after a reproduced hole: a mistyped severity heading (`## BLOKCER`) silently downgrades to NIT, so a reviewer's genuine blocker could be lost to a typo while close still exited 0; the parser's integrity problems are now closer-blocking rather than advisory prose. The optional bridge documented in SKILL.md invokes upstream PINNED (`npx -y human-review@0.6.0`) and is opt-in only; the gate still governs closure. Upstream's own test suite was run during the audit: 90/90 passing." + } +} diff --git a/engineering/human-gate/.claude-plugin/plugin.json b/engineering/human-gate/.claude-plugin/plugin.json index 6ad8db2d..a337a2ae 100644 --- a/engineering/human-gate/.claude-plugin/plugin.json +++ b/engineering/human-gate/.claude-plugin/plugin.json @@ -11,15 +11,5 @@ "license": "MIT", "skills": [ "./skills/human-gate" - ], - "source": { - "build_pattern": "Conceptual derivation, not a code vendor -- the batched-review pattern from petergyang/human-review rebuilt as three stdlib-only Python tools (review page builder, sidecar parser, gate state machine) under this repo's no-dependency conventions, with a closing gate and loop discipline upstream does not have. Audit record: audit/human-review-2026-08/AUDIT.md", - "distinct_from": "engineering/agent-harness (machine verification and loop control -- human-gate is the human lane it lacks; pair them); markdown-html/md-review (renders a code review TO html, one-way, no feedback channel -- use when YOU are the reviewer, human-gate when someone else is); engineering/grill-me (interrogates a plan through conversation, before an artifact exists); engineering/ship-gate (pre-production technical audit, not human sign-off); marketing-skill/content-humanizer and engineering/behuman (make AI text sound human -- human APPROVAL, not human VOICE, despite the name)" - }, - "attribution": { - "upstream": "https://github.com/petergyang/human-review", - "upstream_author": "Peter Yang", - "upstream_license": "MIT", - "derivation_note": "CONCEPTUAL derivation -- no upstream source code is copied or vendored. Upstream is a ~5,200 LOC Node application (Node >= 20, npm dependency 'marked', detached local HTTP server, browser chrome UI); this repo's conventions are stdlib-Python-only with no build system and no dependencies, which is the same test that kept the heavier skillopt package out in v2.11.2. What was taken is the pattern: human feedback as a batched, anchored, machine-parseable artifact rather than chat prose, and the verbatim-edit rule (a reviewer's `after` text is carried across exactly, applied to the generating source as well as the rendered artifact). What was deliberately built differently, and why, is recorded per-finding in audit/human-review-2026-08/AUDIT.md: no unpinned `npx -y` execution (F1 -- upstream instructs the agent to auto-fetch and run the latest published version on every invocation); no blocking poll and an explicit headless guard plus round cap with escalation (F2 -- upstream tells the agent not to end its turn and to re-poll indefinitely on timeout, with no terminating condition on a browserless host); no local HTTP server or socket at all, so the partially-ungated-route question does not arise (F3); no writes to user-global agent config as an install side effect (F4); no silent in-place overwrite of the reviewed file (F5); no third-party parser in the trust path (F6). Added beyond upstream: a closing gate (G1-G7) that refuses to report done without a collected round, a named reviewer, and resolved blocking items, with explicit recorded waivers. G7 was added during PR review after a reproduced hole: a mistyped severity heading (`## BLOKCER`) silently downgrades to NIT, so a reviewer's genuine blocker could be lost to a typo while close still exited 0; the parser's integrity problems are now closer-blocking rather than advisory prose. The optional bridge documented in SKILL.md invokes upstream PINNED (`npx -y human-review@0.6.0`) and is opt-in only; the gate still governs closure. Upstream's own test suite was run during the audit: 90/90 passing." - } + ] } diff --git a/engineering/llm-cost-optimizer/skills/llm-cost-optimizer/SKILL.md b/engineering/llm-cost-optimizer/skills/llm-cost-optimizer/SKILL.md index 3dd22507..86f049d9 100644 --- a/engineering/llm-cost-optimizer/skills/llm-cost-optimizer/SKILL.md +++ b/engineering/llm-cost-optimizer/skills/llm-cost-optimizer/SKILL.md @@ -60,9 +60,13 @@ Sort by: feature × model × token count. Usually 2–3 endpoints drive the majo | Complexity | Characteristics | Right Model Tier | |---|---|---| -| Simple | Classification, extraction, yes/no, short output | Small (Haiku, GPT-4o-mini, Gemini Flash) | -| Medium | Summarization, structured output, moderate reasoning | Mid (Sonnet, GPT-4o) | -| Complex | Multi-step reasoning, code gen, long context | Large (Opus, o3) | +| Simple | Classification, extraction, yes/no, short output | Small (Haiku tier, or your provider's cheapest) | +| Medium | Summarization, structured output, moderate reasoning | Mid (Sonnet tier) | +| Complex | Multi-step reasoning, code gen, long context | Large (Opus tier, or your provider's frontier model) | + +Tiers, not model names: the naming churns every few months, the three-tier +shape does not. Check your provider's current lineup and price list when you +apply this. **If token logging doesn't exist yet:** That's the first deliverable -- not prompt compression, not routing. You cannot optimize what you cannot see. Provide a logging schema and move to optimization only once baseline data exists. diff --git a/engineering/memory-engineering/.claude-plugin/authoring-notes.json b/engineering/memory-engineering/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..b02bd2f6 --- /dev/null +++ b/engineering/memory-engineering/.claude-plugin/authoring-notes.json @@ -0,0 +1,6 @@ +{ + "source": { + "build_pattern": "Four-lens synthesis (Stanford cost / Microsoft what-to-keep / Anthropic control / Nvidia hardware) + 4 deterministic stdlib scripts, with a blocking forgetting gate. Framing synthesized from 'How to be a Memory Engineer' by @N01ennn (x.com/N01ennn/status/2083971749079581120); every quantitative claim is cited to the primary source instead, and two of the article's paraphrases are corrected in the references (the 47x energy figure is the spread across ten systems, not an accuracy-matched pair; the 97% error-reduction figure is one named customer's reported result, not a general property).", + "distinct_from": "llm-wiki (maintains one specific markdown vault; this audits and prices any memory system); skillopt-sleep (runs a nightly consolidation loop; this decides whether that loop's output is worth keeping); agent-harness (bounds a task loop; this bounds a store); llm-cost-optimizer (prices inference generally, not the memory write path specifically)" + } +} diff --git a/engineering/memory-engineering/.claude-plugin/plugin.json b/engineering/memory-engineering/.claude-plugin/plugin.json new file mode 100644 index 00000000..205f85f4 --- /dev/null +++ b/engineering/memory-engineering/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "memory-engineering", + "description": "Engineer an agent's forgetting, not just its remembering. Four deterministic stdlib scripts implement the four lenses of agent memory: a cost profiler that splits construction from query spend and reports cost per correct answer (construction energy exceeds total query energy across 300 queries in the Stanford characterization); an architecture picker that scores the four paradigm families — long-context, flat RAG, structure-augmented RAG, agentic — disqualifies on hard constraints, names the cost the winning choice makes you pay, and refuses to pick when the top two tie; a density auditor that classifies every record in a real memory directory or JSONL export as FACT / SKILL / LOG / PROSE, finds near-duplicates, and flags stale and time-relative wording; and a forgetting-policy linter that fails any design with no forgetting rule or that auto-merges contradictions. Ships cs-memory-engineer agent, /cs:memory-engineering and /cs:forgetting-audit commands, 4 references citing 7 sources each, and a seven-question forcing worksheet.", + "version": "2.11.2", + "author": { + "name": "Alireza Rezvani", + "url": "https://alirezarezvani.com" + }, + "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/engineering/memory-engineering", + "repository": "https://github.com/alirezarezvani/claude-skills", + "license": "MIT", + "skills": [ + "./skills/memory-engineering" + ] +} diff --git a/engineering/memory-engineering/README.md b/engineering/memory-engineering/README.md new file mode 100644 index 00000000..4166f823 --- /dev/null +++ b/engineering/memory-engineering/README.md @@ -0,0 +1,121 @@ +# memory-engineering + +> Your agent's problem was never that it forgets. It's that it never forgets +> **on purpose**. + +A storer optimizes what a system remembers. A memory engineer optimizes what it +forgets. This plugin makes that shift executable: four deterministic stdlib +scripts that price the write path, choose which cost to pay, audit what a store +actually holds, and **refuse a design with no forgetting policy**. + +## Why this exists + +Everyone building agent memory optimizes retrieval. Almost nobody engineers +what it costs to build, what is worth keeping, who can delete it, and where it +lands on the hardware. Stanford's systems characterization of ten memory systems +found the gap concretely: + +- **Construction energy exceeds total query-phase energy across 300 queries** — + the bill is paid on the write path you never watch. +- Energy per correct answer **spreads more than 47×** across systems (BM25 at + 4,145 J; MIRIX at ~197 kJ). +- At 1M tokens, footprint varies **up to 9×** — and **"none of the evaluated + systems prune or forget by default."** + +If you did not build forgetting, you do not have it. + +## Install + +```bash +/plugin marketplace add alirezarezvani/claude-skills +/plugin install memory-engineering +``` + +## Use + +```bash +/cs:memory-engineering ~/.claude/memory # full four-lens pass +/cs:forgetting-audit design.json # just the blocking gate +``` + +Or run the scripts directly — each has `--help`, `--sample`, and `--output json`: + +```bash +cd skills/memory-engineering + +python scripts/memory_cost_profiler.py --sample +python scripts/memory_architecture_picker.py --sample +python scripts/memory_density_auditor.py --dir ~/.claude/memory +python scripts/forgetting_policy_linter.py --sample-failing +``` + +## The four scripts + +| Script | Lens | What it does | Exit codes | +|---|---|---|---| +| `memory_cost_profiler.py` | Stanford — *what does it cost?* | Splits construction vs query spend, computes **cost per correct answer**, flags under-amortized writes and construction co-located with live queries | 0 · 2 finding · 3 bad input | +| `memory_architecture_picker.py` | Stanford — *which cost to pay?* | Scores long-context / flat RAG / structure-augmented RAG / agentic against constraints, disqualifies on hard limits, **names the cost you're choosing**, refuses to pick on a tie | 0 · 2 ambiguous · 3 bad input · 4 none viable | +| `memory_density_auditor.py` | Microsoft — *what's worth keeping?* | Classifies records **FACT / SKILL / LOG / PROSE**, finds near-duplicates, flags stale and time-relative wording, scores knowledge density. Runs on a real directory or JSONL | 0 dense · 2 finding · 3 bad input | +| `forgetting_policy_linter.py` | Anthropic + the gate | 8 checks; **F1** (explicit forgetting rule) and **F4** (contradictions surfaced, never auto-merged) are **blocking** | 0 PASS · 2 CONDITIONAL · **4 FAIL** | + +Stdlib only. No network, no LLM calls, no dependencies. + +## The gate + +``` +$ python scripts/forgetting_policy_linter.py --sample-failing + +VERDICT: FAIL (0/8 checks pass) +This design does not forget on purpose. F1 failed. F4 failed. + + FAIL F1 explicit forgetting rule [BLOCKING] + No TTL, no capacity bound, no decay. The store only grows. + FAIL F4 contradictions surfaced, never auto-merged [BLOCKING] + Contradiction policy is 'newest_wins', which resolves conflicts silently. +``` + +**F4 is blocking on purpose.** Two memories that disagree may both have been +true in different contexts — "deploys go through Jenkins" and "deploys go +through GitHub Actions" is not a contradiction to resolve, it is a migration to +record. Auto-merging destroys the only evidence the conflict existed. + +## Evidence discipline + +The four-lens framing synthesizes *"How to be a Memory Engineer, from the +perspective of Stanford, Microsoft, Anthropic and Nvidia"* by +[@N01ennn](https://x.com/N01ennn/status/2083971749079581120). + +**Every quantitative claim is cited to the primary source, not to that +article,** and each carries an explicit confidence level. Two of the article's +paraphrases are corrected in the references: + +- The **47×** energy figure is the spread across ten evaluated systems, not + "two systems with identical accuracy" (`memory_cost_canon.md` §2). +- The **97%** first-pass-error reduction is Rakuten's named, vendor-published + customer testimonial — not a controlled study or a general property of + building memory this way (`memory_control_and_governance.md` §4). + +## Not this plugin + +| You want | Use | +|---|---| +| Build and maintain one markdown knowledge vault | `llm-wiki` | +| A nightly self-improvement loop over transcripts | `skillopt-sleep` | +| Bound an agent's *task loop* | `agent-harness` | +| Price inference generally | `llm-cost-optimizer` | + +This bounds a **store**, not a loop and not a vault. + +## Primary sources + +- Omri, Y. et al. — *Agent Memory: Characterization and System Implications of Stateful Long-Horizon Workloads*, [arXiv:2606.06448](https://arxiv.org/abs/2606.06448) +- Microsoft Research — [*PlugMem: A Task-Agnostic Plugin Memory Module for LLM Agents*](https://www.microsoft.com/en-us/research/publication/plugmem-a-task-agnostic-plugin-memory-module-for-llm-agents/) +- Kontonis, V. et al. — *MEMENTO: Teaching LLMs to Manage Their Own Context*, [arXiv:2604.09852](https://arxiv.org/abs/2604.09852) +- Anthropic — [*Built-in memory for Claude Managed Agents*](https://claude.com/blog/claude-managed-agents-memory) + +Full citation lists (7 sources each) are in +[`skills/memory-engineering/references/`](skills/memory-engineering/references/). + +## License + +MIT. diff --git a/engineering/memory-engineering/agents/cs-memory-engineer.md b/engineering/memory-engineering/agents/cs-memory-engineer.md new file mode 100644 index 00000000..eeaf8e01 --- /dev/null +++ b/engineering/memory-engineering/agents/cs-memory-engineer.md @@ -0,0 +1,78 @@ +--- +name: cs-memory-engineer +description: Use when someone is adding memory to an agent, choosing a memory architecture, auditing an existing memory store, or asking why their memory system is expensive, slow, or wrong. Prices the write path, names which cost the design is paying, classifies what the store actually holds, and refuses to sign off a design with no forgetting policy. +model: inherit +--- + +# cs-memory-engineer + +You are a memory engineer. Your first question is never "what should it +remember?" — it is **"what leaves the store, and on what rule?"** + +## Voice + +Blunt, cost-first, and allergic to the word "best". You have read the systems +research and you quote it with its confidence level attached. You would rather +tell someone their memory system is unaffordable now than let them discover it +after two years of accumulated records. + +Your opening move on almost any request: + +> "Before we talk about what it retrieves — what does one write cost, and what +> leaves the store?" + +## Hard rules + +1. **Never quote a quality number without a cost number.** Accuracy alone is + the measurement this role exists to refuse. +2. **Never recommend the "best" memory system.** No family wins on build cost, + query speed, and accuracy at once. Recommend a family and *name the cost it + makes them pay*. +3. **Never auto-merge contradictions**, and never let a design do it. Two + memories that disagree may both have been true in different contexts. The + system surfaces; the human decides. +4. **Never sign off a design without a forgetting rule.** If they did not build + forgetting, they do not have it — no evaluated system provides it by default. + `forgetting_policy_linter.py` exiting 4 is a stop, not a suggestion. +5. **Never schedule a pass that has not been run by hand once.** If the manual + run did not change a decision, automating it only makes noise. +6. **Attribute every number.** Say which paper or vendor it came from and how + much confidence it carries. Vendor customer testimonials are not benchmarks + and must be labeled as testimonials. + +## How you work + +1. **Price it.** Run `memory_cost_profiler.py`. Lead with the + construction/query split and cost per correct answer, not with latency. +2. **Name the tradeoff.** Run `memory_architecture_picker.py`. If it exits 2 + (ambiguous), do not pick for them — put the tie-breaking question to them and + wait. +3. **Look in the store.** Run `memory_density_auditor.py` against the real + directory. People are consistently wrong about how much of their memory is + transcripts. +4. **Gate.** Run `forgetting_policy_linter.py`. Report FAIL as a blocker with + the specific check that failed and its fix. +5. **Sequence it.** Write path first → contradiction detection by hand → + forgetting policy before volume climbs → hardware tuning last. + +## What you refuse + +- Recommending a memory system when the user has not stated a retention rule. +- Reporting accuracy improvements without the cost delta beside them. +- Treating a vendor's published customer figure as a general property of an + approach. +- Letting "we'll add pruning later" stand. Later is a data migration with a + judgment call attached to every record, which is why it never happens. + +## Scope boundaries + +- Maintaining one specific markdown vault → hand off to `llm-wiki`. +- A nightly consolidation loop over transcripts → hand off to `skillopt-sleep`. +- Bounding an agent's task loop → hand off to `agent-harness`. + +You bound the **store**, not the loop and not the vault. + +## Skill + +Full workflow, scripts, references and worksheets: +`engineering/memory-engineering/skills/memory-engineering/SKILL.md` diff --git a/engineering/memory-engineering/commands/cs-forgetting-audit.md b/engineering/memory-engineering/commands/cs-forgetting-audit.md new file mode 100644 index 00000000..10cc56ff --- /dev/null +++ b/engineering/memory-engineering/commands/cs-forgetting-audit.md @@ -0,0 +1,60 @@ +--- +description: Run only the blocking forgetting gate on a memory design or store — what leaves, and on what rule. +argument-hint: "[policy JSON, or a memory directory to audit]" +--- + +# /cs:forgetting-audit + +The short pass. Skip the cost and architecture work; answer one question about +`$ARGUMENTS`: + +> **What leaves this store, and on what rule?** + +## Run + +If given a policy JSON: + +```bash +python skills/memory-engineering/scripts/forgetting_policy_linter.py --policy +``` + +If given a directory, first show what is actually accumulating, then gate: + +```bash +python skills/memory-engineering/scripts/memory_density_auditor.py --dir +python skills/memory-engineering/scripts/forgetting_policy_linter.py --policy +``` + +If no policy file exists, that is the answer — nothing leaves the store. Show +what `--sample-failing` blocks, then help write one from +`skills/memory-engineering/assets/forgetting_policy_template.md`. + +## The two blocking checks + +- **F1 — an explicit forgetting rule** (TTL, capacity bound with a stated + eviction order, or relevance decay). None of the memory systems in the + Stanford evaluation prunes or forgets by default: if it was not built, it does + not exist. +- **F4 — contradictions surfaced, never auto-merged.** `newest_wins`, + `auto_merge`, `overwrite` and `last_write_wins` all fail. Two memories that + disagree may both have been true in different contexts, and silently resolving + them destroys the only evidence the conflict existed. + +The other six checks (dedup, consolidation, scope, audit trail, rollback, +growth-slope monitoring) degrade the verdict to CONDITIONAL rather than failing +it. + +## Report + +1. **Verdict** — PASS (0) / CONDITIONAL (2) / **FAIL (4)** +2. **Every failing check** with its ID, why it matters, and its fix +3. **The one thing to fix first** — F1 or F4 if either failed; otherwise the + highest-leverage warning + +## Do not + +- Do not soften a FAIL into a suggestion. Retrofitting forgetting onto a full + store is a data migration with a judgment call attached to every record — + which is exactly why it never happens. +- Do not accept "we will add pruning later." Later is the failure mode. +- Do not propose auto-resolution for contradictions, in any form. diff --git a/engineering/memory-engineering/commands/cs-memory-engineering.md b/engineering/memory-engineering/commands/cs-memory-engineering.md new file mode 100644 index 00000000..2440fd60 --- /dev/null +++ b/engineering/memory-engineering/commands/cs-memory-engineering.md @@ -0,0 +1,77 @@ +--- +description: Price, choose, audit and gate an agent memory system — the full four-lens memory-engineering pass. +argument-hint: "[memory dir, design spec JSON, or a question about a memory system]" +--- + +# /cs:memory-engineering + +Run the memory-engineering pass on `$ARGUMENTS`. + +Load `engineering/memory-engineering/skills/memory-engineering/SKILL.md` and +follow it. Report every script's exit code as a finding — a non-zero exit is a +result to surface, never an error to swallow. + +## Pre-flight + +Establish these before running anything. If the user cannot answer 1 or 2, +that gap **is** the first finding — say so rather than guessing: + +1. **Does a memory system exist yet, or is this a design?** Design → steps 1, 2, 4. Existing store → steps 1, 3, 4. +2. **What leaves the store today?** If the answer is "nothing", skip to step 4; the gate result is the headline. +3. **Is this actually a memory question?** Maintaining one markdown vault → `llm-wiki`. Nightly consolidation loop → `skillopt-sleep`. Bounding a task loop → `agent-harness`. + +## Pass + +**1. Price the write path** + +```bash +python skills/memory-engineering/scripts/memory_cost_profiler.py --spec +``` + +Lead the report with the construction/query split and **cost per correct +answer**. Never present accuracy on its own. + +**2. Choose which cost to pay** + +```bash +python skills/memory-engineering/scripts/memory_architecture_picker.py --constraints +``` + +If it exits 2 (`AMBIGUOUS`), **stop and put the printed tie-breaking question to +the user.** Do not pick for them — the tie is real, not a tooling limitation. + +**3. Audit the real store** (skip if this is a greenfield design) + +```bash +python skills/memory-engineering/scripts/memory_density_auditor.py --dir +``` + +Report the FACT/SKILL/LOG/PROSE split. Users are routinely wrong about how much +of their store is transcripts. + +**4. Gate on forgetting** — blocking + +```bash +python skills/memory-engineering/scripts/forgetting_policy_linter.py --policy +``` + +Exit 4 is a **stop**. Name the failing check (F1 or F4) and its fix. Do not +present a FAIL alongside a recommendation to proceed. + +## Output + +Report in this order — cost before quality, always: + +1. **Verdict** — one line, leading with the blocking result if there is one +2. **Cost** — construction/query split, cost per correct answer, amortization +3. **Architecture** — the family, and the cost it makes them pay +4. **What the store holds** — the FACT/SKILL/LOG/PROSE split, duplicates, staleness +5. **Forgetting gate** — PASS / CONDITIONAL / FAIL with the named failing checks +6. **Next step** — exactly one, sequenced per the ship order + +Attribute every number to its source with a confidence level. Vendor customer +figures are testimonials, not benchmarks — label them as such. + +For a structured walkthrough, hand the user +`skills/memory-engineering/assets/memory_engineer_worksheet.md` (the seven forcing questions) and walk +them **one at a time**. diff --git a/engineering/memory-engineering/skills/memory-engineering/SKILL.md b/engineering/memory-engineering/skills/memory-engineering/SKILL.md new file mode 100644 index 00000000..d31b8716 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/SKILL.md @@ -0,0 +1,100 @@ +--- +name: memory-engineering +description: Use when designing, reviewing, or paying for an agent memory system — adding memory to an agent, choosing between long-context / RAG / graph / agentic memory, auditing what a CLAUDE.md or memory directory actually holds, deciding what to keep and what to expire, or when a memory store keeps growing and nobody has said what leaves it. Prices the write path, picks which cost to pay, classifies records as facts / skills / logs, and refuses a design that has no forgetting policy. +argument-hint: "[optional: path to a memory dir, design spec JSON, or a question]" +license: MIT +metadata: + version: 1.0.0 + build_pattern: "Four-lens synthesis (Stanford / Microsoft / Anthropic / Nvidia) + 4 deterministic stdlib scripts, with a blocking forgetting gate" + distinct_from: "llm-wiki (maintains one specific markdown vault; this audits and prices any memory system); skillopt-sleep (runs a nightly consolidation loop; this decides whether that loop's output is worth keeping); agent-harness (bounds a task loop; this bounds a store)" +--- + +# Memory Engineering — engineer the forgetting, not just the remembering + +> **Portability:** 4 stdlib scripts, no APIs/LLM calls/network. They measure and gate; you decide. + +## What this does + +Anyone can give an agent memory: vector store, pipe in the history, retrieve +top-k. That works until the history outgrows the context window, the write path +costs more than every query it serves, and the store fills with stale state +nobody removes. Memory is not a bucket — it is a system with a metabolism. + +**The shift:** a storer optimizes what a system remembers; a memory engineer +optimizes what it forgets. The problem was never that an agent forgets — it is +that it never forgets *on purpose*. + +## The four lenses + +| Lens | Question | The finding that hurts | +|---|---|---| +| **Stanford** | What does remembering cost? | Construction energy exceeds total query energy across 300 queries. The tuned half is the smaller half. | +| **Microsoft** | What is worth keeping? | More raw memory can make an agent *worse*. Keep facts and skills; drop the events. | +| **Anthropic** | Who controls what it keeps? | A wrong memory does not fail once — it persists into every future session that reads it. | +| **Nvidia** | Where does it hit hardware? | It is all KV cache in HBM. Construction is prefill-heavy and stalls the query a user is waiting on. | + +## Workflow + +```bash +# 1 - Price it first. Never quote a quality number without a cost number. +python scripts/memory_cost_profiler.py --print-sample-spec > workload.json +python scripts/memory_cost_profiler.py --spec workload.json +# 2 - Pick which cost to pay. No "best" verdict; on a tie it asks, exit 2. +python scripts/memory_architecture_picker.py --constraints workload.json +# 3 - Audit what the store actually holds (skip if greenfield). +python scripts/memory_density_auditor.py --dir ~/.claude/memory +# 4 - Gate on forgetting. Exit 4 is a stop, not a suggestion. +python scripts/forgetting_policy_linter.py --policy design.json +# 5 - No command. Prove each pass by hand before scheduling it. +``` + +Step 1 reports the construction/query split, **cost per correct answer**, and +amortization — if construction dominates, cut construction tokens *before* +touching retrieval. Step 2 names the cost the winning family makes you pay. +Step 3 classifies records FACT / SKILL / LOG / PROSE (`LOG-HEAVY` = archiving +events; `PROSE-HEAVY` = docs, not memory). + +Step 4 is the gate: **F1** (explicit forgetting rule) and **F4** (contradictions +surfaced, never auto-merged) are blocking. Retrofitting forgetting onto two +years of records is a migration nobody does; auto-merging disagreeing memories +destroys the evidence the conflict existed. + +Step 5 has no script — prove each pass by hand, then automate. Run it once +against real history and ask whether it changed a decision. If not, scheduling +it only makes noise. Ship order: `forgetting_policy_design.md` §7. + +## Hard rules + +1. **Never quote accuracy without cost per correct answer.** +2. **Never return a "best" memory system** — name the cost the choice makes you pay. +3. **Never auto-merge contradictions.** The system surfaces; the human decides. +4. **Never call a design done without a forgetting rule.** No evaluated system provides one by default. +5. **Never schedule a pass not yet run by hand.** +6. **Report findings as findings.** A non-zero exit is a result to surface, not an error to swallow. +7. **Attribute every number** with its confidence level. Vendor customer figures are testimonials, not benchmarks. + +## Scripts + +| Script | Role | Exit codes | +|---|---|---| +| `scripts/memory_cost_profiler.py` | Construction vs query split, cost per correct answer, amortization, co-location warning | 0 · 2 finding · 3 bad input | +| `scripts/memory_architecture_picker.py` | Scores 4 families, disqualifies, names the cost, refuses to pick on a tie | 0 · 2 ambiguous · 3 bad input · 4 none viable | +| `scripts/memory_density_auditor.py` | FACT/SKILL/LOG/PROSE, duplicates, staleness, density (`--dir` or `--jsonl`) | 0 dense · 2 finding · 3 bad input | +| `scripts/forgetting_policy_linter.py` | The gate: 8 checks, F1 and F4 blocking | 0 PASS · 2 CONDITIONAL · 4 FAIL | + +All support `--output json` and `--sample` (no input file needed). + +## References and assets + +- [`references/memory_cost_canon.md`](references/memory_cost_canon.md) — construction dominance, energy per correct answer, the four families, ten recommendations (7 sources) +- [`references/what_to_keep.md`](references/what_to_keep.md) — PlugMem and MEMENTO: facts over logs, density over volume (7 sources) +- [`references/memory_control_and_governance.md`](references/memory_control_and_governance.md) — memory as files, scope/audit/rollback, poisoning, reading vendor numbers (7 sources) +- [`references/forgetting_policy_design.md`](references/forgetting_policy_design.md) — forgetting mechanisms, contradiction discipline, KV cache, ship order (7 sources) +- [`assets/memory_engineer_worksheet.md`](assets/memory_engineer_worksheet.md) — seven forcing questions with recommended answers + citations; walk one at a time +- [`assets/memory_design_spec.example.json`](assets/memory_design_spec.example.json) — one file covering every script's input +- [`assets/forgetting_policy_template.md`](assets/forgetting_policy_template.md) — fillable policy covering F1–F8 + +## Provenance + +Framing from *"How to be a Memory Engineer"* by [@N01ennn](https://x.com/N01ennn/status/2083971749079581120); every +number is cited to a primary source instead, and two paraphrases are corrected — `memory_cost_canon.md` §2, `memory_control_and_governance.md` §4. diff --git a/engineering/memory-engineering/skills/memory-engineering/assets/forgetting_policy_template.md b/engineering/memory-engineering/skills/memory-engineering/assets/forgetting_policy_template.md new file mode 100644 index 00000000..81baa704 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/assets/forgetting_policy_template.md @@ -0,0 +1,136 @@ +# Forgetting Policy — + +> Fill this in **before** the store grows. Every section maps to a check in +> `forgetting_policy_linter.py`. F1 and F4 are blocking: a design that fails +> either is not ready, regardless of how good its retrieval is. +> +> Copy the JSON block at the bottom into your own file and lint it. + +**System:** ____________________ **Named owner:** ____________________ +**Store location:** ____________________ **Reviewed:** ____________ + +--- + +## F1 — Explicit forgetting rule (BLOCKING) + +*No evaluated memory system prunes or forgets by default. If it is not written +here, the store only grows.* + +Choose at least one: + +- [ ] **TTL** — records expire after `______` days +- [ ] **Capacity bound** — max `______` records / `______` bytes + - Eviction order: ____________________________________ + - *(The eviction order IS the policy. "LRU" is a decision, not a default — + recency is a poor proxy for value, and the fact retrieved once a year is + often the one you cannot reconstruct.)* +- [ ] **Relevance decay** — score decays unless retrieved; expire below `______` + +**Exempt from forgetting** (records that must never expire), and why: + +``` +________________________________________________________ +``` + +## F2 — Dedup at write time + +- [ ] Every write is fingerprinted and near-matches collapsed +- Method: ____________________ Threshold: ____________ + +*Duplicates do not merely waste tokens — they let a stale copy outrank a +corrected one.* + +## F3 — Consolidation / compaction + +- [ ] Enabled Cadence: ____________ +- What merges into what: ______________________________ +- [ ] Merges preserve the source list of every merged record + +*Warning: consolidation is lossy, and it amplifies. A merge pass propagates a +wrong (or poisoned) record into derived records, past the point where source +attribution helps.* + +## F4 — Contradiction handling (BLOCKING) + +- [ ] Contradictions are **surfaced to a human** with both versions, both + sources, and both timestamps +- Who resolves them: ____________________ +- Where they surface: ____________________ + +**Explicitly forbidden:** `auto_merge`, `newest_wins`, `overwrite`, +`last_write_wins`. + +*Two memories that disagree may both have been true in different contexts. +"Deploys go through Jenkins" and "deploys go through GitHub Actions" is not a +contradiction to resolve — it is a migration to record.* + +## F5 — Scope + +| | Who | Notes | +|---|---|---| +| **Read** | ______________ | | +| **Write** | ______________ | | + +- [ ] Read scope and write scope are different +- [ ] Shared / org-wide stores are read-only +- [ ] Components ingesting untrusted content do **not** hold write scope + +## F6 — Audit trail + +- [ ] Every write carries a timestamp +- [ ] Every write carries source attribution +- Where audit events are visible: ____________________ + +*Without attribution you can detect a bad fact but not find its origin — which +means you cannot stop it recurring.* + +## F7 — Rollback and delete + +- [ ] Earlier versions can be restored +- [ ] A single record can be hard-deleted without a migration +- [ ] Content can be **redacted from history** (distinct from version rollback, + and what erasure obligations such as GDPR Art. 17 actually require) +- Delete path: ____________________ Typical time to delete: __________ + +## F8 — Growth-slope monitoring + +- [ ] Footprint over time is tracked, not just current size +- Alert threshold (slope): ____________________ +- Current baseline: ____________ Current slope: ____________/month + +*Slope, not starting size, is what bankrupts a long-lived agent.* + +--- + +## Lint this + +```json +{ + "name": "", + "forgetting": { + "rule": "ttl", + "ttl_days": 365, + "max_records": 50000, + "decay": "none" + }, + "dedup_on_write": true, + "consolidation": { "enabled": true, "cadence": "weekly" }, + "contradiction_policy": "surface", + "scope": { + "read": [""], + "write": [""] + }, + "audit_trail": { "timestamp": true, "source_attribution": true }, + "rollback": { "supported": true, "delete_path": "api" }, + "growth_monitoring": { "tracks_slope": true, "baseline_only": false } +} +``` + +```bash +python scripts/forgetting_policy_linter.py --policy my_policy.json +# exit 0 = PASS · 2 = CONDITIONAL · 4 = FAIL (F1 or F4 failed) +``` + +**Ship order reminder** — build the write path first and let it fill; add +contradiction detection by hand a few times; add this policy *before* volume +climbs; tune the hardware layer last. diff --git a/engineering/memory-engineering/skills/memory-engineering/assets/memory_design_spec.example.json b/engineering/memory-engineering/skills/memory-engineering/assets/memory_design_spec.example.json new file mode 100644 index 00000000..c4e7fcba --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/assets/memory_design_spec.example.json @@ -0,0 +1,71 @@ +{ + "_comment": "One spec covering every script in the memory-engineering skill. Each top-level block is consumed by a different script; pass this same file to all of them.", + "_usage": { + "memory_cost_profiler.py": "--spec (reads: name, construction, query, pricing_usd_per_mtok, accuracy)", + "memory_architecture_picker.py": "--constraints (reads: name, *_sensitivity/_pressure/_need/growth, hard_constraints)", + "forgetting_policy_linter.py": "--policy (reads: name, forgetting, dedup_on_write, consolidation, contradiction_policy, scope, audit_trail, rollback, growth_monitoring)", + "memory_density_auditor.py": "takes --dir or --jsonl instead of this file" + }, + "name": "support-agent memory store (worked example)", + "construction": { + "records_per_day": 400, + "prompt_tokens_per_record": 12000, + "output_tokens_per_record": 800, + "embedding_tokens_per_record": 12000, + "colocated_with_queries": true + }, + "query": { + "queries_per_day": 1200, + "prompt_tokens_per_query": 2400, + "output_tokens_per_query": 300, + "embedding_tokens_per_query": 40 + }, + "pricing_usd_per_mtok": { + "prompt": 3.0, + "output": 15.0, + "embedding": 0.02 + }, + "accuracy": 0.72, + "query_latency_sensitivity": "high", + "build_budget_pressure": "medium", + "recall_need": "high", + "volume_growth": "high", + "mutability_need": "medium", + "hard_constraints": { + "max_p99_query_ms": 1500, + "context_window_tokens": 200000, + "expected_history_tokens": 4000000 + }, + "forgetting": { + "rule": "ttl", + "ttl_days": 365, + "max_records": 50000, + "decay": "none" + }, + "dedup_on_write": true, + "consolidation": { + "enabled": true, + "cadence": "weekly" + }, + "contradiction_policy": "surface", + "scope": { + "read": [ + "support-agents" + ], + "write": [ + "memory-writer-service" + ] + }, + "audit_trail": { + "timestamp": true, + "source_attribution": true + }, + "rollback": { + "supported": true, + "delete_path": "api" + }, + "growth_monitoring": { + "tracks_slope": false, + "baseline_only": true + } +} diff --git a/engineering/memory-engineering/skills/memory-engineering/assets/memory_engineer_worksheet.md b/engineering/memory-engineering/skills/memory-engineering/assets/memory_engineer_worksheet.md new file mode 100644 index 00000000..76d0c4a9 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/assets/memory_engineer_worksheet.md @@ -0,0 +1,171 @@ +# Memory Engineer Worksheet — the seven forcing questions + +Walk these **one at a time**, in order. Each has a recommended answer and a +citation. Do not batch them; the answer to one changes the framing of the next. + +Fill this in before writing any memory code. If a question cannot be answered, +that is the finding — stop and go get the answer. + +--- + +**System under review:** ________________________________________ +**Date:** ____________ **Owner (a named human):** ____________________ + +--- + +## 1. What does one constructed record cost, and how many queries will it serve? + +*Why it matters:* Construction energy exceeds total query energy across 300 +queries for LLM-mediated memory. The invisible half of the bill is usually the +bigger half. + +*Recommended answer:* Under roughly 10 queries per record, build **lazily on +second access** rather than eagerly at the end of every session. + +*Citation:* Stanford rec. 4 — `memory_cost_canon.md` §6 +*Check with:* `memory_cost_profiler.py` + +**Your answer:** + +``` +cost per record: ______ queries per record: ______ +decision: ____________________________________________ +``` + +--- + +## 2. Which of build cost, query speed, and accuracy are you giving up? + +*Why it matters:* No paradigm family wins all three. Refusing to name the +sacrifice does not avoid it — it just means it gets discovered in production. + +*Recommended answer:* Name it explicitly and write it down here, so the next +person does not re-litigate it. + +*Citation:* Stanford taxonomy — `memory_cost_canon.md` §3 +*Check with:* `memory_architecture_picker.py` + +**Your answer:** + +``` +family chosen: ________________________________________ +cost accepted: ________________________________________ +what would kill this choice: __________________________ +``` + +--- + +## 3. Is this record a fact, a skill, or an event? + +*Why it matters:* Agents do not need to replay what happened; they need the +facts and skills extracted from it. Storing events is what makes retrieval +drown. + +*Recommended answer:* Keep facts and skills. Extract from events, then drop the +events. + +*Citation:* PlugMem — `what_to_keep.md` §1 +*Check with:* `memory_density_auditor.py` + +**Your answer:** + +``` +current FACT/SKILL/LOG/PROSE split: ___________________ +extraction happens at: [ ] write time [ ] read time [ ] not at all +``` + +--- + +## 4. When two stored memories disagree, what happens? + +*Why it matters:* Two memories that disagree may both have been true in +different contexts. Anything automatic destroys the evidence that a conflict +existed — and the conflict is usually the interesting part. + +*Recommended answer:* Surface both versions with sources and timestamps to a +human. `newest_wins` and `auto_merge` are not policies, they are defaults +nobody chose. + +*Citation:* `forgetting_policy_design.md` §3 — linter check **F4 (blocking)** + +**Your answer:** + +``` +contradiction policy: _________________________________ +who resolves it: ______________________________________ +``` + +--- + +## 5. Who can write to this store, and can you delete one record without a migration? + +*Why it matters:* A wrong memory does not fail once — it persists into every +future session that reads it. And anything that influences what the agent reads +can influence what it permanently believes. + +*Recommended answer:* Separate read scope from write scope; shared stores +read-only. Keep a hard-delete path you can invoke without a migration. + +*Citation:* Anthropic — `memory_control_and_governance.md` §3, §5 +*Linter checks:* F5, F6, F7 + +**Your answer:** + +``` +read scope: ___________________________________________ +write scope: __________________________________________ +delete one record without a migration? [ ] yes [ ] no +untrusted-content ingestion holds write scope? [ ] yes [ ] no +``` + +--- + +## 6. What leaves the store, and on what rule? + +*Why it matters:* None of the evaluated memory systems prunes or forgets by +default. If you did not build it, you do not have it — and retrofitting it onto +a full store is a migration nobody ever does. + +*Recommended answer:* Choose now, while the store is small: a TTL, a capacity +bound **with a stated eviction order**, or relevance decay. + +*Citation:* Stanford — `forgetting_policy_design.md` §1, §2 — linter check +**F1 (blocking)** + +**Your answer:** + +``` +mechanism: [ ] TTL ____d [ ] capacity ______ [ ] decay [ ] NONE (blocked) +eviction order (if capacity): _________________________ +``` + +--- + +## 7. Are you tracking footprint growth *slope*, or only current size? + +*Why it matters:* At 1M tokens, footprint already varies up to 9× across +systems. Growth slope, not starting size, is what bankrupts a long-lived agent — +and agentic systems compound as the store itself grows. + +*Recommended answer:* Track the slope and alert on it. + +*Citation:* Stanford rec. 9 — `memory_cost_canon.md` §4 — linter check F8 + +**Your answer:** + +``` +slope tracked? [ ] yes [ ] no (baseline only) +alert threshold: ______________________________________ +``` + +--- + +## Sign-off + +- [ ] `memory_cost_profiler.py` run; cost per correct answer recorded +- [ ] `memory_architecture_picker.py` run; the accepted cost is named above +- [ ] `memory_density_auditor.py` run; FACT/SKILL/LOG/PROSE split recorded +- [ ] `forgetting_policy_linter.py` exits 0 or 2 — **never 4** +- [ ] Every scheduled pass was run by hand first and changed a decision + +**Named owner:** ______________________ **Date:** ____________ diff --git a/engineering/memory-engineering/skills/memory-engineering/references/forgetting_policy_design.md b/engineering/memory-engineering/skills/memory-engineering/references/forgetting_policy_design.md new file mode 100644 index 00000000..c5851e66 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/references/forgetting_policy_design.md @@ -0,0 +1,184 @@ +# Forgetting Policy Design — and where memory hits the hardware + +> The keystone, plus the Nvidia lens: *how do you forget on purpose, and where +> does all of it land on the GPU?* + +--- + +## 1. Why forgetting must be designed before the store grows + +The single most consequential finding for anyone shipping agent memory: + +> "None of the evaluated systems prune or forget by default, so footprint grows +> monotonically under default behavior." +> — Omri et al., arXiv:2606.06448 (confidence: **high**) + +Read that as an engineering instruction: **if you did not build forgetting, you +do not have it.** Not from your vector database, not from your memory +framework, not from your agent SDK. + +And the cost of retrofitting is asymmetric. Adding a forgetting policy to an +empty store is a config decision. Adding one to a store with two years of +accumulated records is a data-migration project with a judgment call attached to +every record — which is why it never happens, and why the store keeps growing. + +**Slope beats baseline.** The paper's recommendation 9 is to evaluate both +baseline footprint *and* cost growth slope. A store that starts at 2 GB and +grows 1%/month is healthier than one starting at 200 MB and growing 40%/month. +Agentic systems (Paradigm IV) compound worst, because the store itself becomes +input to the next construction pass. + +## 2. The four forgetting mechanisms + +Pick at least one. They compose. + +| Mechanism | Rule | Best when | Failure mode | +|---|---|---|---| +| **TTL** | Expire after N days | Facts with a natural shelf life (prices, staffing, config) | Deletes a still-true fact nobody restated | +| **Capacity bound** | Cap records/bytes, evict by policy | Hard budget, predictable cost | Eviction order becomes the real policy — LRU evicts rare-but-critical facts | +| **Relevance decay** | Score decays unless retrieved; expire below threshold | Retrieval frequency correlates with value | Self-reinforcing: never-retrieved-because-never-surfaced records die | +| **Consolidation** | Merge N related records into one denser record | Many thin records on one topic | Lossy merges destroy the distinctions that mattered | + +**On eviction order.** If you use a capacity bound, the eviction policy *is* +your forgetting policy — "LRU" is a real design decision, not a default. Recency +is a poor proxy for value in memory systems: the fact you look up once a year is +often the one you cannot reconstruct. + +## 3. Never auto-merge contradictions + +This is check **F4** in the linter, and it is blocking. + +When two stored memories disagree, the tempting resolutions are all wrong: + +- **`newest_wins`** — assumes recency implies correctness. Often it means the + newest session was confused. +- **`auto_merge`** — produces a record that says something neither source said. +- **`overwrite` / `last_write_wins`** — the storage layer's default, chosen by + nobody, silently destroying the evidence that a conflict existed. + +**Two memories that disagree may both have been true in different contexts.** +"Deploys go through Jenkins" and "deploys go through GitHub Actions" are not a +contradiction to resolve — they are a migration to record, and the interesting +information is *when it changed and why*. + +The rule: **the system surfaces, the human decides.** Surface both versions with +their sources and timestamps. A contradiction is a signal that your model of the +world is out of date, which is exactly the signal you do not want auto-resolved. + +## 4. Where all of this lands on the hardware + +Strip away the algorithms and every memory decision becomes a GPU decision. + +**Keeping full history in context is quadratic, not merely slow.** Attention +cost grows with the square of sequence length, so doubling retained history +roughly quadruples the attention work. + +**Prefix caching saves you within a session and collapses across sessions.** +The KV cache that makes turn 40 cheap in one conversation does not carry to +tomorrow's conversation. Inter-session memory is precisely the case where the +cache does not help — which is why "just keep it in context" degrades from a +cost problem into a feasibility problem at session boundaries. + +**The scarce resource is KV cache in high-bandwidth memory.** A memory engineer +should be able to state their system in these units: HBM bandwidth, GPU +utilization, tokens/second, and KV slots freed. Under every clever retrieval +scheme, the real currency is cache. + +MEMENTO makes the connection concrete: compressing reasoning blocks into +summaries cut peak KV cache ~2.5× and improved vLLM throughput ~1.75× +(arXiv:2604.09852, confidence: **high**). Forgetting *is* a throughput +optimization. + +## 5. Construction is a background job + +Construction is almost pure prefill — long reads in, short writes out — so it +behaves like a background indexing job, not like a user request. + +**Co-locate it with live queries and a large write will stall the scheduler +exactly when a user query arrives.** Prefill saturates the GPU; a query that +lands behind a big construction batch waits for it. + +The controls, per the paper's recommendations 3, 6, 8 and 10: + +1. **Rate-limit** construction with admission control. +2. **Batch** writes rather than constructing per-session inline. +3. **Defer** construction off the latency-sensitive path entirely. +4. **Cap** LLM-bounded retrieval loops — worst-case latency is a selection + criterion, and agentic systems have no natural bound without one. + +`memory_cost_profiler.py` flags `CONSTRUCTION_COLOCATED` for exactly this. + +## 6. Prove each pass by hand before you schedule it + +Before automating any memory pass — extraction, consolidation, contradiction +detection, expiry — run it once, by hand, against your real history. + +Ask of the output: **did this change a decision?** If yes, it earns a schedule. +If no, scheduling it just generates noise you will learn to ignore. + +**A memory system run against three notes will hallucinate connections that are +not there.** Sparse input produces confident spurious structure, and the +experience of being wrong early trains you to distrust the system permanently. +Let the store fill with real material first. + +## 7. Ship order + +The sequence matters, because each step's output is the next step's input: + +1. **Build the write path first** — storing facts and skills, not logs — and let + it fill for a few weeks so there is real material to work with. +2. **Add contradiction detection by hand**, a few times. Schedule it only if the + collisions surprise you. +3. **Add the forgetting and maintenance policy before volume climbs.** This is + the step that is easy now and impossible later. +4. **Tune the hardware layer last**, once volume is real: batch construction, + cap retrieval, watch the KV cache. + +Do not schedule everything on day one. Get one manual run reliable, wrap it, +then automate it. + +## 8. The eight checks + +What `forgetting_policy_linter.py` enforces: + +| ID | Check | Blocking | +|---|---|---| +| F1 | Explicit forgetting rule (TTL, capacity, or decay) | **Yes** | +| F2 | Dedup at write time | No | +| F3 | Consolidation / compaction | No | +| F4 | Contradictions surfaced, never auto-merged | **Yes** | +| F5 | Read scope and write scope both named | No | +| F6 | Audit trail (timestamp + source attribution) | No | +| F7 | Rollback and delete path | No | +| F8 | Growth-slope monitoring | No | + +F1 and F2–F8 come from the Stanford recommendations and the Anthropic control +surface. F4 is blocking because it is the one failure that silently destroys +information rather than merely accumulating it. + +--- + +## Sources + +1. Omri, Y. et al. — *Agent Memory: Characterization and System Implications of + Stateful Long-Horizon Workloads*, arXiv:2606.06448. + — §1, §5, §8. +2. Kontonis, V. et al. — *MEMENTO: Teaching LLMs to Manage Their Own Context*, + arXiv:2604.09852. — §4. +3. Kwon, W. et al. — *Efficient Memory Management for Large Language Model + Serving with PagedAttention* (vLLM), SOSP 2023. KV cache paging and prefix + reuse mechanics behind §4. +4. Dao, T. et al. — *FlashAttention* (2022) and *FlashAttention-2* (2023). The + quadratic-attention cost structure referenced in §4. +5. Ebbinghaus, H. — *Über das Gedächtnis* (1885), and Bjork, R. A. & Bjork, + E. L. — *A New Theory of Disuse* (1992). The retrieval-strength/decay model + behind relevance decay in §2. +6. Anthropic — *Built-in memory for Claude Managed Agents*. + — §8 controls F5–F7. +7. Denning, P. J. — *The Working Set Model for Program Behavior* (1968), and the + LRU/LFU cache-eviction literature. Prior art for §2's eviction-order warning. + +## Related tools in this skill + +- `forgetting_policy_linter.py` — §2, §3, §8 +- `memory_cost_profiler.py` — §5 diff --git a/engineering/memory-engineering/skills/memory-engineering/references/memory_control_and_governance.md b/engineering/memory-engineering/skills/memory-engineering/references/memory_control_and_governance.md new file mode 100644 index 00000000..06483abd --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/references/memory_control_and_governance.md @@ -0,0 +1,165 @@ +# Memory Control and Governance — who controls what it keeps + +> The Anthropic lens: *who controls what it keeps?* +> +> Every figure is attributed with a confidence level. The customer metrics in +> §4 are **vendor-published testimonials**, not controlled studies, and are +> labeled as such. + +--- + +## 1. A wrong memory does not fail once + +This is the asymmetry that makes memory governance different from ordinary +storage governance: + +**A bad retrieval fails one query. A bad memory fails every future session that +reads it.** + +An error written into memory is not a transient defect — it is a persistent +one that compounds, propagates into derived records during consolidation, and +is retrieved with the same confidence as a correct one. By the time you notice, +it has been read hundreds of times and possibly rewritten into summaries. + +This is why control is not a layer added on top of a memory system. It is a +property the system either has by construction or does not have at all. + +## 2. Memory as files — the deliberately boring move + +Anthropic's design for Claude Managed Agents mounts memory as **files on a +filesystem**, at `/mnt/memory/` inside the agent's container, so the agent reads +and writes memory with the same bash and code-execution tools it already uses. + +> Memory is "a workspace-scoped collection of text documents mounted as a +> directory," relying on "the same bash and code execution capabilities that +> make it effective at agentic tasks." +> — Anthropic, *Built-in memory for Claude Managed Agents* +> (confidence: **high**) + +The choice looks unambitious, and that is the argument for it. Files give you, +for free, every property a bespoke store has to reimplement: + +| Property | What files give you | +|---|---| +| Inspection | `cat`, `grep`, a text editor | +| Diffing | `diff`, version control | +| Export | copy the directory | +| Selective deletion | `rm` one file | +| Programmatic control | any language's file API | +| Review | a human reads it without a query language | + +**The test:** *a store you cannot open and edit is a store you do not control.* +If answering "what does the agent believe about X, and why?" requires writing a +query against an embedding index, you have given up observability to gain +retrieval convenience. + +## 3. Scope, audit, rollback + +The three controls, as implemented in the Anthropic design (confidence: +**high** — all quoted from vendor documentation): + +**Scope.** Access is set per store: `read_only` makes the mount read-only at +the filesystem level; `read_write` allows create, edit, and delete. An org-wide +store is typically read-only while per-user stores are writable — so shared +knowledge cannot be corrupted by one agent's bad session. Multiple agents can +work concurrently against the same store without overwriting each other. + +**Audit.** "Each write becomes a session event with a timestamp, source +attribution, and a rollback option." Session events surface in the Console. +This is what makes a wrong memory traceable to the session that wrote it — +without attribution, you can detect a bad fact but not find its origin, which +means you cannot stop it recurring. + +**Rollback.** Earlier versions can be restored, and content can be redacted +from history. Note the second half: *redaction from history* is a distinct +capability from *restoring a prior version*, and regimes like GDPR's right to +erasure require the former. + +These map to checks **F5** (scope), **F6** (audit trail), and **F7** (rollback) +in `forgetting_policy_linter.py`. + +## 4. Reported outcomes — read the label + +Vendor-published customer testimonials accompanying the Anthropic memory +launch: + +| Source | Reported result | +|---|---| +| Rakuten (Yusuke Kaji, GM AI for Business) | "97% fewer first-pass errors" at "27% lower cost and 34% lower latency" | +| Wisedocs (Denys Linkov, Head of ML) | Memory use "sped verification up 30%" | + +**Confidence: low-to-moderate, and the reason matters.** These are named, +attributable, on-the-record customer statements — which is better than an +anonymous benchmark — but they are: + +- **not controlled experiments** (no stated baseline methodology, no control arm); +- **selected for publication** by the vendor; +- **not isolated to memory** (a team that adds memory usually changes other + things at the same time). + +⚠️ A widely-shared summary of this material presents the 97% figure as though it +were a general property of building memory this way — "teams building this way +cut first-pass errors by 97 percent." That overstates it. It is *one named +customer's reported result*, not a generalizable finding. Cite it as Rakuten's +claim, with the attribution attached, or do not cite it. + +The defensible version of the claim is the mechanism, not the number: +**observable learning is debuggable learning.** When every write is attributed +and reversible, you can find and fix a bad memory instead of discovering it as +unexplained model drift. + +## 5. Memory poisoning is a security boundary, not just a quality problem + +If an agent writes to memory based on content it reads, then **anything that +can influence what the agent reads can influence what it permanently believes.** +A prompt injection that lands in a memory record does not end with the session +— it persists and is retrieved as trusted context later. + +Minimum controls: + +1. **Separate write authority from read exposure.** The component that ingests + untrusted content should not be the component with write scope. +2. **Attribute every write to a source**, so injected records can be traced and + swept. +3. **Keep the delete path fast.** Incident response on a poisoned memory store + is bounded by how quickly you can remove records. +4. **Treat consolidation as an amplifier.** A merge pass propagates a poisoned + record into derived records, past the point where source attribution helps. + +## 6. The governance checklist + +Before a memory system holds anything that matters: + +- [ ] Read scope and write scope are both named, and they differ +- [ ] Every write carries a timestamp and a source +- [ ] There is a restore path *and* a hard-delete path +- [ ] Deletion satisfies your regulatory obligations (erasure, not just tombstoning) +- [ ] A human can read the store without a query language +- [ ] Untrusted-content ingestion does not hold write scope +- [ ] Contradictions surface to a human rather than resolving silently + +--- + +## Sources + +1. Anthropic — *Built-in memory for Claude Managed Agents*. + — primary source for + §2, §3, §4. +2. `anthropics/skills` — `skills/claude-api/shared/managed-agents-memory.md`. + Implementation-level reference for scopes and store semantics. + +3. Anthropic — memory tool documentation, Claude Developer Platform. Reference + for the filesystem-backed memory tool surface. +4. OWASP — *Top 10 for LLM Applications*, notably LLM01 (Prompt Injection) and + the agentic-memory poisoning discussion. Basis for §5. +5. NIST — *AI Risk Management Framework* (AI 100-1), MAP and MEASURE functions. + Governance framing for auditability requirements. +6. Regulation (EU) 2016/679 (GDPR), Article 17 — right to erasure. Why redaction + from history is a distinct requirement from version rollback. +7. Anthropic — *Building effective agents* (2024). Design context for + tool-mediated agent state. + +## Related tools in this skill + +- `forgetting_policy_linter.py` — §3 (F5 scope, F6 audit, F7 rollback), + §6 (F4 contradictions) diff --git a/engineering/memory-engineering/skills/memory-engineering/references/memory_cost_canon.md b/engineering/memory-engineering/skills/memory-engineering/references/memory_cost_canon.md new file mode 100644 index 00000000..80ddb7ff --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/references/memory_cost_canon.md @@ -0,0 +1,154 @@ +# Memory Cost Canon — what remembering actually costs + +> The Stanford lens: *what does remembering cost?* +> +> Every figure below is attributed and carries a confidence level. Where the +> popular summary of this research differs from the paper, the paper wins and +> the difference is called out. + +--- + +## 1. The finding that reorders your priorities + +**Construction, not retrieval, dominates the lifecycle cost of LLM-mediated +agent memory.** + +> "For LLM-mediated agent memory systems, construction energy exceeds total +> query-phase energy across 300 queries." +> — Omri et al., *Agent Memory: Characterization and System Implications of +> Stateful Long-Horizon Workloads*, arXiv:2606.06448 (confidence: **high** — +> direct quote, measured with a phase-aware profiling harness) + +This is uncomfortable because query latency is the number you watch: the user +feels it, your dashboard graphs it, your on-call pages on it. Construction is +invisible — it happens after the session, on a background worker, and nobody +has an SLO for it. + +The practical consequence: **tuning retrieval on a write-heavy memory system is +optimizing the smaller half of the bill.** + +## 2. Normalize by correct answers, never by accuracy alone + +Accuracy hides cost. Two systems can report the same benchmark score while +differing by more than an order of magnitude in energy per useful result. + +Measured spread across the ten evaluated systems: + +| System | Energy per correct answer | Multiple vs baseline | +|---|---|---| +| BM25 (lexical baseline) | 4,145 J | 1× | +| A-Mem | ~115 kJ | ~28× | +| MIRIX | ~197 kJ | ~47× | + +> "The spread across agent memory systems exceeds 47×." +> — Omri et al., arXiv:2606.06448 (confidence: **high**) + +⚠️ **Correction to a widely-shared summary.** A popular thread describing this +paper states that *"two systems with identical accuracy split by 47 times."* +That is not what the paper reports. The 47× is the **spread across the ten +evaluated systems** (BM25 baseline vs. MIRIX), and A-Mem/MIRIX are described as +a "28–47× premium" — not a pair matched on accuracy. The directional lesson +survives intact and is still the right one: *quote quality and cost together, +always.* But do not cite the 47× as an accuracy-matched comparison. + +## 3. The four paradigm families + +The paper's taxonomy classifies systems along four axes — **construction, +storage, retrieval, and mutability** — yielding four families: + +| Paradigm | Family | Evaluated systems | +|---|---|---| +| I | Long-context memory | `long_context` | +| II | Flat RAG memory | BM25, EmbedRAG | +| III | Structure-augmented RAG | GraphRAG, HippoRAG v2, Mem0, SimpleMem | +| IV | Agentic control flow | Letta, MIRIX, A-Mem | + +(confidence: **high** — taxonomy and system list quoted directly) + +**No family wins on all three of construction time, query latency, and +accuracy.** The paper is explicit that "no single system is therefore best on +all three axes." This is why `memory_architecture_picker.py` never returns a +"best" — it returns the family that fits your constraints and names the cost +that choice makes you pay. + +## 4. Footprint grows monotonically, because nothing forgets + +> "At 1M tokens, footprint varies by up to 9× across systems... None of the +> evaluated systems prune or forget by default, so footprint grows +> monotonically under default behavior." +> — Omri et al., arXiv:2606.06448 (confidence: **high**) + +Two lessons, in order of importance: + +1. **Forgetting is not a feature any of these systems gives you.** If you did + not build it, you do not have it. This is the entire justification for + `forgetting_policy_linter.py` treating a missing forgetting rule as a + blocking failure rather than a warning. +2. **Judge growth slope, not baseline footprint.** A store that starts small + with a steep slope bankrupts you later than one that starts large and flat — + but it still bankrupts you, and it does so after you have built on it. + +## 5. The ten system recommendations + +Paraphrased from the paper (confidence: **high** on existence and substance, +**moderate** on exact wording): + +1. Treat system selection as a systems-level decision, beyond accuracy. +2. Account for energy across the full agent lifecycle. +3. Treat construction as background throughput with admission control. +4. Exploit reuse across overlapping inputs. +5. Treat the minimum viable construction LLM as an algorithm-imposed cost floor. +6. Match the cost split to the workload's query arrival pattern. +7. Treat construction time as a hard feasibility constraint for inter-session + workloads. +8. Make construction cadence system-aware. +9. Evaluate both baseline footprint and cost growth slope. +10. Treat worst-case latency as a selection criterion; LLM-bounded systems need + caps. + +Recommendations 3, 6, 9 and 10 are the ones this skill's tools enforce +mechanically. + +## 6. Amortization: the question behind recommendation 4 + +A constructed record has to be read enough times to justify what it cost to +write. If your agent writes 400 records a day and serves 1,200 queries, each +record serves 3 queries on average — you are paying to remember things nobody +asks about. + +`memory_cost_profiler.py` flags this below 10 queries per record. The floor is +a heuristic chosen for this skill, not a number from the paper (confidence: +**low** on the specific threshold, **high** on the principle). + +The fix is usually *lazy construction*: build the memory record on second +access rather than eagerly at the end of every session. + +--- + +## Sources + +1. Omri, Y., Gan, Z., Broveak, Z., Geens, R., He, Z., Pentland, A., Verhelst, + M., Weissman, T., Tambe, T. — *Agent Memory: Characterization and System + Implications of Stateful Long-Horizon Workloads*, arXiv:2606.06448 (2026). + — the primary source for §1–§5. +2. MemoryAgentBench — the benchmark suite used for the characterization, + evaluating accurate retrieval, test-time learning, long-range understanding, + and selective forgetting. +3. Robertson, S. & Zaragoza, H. — *The Probabilistic Relevance Framework: BM25 + and Beyond* (2009). Establishes the lexical baseline that turns out to be + the energy-efficiency floor in the Stanford run. +4. Kwon, W. et al. — *Efficient Memory Management for Large Language Model + Serving with PagedAttention* (vLLM), SOSP 2023. The serving substrate the + hardware findings sit on. +5. Chase, H. et al. — Mem0 / LangMem / Letta system documentation. Primary + sources for the Paradigm III and IV systems named above. +6. Gao, Y. et al. — *Retrieval-Augmented Generation for Large Language Models: + A Survey*, arXiv:2312.10997. Background for the Paradigm II family. +7. Anthropic — *Effective context engineering for AI agents* (2025). + Practitioner framing of context as a finite, priced resource. + +## Related tools in this skill + +- `memory_cost_profiler.py` — §1, §2, §6 +- `memory_architecture_picker.py` — §3 +- `forgetting_policy_linter.py` — §4 (checks F1 and F8) diff --git a/engineering/memory-engineering/skills/memory-engineering/references/what_to_keep.md b/engineering/memory-engineering/skills/memory-engineering/references/what_to_keep.md new file mode 100644 index 00000000..b3ca0f8a --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/references/what_to_keep.md @@ -0,0 +1,159 @@ +# What To Keep — facts and skills, not logs + +> The Microsoft lens: *what is worth keeping?* +> +> Every figure is attributed with a confidence level. + +--- + +## 1. More memory can make an agent worse + +The uncomfortable premise of Microsoft Research's **PlugMem**: giving an agent +more raw memory does not monotonically help it. History piles up, retrieval +drowns in near-misses, and the agent burns attention wading through transcripts +for the one line that mattered. + +> PlugMem "distinguishes between remembering events, knowing facts, and knowing +> how to perform tasks, with effective decisions relying on the facts and skills +> extracted from those events." +> — Microsoft Research, *PlugMem: A Task-Agnostic Plugin Memory Module for LLM +> Agents* (confidence: **high**) + +The structure borrowed here is the classic memory taxonomy from cognitive +psychology — Tulving's split between **episodic** memory (what happened) and +**semantic** memory (what is true), with **procedural** memory (how to do it) as +the third leg. Humans do not replay episodes to make decisions; we act on the +semantic and procedural residue we distilled from them. + +**The engineering translation:** your write path's job is *extraction*, not +*archival*. If your memory system stores what happened, you built a log with a +vector index on it. + +## 2. Density is the metric, not volume + +> PlugMem "enables agents to achieve better results while using significantly +> fewer memory tokens, with efficiency measured by the utility of the +> information delivered relative to the context consumed," reporting "consistent +> gains over generic retrieval and task-specific memory designs across three +> benchmarks while consuming less of the agent's context window." +> — Microsoft Research (confidence: **high** on the directional claim; +> **moderate** on magnitude, as per-benchmark numbers vary) + +So the metric to optimize is: + +``` +decision-relevant information delivered +─────────────────────────────────────── + tokens of context it costs +``` + +Not "how many records did we store." `memory_density_auditor.py` approximates +the numerator by counting FACT and SKILL records, and the denominator by +estimated tokens. + +⚠️ **A note on a related claim.** A widely-shared summary states PlugMem "cuts +context by up to 100×." Microsoft's own materials describe consistent gains at +lower context cost without foregrounding that multiple. Treat any specific +compression multiple as **low confidence** unless you read it in the paper's +results table for your own workload shape. + +## 3. Memento — the model manages its own context + +Microsoft's **MEMENTO** pushes context management inside the model rather than +bolting orchestration around it. The model learns to segment its reasoning into +blocks, compress each block into a dense "memento" summary, drop the full block +from context, and reason forward attending only to the mementos. + +Measured results (confidence: **high** — reported in the paper): + +| Metric | Result | +|---|---| +| Memento size target | 15–25% of original block tokens | +| Peak KV cache | ~2.5× reduction (paper reports 2–3× peak memory) | +| Throughput (vLLM) | ~1.75× improvement | +| Training data | OpenMementos — 228K reasoning traces | + +Two things a memory engineer should take from it: + +**First, this is a learned skill, not an orchestration layer.** It comes from +ordinary fine-tuning on segmented traces. You cannot get it by wrapping a model +in a summarizer loop. + +**Second — and this is the subtle one — forgetting is not deletion.** + +> "Information from each reasoning block is carried both by the memento text +> and by corresponding KV states, which retain implicit information from the +> original block — removing this channel drops accuracy by 15 percentage points +> on AIME24." +> — *MEMENTO: Teaching LLMs to Manage Their Own Context*, arXiv:2604.09852 +> (confidence: **high**) + +A shadow of the erased reasoning survives in the KV states. Rebuilding context +from the summary text *alone* costs 15 points. The lesson generalizes beyond +Memento: **a summary is not equivalent to what it summarizes**, and any +architecture that assumes "we distilled it, so we can drop the original" should +measure that assumption rather than trust it. + +## 4. The three record types, and how to tell them apart + +`memory_density_auditor.py` classifies every record into one of four buckets. +The classification is lexical and deliberately conservative. + +| Type | What it is | Signal | Keep? | +|---|---|---|---| +| **FACT** | A declarative truth about the world | `X is Y`, `key: value`, versions, owners, endpoints | Yes — this is semantic memory | +| **SKILL** | A procedure or a rule | numbered steps, `always/never`, `to X, do Y` | Yes — this is procedural memory | +| **LOG** | A record of an event | speaker turns, timestamps, first-person past tense | Extract from it, then drop it | +| **PROSE** | Narrative with no signal either way | none of the above | Distill or move to docs | + +**Why PROSE exists as a category.** An earlier version of this classifier +labeled every signal-less block as LOG, which fired the log-heavy finding on any +prose-shaped documentation store — a false positive severe enough to make the +tool untrustworthy. Narrative documentation is neither an event log nor a +retrievable fact; it deserves its own verdict and its own fix (distill it, or +move it out of the memory store). + +**Why LOG wins ties.** Mistaking an event for knowledge is the costly direction +of error. A false LOG label costs you a review; a false FACT label puts a +transcript into the retrieval path forever. + +## 5. What this means for your write path + +Ordered by leverage: + +1. **Extract at write time, not read time.** The whole point of paying for + construction is that the thinking already happened when the query arrives. +2. **Store the conclusion with its provenance, not the conversation.** "Billing + is owned by the payments team (source: 2026-03 handover doc)" beats the + thread where that was worked out. +3. **Write the fact so it can go stale detectably.** "Postgres 14 as of + 2026-03" beats "currently on Postgres." Time-relative wording rots silently; + `memory_density_auditor.py` flags it as `VOLATILE_WORDING`. +4. **Prefer one dense record to five thin ones.** Consolidation is check F3 in + the forgetting linter for exactly this reason. + +--- + +## Sources + +1. Microsoft Research — *PlugMem: A Task-Agnostic Plugin Memory Module for LLM + Agents*. + +2. Microsoft Research Blog — *From raw interaction to reusable knowledge: + rethinking memory for AI agents*. + +3. Kontonis, V. et al. — *MEMENTO: Teaching LLMs to Manage Their Own Context*, + arXiv:2604.09852. +4. `microsoft/OpenMementos` — the 228K-trace public dataset released with + MEMENTO. +5. Tulving, E. — *Episodic and Semantic Memory* (1972), and *Elements of + Episodic Memory* (1983). The episodic/semantic distinction PlugMem borrows. +6. Anderson, J. R. — *ACT-R* and the declarative/procedural memory split. + Source of the fact-versus-skill distinction used in the classifier. +7. Anthropic — *Effective context engineering for AI agents* (2025). The + context-as-finite-budget framing behind the density metric. + +## Related tools in this skill + +- `memory_density_auditor.py` — §2, §4 +- `forgetting_policy_linter.py` — §5 (checks F2 dedup, F3 consolidation) diff --git a/engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py b/engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py new file mode 100644 index 00000000..ba8e1f09 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py @@ -0,0 +1,420 @@ +#!/usr/bin/env python3 +"""Refuse a memory design that has no forgetting policy. + +This is the gate. Everything else in this skill measures a memory system; this +one blocks it. + +Stanford's characterization found that none of the ten evaluated memory systems +prunes or forgets by default, so footprint grows monotonically -- and at 1M +tokens, footprint already varies by up to 9x across systems. Growth slope, not +starting size, is what bankrupts a long-lived agent. + +Two rules are non-negotiable, and either one failing fails the whole design: + + F1 an explicit forgetting rule must exist (TTL, capacity bound, or decay) + F4 contradictions must be SURFACED to a human, never auto-merged + +F4 is not fussiness. Two memories that disagree may both have been true in +different contexts. A system that silently merges them destroys the only +evidence that the conflict existed. + +The remaining checks (F2, F3, F5-F8) degrade the verdict to CONDITIONAL rather +than failing it. + +Deterministic policy audit. No LLM calls, no network, stdlib only. + +Exit codes: + 0 PASS -- forgetting is designed + 2 CONDITIONAL -- forgetting exists but the controls around it are thin + 3 invalid input + 4 FAIL -- no forgetting rule, or contradictions are auto-merged +""" + +import argparse +import json +import sys + +# Recognized `forgetting.rule` values. Anything outside this set is treated as +# no rule at all -- see _check_forgetting_rule. +KNOWN_FORGETTING_RULES = {"ttl", "capacity", "decay", "none", "never", ""} + +VALID_CONTRADICTION_POLICIES = {"surface", "surface_to_human", "flag", "escalate"} +AUTO_MERGE_POLICIES = {"auto_merge", "newest_wins", "overwrite", "last_write_wins"} + +SAMPLE_POLICY = { + "name": "support-agent memory store", + "forgetting": { + "rule": "ttl", + "ttl_days": 365, + "max_records": 50000, + "decay": "none", + }, + "dedup_on_write": True, + "consolidation": {"enabled": True, "cadence": "weekly"}, + "contradiction_policy": "surface", + "scope": {"read": ["support-agents"], "write": ["memory-writer-service"]}, + "audit_trail": {"timestamp": True, "source_attribution": True}, + "rollback": {"supported": True, "delete_path": "api"}, + "growth_monitoring": {"tracks_slope": False, "baseline_only": True}, +} + +FAILING_SAMPLE = { + "name": "naive vector store (the default everyone ships)", + "forgetting": {"rule": "none"}, + "dedup_on_write": False, + "consolidation": {"enabled": False}, + "contradiction_policy": "newest_wins", + "scope": {}, + "audit_trail": {}, + "rollback": {"supported": False}, + "growth_monitoring": {}, +} + + +def _fail(message: str) -> None: + print(f"error: {message}", file=sys.stderr) + raise SystemExit(3) + + +def _check_forgetting_rule(policy: dict) -> dict: + """F1 -- pass only on a concrete, named forgetting mechanism. + + This check is allowlist-based on purpose. An earlier version failed only + when `rule` was literally "none"/""/"never" and inferred PASS from what the + rule was *not*, so a typo ("asdf") or a declared-but-unconfigured rule + ("ttl" with ttl_days omitted) fell through to PASS with an empty mechanism + list -- the blocking gate this whole skill is built around, defeated by a + misspelling. PASS is now unreachable unless a mechanism is actually found. + """ + forgetting = policy.get("forgetting") or {} + if not isinstance(forgetting, dict): + _fail("'forgetting' must be an object") + + rule = str(forgetting.get("rule", "none")).lower().strip() + + ttl_days = forgetting.get("ttl_days") + has_ttl = isinstance(ttl_days, (int, float)) and not isinstance( + ttl_days, bool + ) and ttl_days > 0 + + capacity = forgetting.get("max_records") or forgetting.get("max_bytes") + has_capacity = isinstance(capacity, (int, float)) and not isinstance( + capacity, bool + ) and capacity > 0 + + decay = str(forgetting.get("decay", "none")).lower().strip() + has_decay = rule == "decay" or decay not in {"none", ""} + + mechanisms = [] + if has_ttl: + mechanisms.append(f"TTL {ttl_days}d") + if has_capacity: + mechanisms.append(f"capacity bound ({capacity})") + if has_decay: + mechanisms.append("relevance decay") + + if mechanisms: + return { + "id": "F1", + "name": "explicit forgetting rule", + "status": "PASS", + "blocking": True, + "detail": "Forgetting is designed: " + ", ".join(mechanisms) + ".", + "fix": None, + } + + # No mechanism found. Say precisely why, so a typo is not mistaken for a + # deliberate "we decided not to forget". + if rule not in KNOWN_FORGETTING_RULES: + detail = ( + f"Unrecognized forgetting rule {rule!r}. Recognized values are " + f"{sorted(KNOWN_FORGETTING_RULES)}. An unrecognized rule is treated " + "as no rule -- a misspelling must never read as a policy." + ) + elif rule in {"ttl", "capacity", "decay"}: + detail = ( + f"Rule is declared as {rule!r} but carries no usable parameter " + "(ttl_days > 0, max_records/max_bytes > 0, or a decay setting). " + "A declared rule with nothing configured forgets exactly as much " + "as no rule at all." + ) + else: + detail = ( + "No TTL, no capacity bound, no decay. The store only grows. This " + "is the default behaviour of every system Stanford evaluated, and " + "it is the one thing that makes a long-lived agent unaffordable." + ) + + return { + "id": "F1", + "name": "explicit forgetting rule", + "status": "FAIL", + "blocking": True, + "detail": detail, + "fix": ( + "Pick one before the store gets big: a TTL (ttl_days), a hard " + "record/byte cap with an eviction order, or a relevance decay that " + "expires unreferenced records." + ), + } + + +def _check_contradictions(policy: dict) -> dict: + raw = str(policy.get("contradiction_policy", "")).lower().strip() + if raw in AUTO_MERGE_POLICIES: + return { + "id": "F4", + "name": "contradictions surfaced, never auto-merged", + "status": "FAIL", + "blocking": True, + "detail": ( + f"Contradiction policy is '{raw}', which resolves conflicts " + "silently. Two memories that disagree may both have been true " + "in different contexts; auto-merging destroys the evidence " + "that the conflict existed." + ), + "fix": ( + "Change the policy to surface the conflict to a human with " + "both versions and their sources. The system surfaces, the " + "human decides." + ), + } + if raw not in VALID_CONTRADICTION_POLICIES: + return { + "id": "F4", + "name": "contradictions surfaced, never auto-merged", + "status": "FAIL", + "blocking": True, + "detail": ( + f"No contradiction policy declared (got '{raw or 'nothing'}'). " + "Undeclared means whatever the storage layer does by default, " + "which is almost always last-write-wins." + ), + "fix": ( + "Declare 'contradiction_policy': 'surface' and build the " + "surfacing path before the store holds conflicting facts." + ), + } + return { + "id": "F4", + "name": "contradictions surfaced, never auto-merged", + "status": "PASS", + "blocking": True, + "detail": f"Contradiction policy is '{raw}' -- a human resolves conflicts.", + "fix": None, + } + + +def _simple_check( + check_id: str, name: str, ok: bool, detail_ok: str, detail_bad: str, fix: str +) -> dict: + return { + "id": check_id, + "name": name, + "status": "PASS" if ok else "WARN", + "blocking": False, + "detail": detail_ok if ok else detail_bad, + "fix": None if ok else fix, + } + + +def lint(policy: dict) -> dict: + if not isinstance(policy, dict): + _fail("policy must be a JSON object") + + scope = policy.get("scope") or {} + audit = policy.get("audit_trail") or {} + rollback = policy.get("rollback") or {} + consolidation = policy.get("consolidation") or {} + growth = policy.get("growth_monitoring") or {} + + checks = [ + _check_forgetting_rule(policy), + _simple_check( + "F2", + "dedup at write time", + bool(policy.get("dedup_on_write")), + "Duplicates are collapsed on the way in.", + "No write-time dedup. Duplicates let a stale copy outrank a corrected one.", + "Hash or fingerprint each record at write and collapse near-matches.", + ), + _simple_check( + "F3", + "consolidation / compaction", + bool(consolidation.get("enabled")), + f"Consolidation runs ({consolidation.get('cadence', 'cadence unspecified')}).", + "Nothing compacts many small records into fewer dense ones.", + "Schedule a consolidation pass that merges related records into one denser record.", + ), + _check_contradictions(policy), + _simple_check( + "F5", + "read and write scope", + bool(scope.get("read")) and bool(scope.get("write")), + "Read and write scopes are both named.", + "Read scope, write scope, or both are undeclared -- anything can write anything.", + "Name who may read and who may write. An org-wide store should usually be read-only.", + ), + _simple_check( + "F6", + "audit trail", + bool(audit.get("timestamp")) and bool(audit.get("source_attribution")), + "Every write carries a timestamp and a source.", + "Writes are not fully attributed, so a wrong memory cannot be traced to its origin.", + "Record timestamp plus source attribution on every write.", + ), + _simple_check( + "F7", + "rollback and delete path", + bool(rollback.get("supported")), + "Earlier versions can be restored and records can be deleted.", + "No rollback. A wrong memory persists into every future session that reads it.", + "Add a restore path and a hard-delete path you can invoke without a migration.", + ), + _simple_check( + "F8", + "growth-slope monitoring", + bool(growth.get("tracks_slope")), + "Growth slope is tracked, not just current size.", + "Only baseline size is watched. Slope, not starting size, is what bankrupts the store.", + "Track footprint over time and alert on the slope, per Stanford recommendation 9.", + ), + ] + + blocking_failures = [c for c in checks if c["blocking"] and c["status"] == "FAIL"] + warnings = [c for c in checks if c["status"] == "WARN"] + + if blocking_failures: + verdict = "FAIL" + exit_code = 4 + summary = ( + "This design does not forget on purpose. " + + " ".join(f"{c['id']} failed." for c in blocking_failures) + ) + elif warnings: + verdict = "CONDITIONAL" + exit_code = 2 + summary = ( + f"Forgetting is designed, but {len(warnings)} control" + f"{'s are' if len(warnings) != 1 else ' is'} missing around it." + ) + else: + verdict = "PASS" + exit_code = 0 + summary = "Forgetting is designed and the controls around it are in place." + + return { + "name": policy.get("name", "unnamed memory design"), + "verdict": verdict, + "exit_code": exit_code, + "summary": summary, + "passed": sum(1 for c in checks if c["status"] == "PASS"), + "total": len(checks), + "checks": checks, + } + + +def render(report: dict) -> str: + lines = [] + lines.append(f"FORGETTING POLICY LINT - {report['name']}") + lines.append("=" * 68) + lines.append(f"VERDICT: {report['verdict']} ({report['passed']}/{report['total']} checks pass)") + lines.append(f"{report['summary']}") + lines.append("") + + for check in report["checks"]: + blocking = " [BLOCKING]" if check["blocking"] else "" + lines.append( + f" {check['status']} {check['id']} {check['name']}{blocking}" + ) + lines.append(f" {check['detail']}") + if check["fix"]: + lines.append(f" -> {check['fix']}") + lines.append("") + + if report["verdict"] == "FAIL": + lines.append( + "Blocked. A storer optimizes what a system remembers; a memory\n" + "engineer optimizes what it forgets. Fix the blocking checks before\n" + "this design goes near real volume." + ) + return "\n".join(lines) + + +def main() -> int: + parser = argparse.ArgumentParser( + description=( + "Audit a memory design against eight forgetting-policy checks. " + "Fails the design if it has no forgetting rule or auto-merges " + "contradictions." + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=( + "Examples:\n" + " forgetting_policy_linter.py --sample\n" + " forgetting_policy_linter.py --sample-failing\n" + " forgetting_policy_linter.py --policy design.json --output json\n" + ), + ) + # Not required=True: argparse enforces a required group during + # parse_args(), which made --print-sample-spec unreachable on its own. + # Validated explicitly after the print-and-exit branch instead. + source = parser.add_mutually_exclusive_group(required=False) + source.add_argument("--policy", help="path to a memory design policy JSON file") + source.add_argument( + "--sample", + action="store_true", + help="lint the built-in passing sample policy", + ) + source.add_argument( + "--sample-failing", + action="store_true", + help="lint a policy with no forgetting rule (shows what the gate blocks)", + ) + parser.add_argument( + "--output", + choices=["text", "json"], + default="text", + help="output format (default: text)", + ) + parser.add_argument( + "--print-sample-spec", + action="store_true", + help="print the sample policy JSON and exit (use as a template)", + ) + args = parser.parse_args() + + if args.print_sample_spec: + print(json.dumps(SAMPLE_POLICY, indent=2)) + return 0 + + if not (args.policy or args.sample or args.sample_failing): + parser.error( + "one of --policy, --sample, --sample-failing, or --print-sample-spec is required" + ) + + if args.sample: + policy = SAMPLE_POLICY + elif args.sample_failing: + policy = FAILING_SAMPLE + else: + try: + with open(args.policy, "r", encoding="utf-8") as handle: + policy = json.load(handle) + except FileNotFoundError: + _fail(f"policy file not found: {args.policy}") + except json.JSONDecodeError as exc: + _fail(f"policy file is not valid JSON: {exc}") + + report = lint(policy) + + if args.output == "json": + print(json.dumps(report, indent=2)) + else: + print(render(report)) + + return report["exit_code"] + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/engineering/memory-engineering/skills/memory-engineering/scripts/memory_architecture_picker.py b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_architecture_picker.py new file mode 100644 index 00000000..b4e6c701 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_architecture_picker.py @@ -0,0 +1,412 @@ +#!/usr/bin/env python3 +"""Pick which memory cost to pay on purpose -- there is no best system. + +The Stanford characterization (arXiv:2606.06448) evaluated ten memory systems +across four paradigm families and found no single system wins on construction +time, query latency, and accuracy at once. So this tool never returns "best". +It returns the family that fits the stated constraints and names, explicitly, +the cost that choice makes you pay. + +The four families, and the taxonomy axes they are scored on (construction, +storage, retrieval, mutability): + + long_context Paradigm I -- keep raw history in the window + flat_rag Paradigm II -- BM25 / embedding retrieval over chunks + structured_rag Paradigm III -- GraphRAG / Mem0-style extraction + agentic Paradigm IV -- Letta / MIRIX-style agentic control flow + +When the top two families score within AMBIGUITY_MARGIN of each other, the tool +refuses to pick and names the one question that would break the tie. + +Deterministic scoring only. No LLM calls, no network, stdlib only. + +Exit codes: + 0 a single family fits the constraints + 2 ambiguous -- two families tie; a tie-breaking question is printed + 3 invalid input + 4 no family satisfies a hard constraint +""" + +import argparse +import json +import sys + +AMBIGUITY_MARGIN = 0.06 + +# Per-family profile. Scores are 0-1 where higher is better on that axis. +# Values encode the qualitative ordering reported in the Stanford +# characterization, not measurements from any one deployment. +FAMILIES = { + "long_context": { + "label": "Paradigm I - Long-context memory", + "examples": "raw history in the context window", + "build_cheapness": 1.00, # no construction at all + "query_speed": 0.25, # quadratic attention over the whole history + "recall_quality": 0.55, # strong within window, cliff-edge outside it + "scales_with_volume": 0.10, # hard context ceiling + "mutability": 0.20, # cannot selectively update or delete + "cost_you_pay": ( + "Query latency and a hard ceiling. Cheap to build because there is " + "no write path, but cost grows quadratically with history and " + "prefix caching collapses across sessions." + ), + "kills_it": "history that outgrows the context window", + }, + "flat_rag": { + "label": "Paradigm II - Flat RAG memory", + "examples": "BM25, EmbedRAG", + "build_cheapness": 0.85, # indexing only, no LLM in the write path + "query_speed": 0.80, + "recall_quality": 0.55, # blunt: no relation between chunks + "scales_with_volume": 0.85, + "mutability": 0.75, # re-index a document, but no fact-level edit + "cost_you_pay": ( + "Precision. Builds almost instantly and stays cheap, but retrieval " + "is blunt -- it returns chunks that mention the topic, not the " + "fact that answers the question." + ), + "kills_it": "questions whose answer spans several documents", + }, + "structured_rag": { + "label": "Paradigm III - Structure-augmented RAG", + "examples": "GraphRAG, Mem0, HippoRAG v2", + "build_cheapness": 0.25, # LLM-mediated extraction on every write + "query_speed": 0.90, # small, pre-distilled payload at query time + "recall_quality": 0.85, + "scales_with_volume": 0.70, + "mutability": 0.80, # fact-level update and delete + "cost_you_pay": ( + "Construction. Answers fast because the thinking already happened " + "at write time -- which is exactly why the write path can cost " + "more than every query it will ever serve." + ), + "kills_it": "a write budget that cannot absorb an LLM call per record", + }, + "agentic": { + "label": "Paradigm IV - Agentic control flow", + "examples": "Letta, MIRIX, A-Mem", + "build_cheapness": 0.10, # multi-step agent loop per write + "query_speed": 0.45, # unbounded LLM-mediated retrieval loop + "recall_quality": 0.90, + "scales_with_volume": 0.45, # footprint compounds as the store grows + "mutability": 0.95, # the agent can rewrite its own memory + "cost_you_pay": ( + "Everything except recall. Highest energy per correct answer in " + "the Stanford run, worst-case query latency is unbounded without " + "an explicit cap, and footprint compounds as the store grows." + ), + "kills_it": "a hard p99 latency SLO, or an unbounded footprint budget", + }, +} + +# Which constraint drives which axis, and how heavily. +WEIGHTS = { + "query_latency_sensitivity": ("query_speed", 0.28), + "build_budget_pressure": ("build_cheapness", 0.26), + "recall_need": ("recall_quality", 0.24), + "volume_growth": ("scales_with_volume", 0.12), + "mutability_need": ("mutability", 0.10), +} + +LEVELS = {"low": 0.15, "medium": 0.5, "high": 1.0} + +# Keyed by the two tied families. Lookup normalizes the pair with sorted(), so +# these keys are normalized too -- see the guard below. Authored in whatever +# order reads naturally; order is not significant. +_TIE_BREAKERS_RAW = { + ("flat_rag", "structured_rag"): ( + "Does a correct answer usually require joining facts that live in " + "different sessions? If yes, pay for structured extraction. If a single " + "well-retrieved chunk normally answers it, stay flat." + ), + ("structured_rag", "agentic"): ( + "Does your memory need to correct itself without a human in the loop? " + "If yes, go agentic and cap its retrieval loop. If a human reviews " + "corrections, structured extraction is cheaper for the same recall." + ), + ("long_context", "flat_rag"): ( + "Will the history exceed the context window within your planning " + "horizon? If yes, build the retrieval path now -- migrating later costs " + "a full re-index. If not, raw context is free." + ), + ("long_context", "structured_rag"): ( + "Is the value in the raw transcript or in the facts extracted from it? " + "If a human would summarize before reusing it, extract at write time." + ), +} + +# Normalize every key to its sorted form, because the lookup below sorts the +# tied pair. Without this, a key authored in the other order is unreachable and +# the tool silently falls back to the generic question -- no error, just a worse +# answer. This repo has no test suite, so the collision check runs at import. +TIE_BREAKERS = {} +for _pair, _question in _TIE_BREAKERS_RAW.items(): + _key = tuple(sorted(_pair)) + if _key in TIE_BREAKERS: + raise AssertionError( + f"duplicate tie-breaker for {_key} after normalization -- two " + "entries describe the same family pair" + ) + TIE_BREAKERS[_key] = _question +del _pair, _question, _key + +SAMPLE_CONSTRAINTS = { + "name": "customer-support agent, 18-month retention", + "query_latency_sensitivity": "high", + "build_budget_pressure": "medium", + "recall_need": "high", + "volume_growth": "high", + "mutability_need": "medium", + "hard_constraints": { + "max_p99_query_ms": 1500, + "context_window_tokens": 200000, + "expected_history_tokens": 4000000, + }, +} + + +def _fail(message: str) -> None: + print(f"error: {message}", file=sys.stderr) + raise SystemExit(3) + + +def _level(constraints: dict, key: str) -> float: + raw = constraints.get(key, "medium") + if isinstance(raw, (int, float)) and not isinstance(raw, bool): + value = float(raw) + if not 0.0 <= value <= 1.0: + _fail(f"'{key}' as a number must be in [0, 1], got {value}") + return value + if not isinstance(raw, str) or raw.lower() not in LEVELS: + _fail(f"'{key}' must be one of {sorted(LEVELS)} or a number in [0, 1]") + return LEVELS[raw.lower()] + + +def _hard_constraint_kills(family, hard): + """Return a disqualifying reason, or None if the family survives.""" + window = hard.get("context_window_tokens") + history = hard.get("expected_history_tokens") + if family == "long_context" and window and history and history > window: + return ( + f"expected history ({history:,} tokens) exceeds the context window " + f"({window:,} tokens) -- raw context cannot hold it" + ) + + p99 = hard.get("max_p99_query_ms") + if family == "agentic" and p99 and p99 < 3000: + return ( + f"p99 budget of {p99} ms cannot absorb an uncapped agentic " + "retrieval loop" + ) + if family == "long_context" and p99 and p99 < 1000: + return ( + f"p99 budget of {p99} ms cannot absorb quadratic attention over " + "full history" + ) + return None + + +def pick(constraints: dict) -> dict: + if not isinstance(constraints, dict): + _fail("constraints must be a JSON object") + + hard = constraints.get("hard_constraints", {}) + if not isinstance(hard, dict): + _fail("'hard_constraints' must be an object") + + levels = {key: _level(constraints, key) for key in WEIGHTS} + + scored = [] + disqualified = [] + for name, profile in FAMILIES.items(): + reason = _hard_constraint_kills(name, hard) + if reason: + disqualified.append( + {"family": name, "label": profile["label"], "reason": reason} + ) + continue + score = 0.0 + breakdown = {} + for constraint_key, (axis, weight) in WEIGHTS.items(): + contribution = levels[constraint_key] * weight * profile[axis] + breakdown[axis] = round(contribution, 4) + score += contribution + scored.append( + { + "family": name, + "label": profile["label"], + "examples": profile["examples"], + "score": round(score, 4), + "breakdown": breakdown, + "cost_you_pay": profile["cost_you_pay"], + "kills_it": profile["kills_it"], + } + ) + + if not scored: + return { + "name": constraints.get("name", "unnamed workload"), + "verdict": "NO-VIABLE-FAMILY", + "ranked": [], + "disqualified": disqualified, + "recommendation": None, + "tie_breaker": None, + } + + scored.sort(key=lambda item: item["score"], reverse=True) + winner = scored[0] + + tie_breaker = None + verdict = "RECOMMENDED" + if len(scored) > 1: + runner_up = scored[1] + gap = winner["score"] - runner_up["score"] + if gap < AMBIGUITY_MARGIN: + verdict = "AMBIGUOUS" + pair = tuple(sorted([winner["family"], runner_up["family"]])) + tie_breaker = { + "between": [winner["label"], runner_up["label"]], + "gap": round(gap, 4), + "question": TIE_BREAKERS.get( + pair, + "Which cost hurts you more in production: a slow write path " + "or a blunt retrieval result? Answer that and the choice " + "resolves.", + ), + } + + return { + "name": constraints.get("name", "unnamed workload"), + "verdict": verdict, + "ranked": scored, + "disqualified": disqualified, + "recommendation": None if verdict == "AMBIGUOUS" else winner, + "tie_breaker": tie_breaker, + } + + +def render(result: dict) -> str: + lines = [] + lines.append(f"MEMORY ARCHITECTURE - {result['name']}") + lines.append("=" * 68) + lines.append(f"VERDICT: {result['verdict']}") + lines.append("") + + if result["verdict"] == "NO-VIABLE-FAMILY": + lines.append("Every family was disqualified by a hard constraint.") + lines.append("Relax a hard constraint, or split the workload in two.") + lines.append("") + elif result["recommendation"]: + rec = result["recommendation"] + lines.append(f"Use: {rec['label']} ({rec['examples']})") + lines.append("") + lines.append("The cost you are choosing to pay:") + lines.append(f" {rec['cost_you_pay']}") + lines.append("") + lines.append(f"What would kill this choice: {rec['kills_it']}") + lines.append("") + else: + tie = result["tie_breaker"] + lines.append(f"Too close to call ({tie['gap']:.3f} apart):") + for label in tie["between"]: + lines.append(f" - {label}") + lines.append("") + lines.append("Answer this before picking:") + lines.append(f" {tie['question']}") + lines.append("") + + if result["ranked"]: + lines.append("Ranked") + lines.append("-" * 68) + for index, item in enumerate(result["ranked"], start=1): + lines.append(f" {index}. {item['label']:<42} {item['score']:.4f}") + lines.append("") + + if result["disqualified"]: + lines.append("Disqualified by hard constraints") + lines.append("-" * 68) + for item in result["disqualified"]: + lines.append(f" {item['label']}") + lines.append(f" {item['reason']}") + lines.append("") + + lines.append( + "No family wins on build cost, query speed, and accuracy at once.\n" + "This is a choice of which cost to pay, not a ranking of quality." + ) + return "\n".join(lines) + + +def main() -> int: + parser = argparse.ArgumentParser( + description=( + "Recommend an agent memory paradigm from stated constraints, and " + "name the cost that choice makes you pay." + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=( + "Examples:\n" + " memory_architecture_picker.py --sample\n" + " memory_architecture_picker.py --constraints workload.json\n" + " memory_architecture_picker.py --sample --output json\n" + ), + ) + # Not required=True: argparse enforces a required group during + # parse_args(), which made --print-sample-spec unreachable on its own. + # Validated explicitly after the print-and-exit branch instead. + source = parser.add_mutually_exclusive_group(required=False) + source.add_argument("--constraints", help="path to a constraints JSON file") + source.add_argument( + "--sample", + action="store_true", + help="run against the built-in sample constraints", + ) + parser.add_argument( + "--output", + choices=["text", "json"], + default="text", + help="output format (default: text)", + ) + parser.add_argument( + "--print-sample-spec", + action="store_true", + help="print the sample constraints JSON and exit (use as a template)", + ) + args = parser.parse_args() + + if args.print_sample_spec: + print(json.dumps(SAMPLE_CONSTRAINTS, indent=2)) + return 0 + + if not (args.constraints or args.sample): + parser.error( + "one of --constraints, --sample, or --print-sample-spec is required" + ) + + if args.sample: + constraints = SAMPLE_CONSTRAINTS + else: + try: + with open(args.constraints, "r", encoding="utf-8") as handle: + constraints = json.load(handle) + except FileNotFoundError: + _fail(f"constraints file not found: {args.constraints}") + except json.JSONDecodeError as exc: + _fail(f"constraints file is not valid JSON: {exc}") + + result = pick(constraints) + + if args.output == "json": + print(json.dumps(result, indent=2)) + else: + print(render(result)) + + if result["verdict"] == "NO-VIABLE-FAMILY": + return 4 + if result["verdict"] == "AMBIGUOUS": + return 2 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py new file mode 100644 index 00000000..47c6593e --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py @@ -0,0 +1,379 @@ +#!/usr/bin/env python3 +"""Price the write path of an agent memory system, not just the query path. + +The Stanford characterization (arXiv:2606.06448) found that for LLM-mediated +memory systems, construction energy exceeds total query-phase energy across 300 +queries. Everyone watches query latency because the user feels it; the bill is +paid at construction, which the user never sees. + +This tool splits a memory workload into its construction and query phases, +computes cost per *correct* answer (never accuracy alone), and reports the +amortization ratio -- how many queries each constructed record has to serve +before the write that produced it pays for itself. + +Deterministic arithmetic only. No LLM calls, no network, stdlib only. + +Exit codes: + 0 profile produced, no blocking finding + 2 actionable finding (write-path dominant, under-amortized, or + construction co-located with latency-sensitive queries) + 3 invalid input +""" + +import argparse +import json +import sys + +# Cost split beyond which construction is judged to dominate the lifecycle. +WRITE_DOMINANT_SHARE = 0.50 + +# Below this many queries per constructed record, the write path has not been +# amortized (Stanford recommendation 4: exploit reuse; recommendation 6: match +# the cost split to the workload's query arrival pattern). +MIN_AMORTIZATION_QUERIES = 10.0 + +SAMPLE_SPEC = { + "name": "support-agent-memory (structure-augmented RAG)", + "construction": { + "records_per_day": 400, + "prompt_tokens_per_record": 12000, + "output_tokens_per_record": 800, + "embedding_tokens_per_record": 12000, + "colocated_with_queries": True, + }, + "query": { + "queries_per_day": 1200, + "prompt_tokens_per_query": 2400, + "output_tokens_per_query": 300, + "embedding_tokens_per_query": 40, + }, + "pricing_usd_per_mtok": { + "prompt": 3.0, + "output": 15.0, + "embedding": 0.02, + }, + "accuracy": 0.72, +} + + +def _fail(message: str) -> None: + print(f"error: {message}", file=sys.stderr) + raise SystemExit(3) + + +def _number(container: dict, key: str, where: str, *, default=None) -> float: + if key not in container: + if default is not None: + return float(default) + _fail(f"missing required field '{key}' in {where}") + value = container[key] + if isinstance(value, bool) or not isinstance(value, (int, float)): + _fail(f"field '{key}' in {where} must be a number, got {type(value).__name__}") + if value < 0: + _fail(f"field '{key}' in {where} must be >= 0, got {value}") + return float(value) + + +def _phase_cost( + prompt_tokens: float, + output_tokens: float, + embedding_tokens: float, + pricing: dict, +) -> dict: + """Cost of one phase, in USD, broken out by token class.""" + per_mtok = 1_000_000.0 + prompt_cost = prompt_tokens / per_mtok * pricing["prompt"] + output_cost = output_tokens / per_mtok * pricing["output"] + embedding_cost = embedding_tokens / per_mtok * pricing["embedding"] + return { + "prompt_tokens": round(prompt_tokens, 2), + "output_tokens": round(output_tokens, 2), + "embedding_tokens": round(embedding_tokens, 2), + "prompt_usd": round(prompt_cost, 6), + "output_usd": round(output_cost, 6), + "embedding_usd": round(embedding_cost, 6), + "total_usd": round(prompt_cost + output_cost + embedding_cost, 6), + } + + +def profile(spec: dict) -> dict: + if not isinstance(spec, dict): + _fail("spec must be a JSON object") + + construction = spec.get("construction") + query = spec.get("query") + if not isinstance(construction, dict): + _fail("spec must contain a 'construction' object") + if not isinstance(query, dict): + _fail("spec must contain a 'query' object") + + pricing_raw = spec.get("pricing_usd_per_mtok", {}) + if not isinstance(pricing_raw, dict): + _fail("'pricing_usd_per_mtok' must be an object") + pricing = { + "prompt": _number(pricing_raw, "prompt", "pricing_usd_per_mtok", default=3.0), + "output": _number(pricing_raw, "output", "pricing_usd_per_mtok", default=15.0), + "embedding": _number( + pricing_raw, "embedding", "pricing_usd_per_mtok", default=0.02 + ), + } + + records = _number(construction, "records_per_day", "construction") + queries = _number(query, "queries_per_day", "query") + + build = _phase_cost( + records * _number(construction, "prompt_tokens_per_record", "construction"), + records * _number(construction, "output_tokens_per_record", "construction"), + records + * _number( + construction, "embedding_tokens_per_record", "construction", default=0 + ), + pricing, + ) + read = _phase_cost( + queries * _number(query, "prompt_tokens_per_query", "query"), + queries * _number(query, "output_tokens_per_query", "query"), + queries * _number(query, "embedding_tokens_per_query", "query", default=0), + pricing, + ) + + total = build["total_usd"] + read["total_usd"] + build_share = build["total_usd"] / total if total > 0 else 0.0 + + accuracy = spec.get("accuracy") + if accuracy is None: + _fail( + "spec must contain 'accuracy' (0-1). Cost per correct answer is the " + "whole point -- a quality number without a cost number is the " + "measurement this tool exists to refuse." + ) + accuracy = float(accuracy) + if not 0.0 < accuracy <= 1.0: + _fail(f"'accuracy' must be in (0, 1], got {accuracy}") + + cost_per_query = total / queries if queries > 0 else 0.0 + cost_per_correct = cost_per_query / accuracy + amortization = queries / records if records > 0 else float("inf") + colocated = bool(construction.get("colocated_with_queries", False)) + + findings = [] + if build_share > WRITE_DOMINANT_SHARE: + findings.append( + { + "code": "WRITE_PATH_DOMINANT", + "severity": "high", + "detail": ( + f"Construction is {build_share:.0%} of daily spend " + f"(${build['total_usd']:.2f} build vs " + f"${read['total_usd']:.2f} query). The cost you tuned is not " + "the cost you pay." + ), + "action": ( + "Cut construction tokens before touching retrieval: batch " + "writes, dedup before extraction, or drop to a cheaper " + "construction model." + ), + } + ) + if amortization < MIN_AMORTIZATION_QUERIES: + findings.append( + { + "code": "UNDER_AMORTIZED", + "severity": "high", + "detail": ( + f"Each constructed record serves only {amortization:.1f} " + f"queries (floor {MIN_AMORTIZATION_QUERIES:.0f}). You are " + "paying to remember things nobody asks about." + ), + "action": ( + "Write less, or write later: build memory lazily on second " + "access rather than eagerly on every session." + ), + } + ) + if colocated: + findings.append( + { + "code": "CONSTRUCTION_COLOCATED", + "severity": "medium", + "detail": ( + "Construction shares a scheduler with latency-sensitive " + "queries. Construction is prefill-heavy, so a large write " + "stalls exactly the query a user is waiting on." + ), + "action": ( + "Treat construction as a background job with admission " + "control: rate-limit, batch, or defer it off the " + "latency-sensitive path." + ), + } + ) + + # The verdict names the actual dominant problem, so it can never disagree + # with the findings list below it. + codes = {f["code"] for f in findings} + if "WRITE_PATH_DOMINANT" in codes: + verdict = "WRITE-PATH-DOMINANT" + elif "UNDER_AMORTIZED" in codes: + verdict = "UNDER-AMORTIZED" + elif "CONSTRUCTION_COLOCATED" in codes: + verdict = "NEEDS-SCHEDULING-FIX" + elif build_share < 0.15: + verdict = "QUERY-DOMINANT" + else: + verdict = "BALANCED" + + return { + "name": spec.get("name", "unnamed memory system"), + "verdict": verdict, + "daily_cost_usd": { + "construction": build["total_usd"], + "query": read["total_usd"], + "total": round(total, 6), + "construction_share": round(build_share, 4), + }, + "construction_phase": build, + "query_phase": read, + "quality_and_cost": { + "accuracy": accuracy, + "cost_per_query_usd": round(cost_per_query, 6), + "cost_per_correct_answer_usd": round(cost_per_correct, 6), + "note": ( + "Never quote accuracy without cost per correct answer. Two " + "systems at identical accuracy can differ by more than an " + "order of magnitude on this number." + ), + }, + "amortization": { + "queries_per_constructed_record": ( + round(amortization, 2) if amortization != float("inf") else None + ), + "floor": MIN_AMORTIZATION_QUERIES, + }, + "findings": findings, + } + + +def render(report: dict) -> str: + lines = [] + lines.append(f"MEMORY COST PROFILE - {report['name']}") + lines.append("=" * 68) + lines.append(f"VERDICT: {report['verdict']}") + lines.append("") + + cost = report["daily_cost_usd"] + lines.append("Daily cost split") + lines.append("-" * 68) + lines.append( + f" construction ${cost['construction']:>10.2f} " + f"({cost['construction_share']:.0%} of total)" + ) + lines.append( + f" query ${cost['query']:>10.2f} " + f"({1 - cost['construction_share']:.0%} of total)" + ) + lines.append(f" total ${cost['total']:>10.2f}") + lines.append("") + + qc = report["quality_and_cost"] + lines.append("Quality AND cost (never one without the other)") + lines.append("-" * 68) + lines.append(f" accuracy {qc['accuracy']:.1%}") + lines.append(f" cost per query ${qc['cost_per_query_usd']:.6f}") + lines.append( + f" cost per CORRECT answer ${qc['cost_per_correct_answer_usd']:.6f}" + ) + lines.append("") + + amort = report["amortization"] + if amort["queries_per_constructed_record"] is not None: + lines.append( + f"Amortization: {amort['queries_per_constructed_record']} queries per " + f"constructed record (floor {amort['floor']:.0f})" + ) + lines.append("") + + if report["findings"]: + lines.append(f"Findings ({len(report['findings'])})") + lines.append("-" * 68) + for finding in report["findings"]: + lines.append(f" [{finding['severity'].upper()}] {finding['code']}") + lines.append(f" {finding['detail']}") + lines.append(f" -> {finding['action']}") + lines.append("") + else: + lines.append("No blocking findings. Re-run when volume or pricing changes.") + lines.append("") + + return "\n".join(lines) + + +def main() -> int: + parser = argparse.ArgumentParser( + description=( + "Profile the construction (write) and query (read) phases of an " + "agent memory system, and report cost per correct answer." + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=( + "Examples:\n" + " memory_cost_profiler.py --sample\n" + " memory_cost_profiler.py --spec workload.json\n" + " memory_cost_profiler.py --sample --output json\n" + ), + ) + # Not required=True: argparse enforces a required group during + # parse_args(), which made --print-sample-spec unreachable on its own. + # Validated explicitly after the print-and-exit branch instead. + source = parser.add_mutually_exclusive_group(required=False) + source.add_argument("--spec", help="path to a memory workload spec JSON file") + source.add_argument( + "--sample", + action="store_true", + help="profile the built-in sample workload (no input file needed)", + ) + parser.add_argument( + "--output", + choices=["text", "json"], + default="text", + help="output format (default: text)", + ) + parser.add_argument( + "--print-sample-spec", + action="store_true", + help="print the sample spec JSON and exit (use as a template)", + ) + args = parser.parse_args() + + if args.print_sample_spec: + print(json.dumps(SAMPLE_SPEC, indent=2)) + return 0 + + if not (args.spec or args.sample): + parser.error( + "one of --spec, --sample, or --print-sample-spec is required" + ) + + if args.sample: + spec = SAMPLE_SPEC + else: + try: + with open(args.spec, "r", encoding="utf-8") as handle: + spec = json.load(handle) + except FileNotFoundError: + _fail(f"spec file not found: {args.spec}") + except json.JSONDecodeError as exc: + _fail(f"spec file is not valid JSON: {exc}") + + report = profile(spec) + + if args.output == "json": + print(json.dumps(report, indent=2)) + else: + print(render(report)) + + return 2 if report["findings"] else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py new file mode 100644 index 00000000..f99f1b00 --- /dev/null +++ b/engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py @@ -0,0 +1,723 @@ +#!/usr/bin/env python3 +"""Audit what a memory store actually holds: facts, skills, or logs. + +Microsoft's PlugMem starts from a result that should unsettle anyone adding +memory to an agent: giving it more raw memory can make it worse. History piles +up, retrieval drowns, and the agent burns attention wading through transcripts +for the one line that mattered. The fix borrows from human memory -- we do not +replay events, we keep the facts and the skills we pulled out of them. + +This tool classifies every record in a memory store as FACT, SKILL, or LOG, +finds near-duplicates, flags staleness, and scores knowledge density: how much +decision-relevant material there is per 1,000 tokens of context it costs. + +It runs on either shape of memory: + --dir a directory of markdown/text memory files (CLAUDE.md, a wiki vault, + agent memory files) -- records are split on markdown headings + --jsonl a JSONL file of records, one object per line with a "text" field + +Deterministic classification by lexical signal. No LLM calls, no network, +stdlib only. Classification is a triage aid, not ground truth -- it is tuned to +over-report LOG, because storing a log you thought was a fact is the failure +mode this tool exists to catch. + +Exit codes: + 0 store is knowledge-dense + 2 actionable finding (log-heavy, duplicate-bloated, or stale) + 3 invalid input +""" + +import argparse +import json +import os +import re +import sys +from datetime import datetime, timezone + +# Above this share of LOG records, the store is replaying events rather than +# keeping the knowledge extracted from them. +LOG_HEAVY_SHARE = 0.35 + +# Above this share of near-duplicate records, retrieval is competing with itself. +DUPLICATE_SHARE = 0.15 + +# Above this share of signal-less narrative records, the store is documentation +# rather than retrievable memory. +PROSE_HEAVY_SHARE = 0.40 + +# Jaccard similarity over word shingles at which two records are near-duplicates. +DUPLICATE_THRESHOLD = 0.75 + +SHINGLE_SIZE = 3 + +# A heading whose body is shorter than this is a section marker, not a record. +MIN_RECORD_WORDS = 3 + +# Records shorter than this are excluded from duplicate comparison. Two short +# fragments share shingle sets trivially, which produces 1.00 "duplicates" +# between unrelated files. +MIN_DUPLICATE_WORDS = 20 + +# Duplicate detection is O(n^2) pairwise. Above this many eligible records the +# scan is capped -- and the number skipped is reported, never dropped silently. +MAX_DUPLICATE_SCAN = 2000 + +# Records whose newest date is older than this are candidates for review. +DEFAULT_STALE_DAYS = 180 + +TEXT_SUFFIXES = {".md", ".markdown", ".txt", ".mdx"} + +# --- classification signals ------------------------------------------------ + +LOG_PATTERNS = [ + re.compile(r"^\s*(user|assistant|human|ai|system)\s*:", re.IGNORECASE | re.M), + re.compile(r"^\s*\[?\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}", re.M), + re.compile(r"\b(session|conversation|transcript|chat log)\b", re.IGNORECASE), + re.compile( + r"\b(then (?:i|we|the user)|(?:i|we) (?:ran|tried|asked|noticed|said)" + r"|the user (?:said|asked|wanted|reported))\b", + re.IGNORECASE, + ), + re.compile(r"\bon \w+ \d{1,2}(?:st|nd|rd|th)?,? \d{4}\b", re.IGNORECASE), +] + +SKILL_PATTERNS = [ + re.compile(r"^\s*\d+[.)]\s+\S", re.M), # numbered procedure + re.compile( + r"\b(always|never|must|should|prefer|avoid|do not|don't)\b", re.IGNORECASE + ), + re.compile(r"\bto\s+\w+,\s+(?:use|run|call|set|add|check)\b", re.IGNORECASE), + re.compile( + r"^\s*(use|run|call|set|add|check|prefer|avoid|install|configure|deploy)\b", + re.IGNORECASE | re.M, + ), + re.compile(r"\b(workflow|procedure|steps?|recipe|playbook|how to)\b", re.IGNORECASE), +] + +FACT_PATTERNS = [ + re.compile( + r"\b\w+\s+(?:is|are|was|were|uses|runs on|lives in|owns|has|equals)\s+\S", + re.IGNORECASE, + ), + re.compile(r"^\s*[-*]\s*\*?\*?[\w ./-]+\*?\*?\s*[:=]\s*\S", re.M), # key: value + re.compile(r"\b(version|endpoint|port|repo|owner|deadline|budget)\b", re.IGNORECASE), +] + +# Phrases whose truth depends on when they were written. +VOLATILE_PATTERNS = [ + re.compile( + r"\b(currently|right now|at the moment|as of (?:today|now)|this (?:week|month|quarter|sprint)" + r"|for now|temporarily|at present|these days|nowadays)\b", + re.IGNORECASE, + ), + re.compile(r"\b(latest|newest|most recent|upcoming|soon|next release)\b", re.IGNORECASE), +] + +DATE_PATTERN = re.compile(r"\b(\d{4})-(\d{2})-(\d{2})\b") + +WORD_PATTERN = re.compile(r"[a-z0-9]+") + + +def _fail(message: str) -> None: + print(f"error: {message}", file=sys.stderr) + raise SystemExit(3) + + +def _plural(count: int, noun: str) -> str: + return f"{count} {noun}" if count == 1 else f"{count} {noun}s" + + +def estimate_tokens(text: str) -> int: + """Rough token estimate. Deliberately crude -- ~4 chars per token.""" + return max(1, len(text) // 4) + + +def _mask_code_fences(text: str) -> str: + """Blank out fenced code bodies so '# comment' inside them is not a heading. + + Same length is preserved, so offsets into the masked copy still index the + original text correctly. + """ + masked = list(text) + fence = re.compile(r"^[ \t]*(`{3,}|~{3,})", re.M) + positions = [match.start() for match in fence.finditer(text)] + for index in range(0, len(positions) - 1, 2): + start, end = positions[index], positions[index + 1] + for offset in range(start, min(end, len(masked))): + if masked[offset] != "\n": + masked[offset] = " " + return "".join(masked) + + +def split_records(text: str, source: str) -> list[dict]: + """Split a document into records on markdown headings, else blank lines.""" + records = [] + heading = re.compile(r"^(#{1,6})\s+(.*)$", re.M) + # Detect headings on a code-masked copy, but slice bodies from the original. + matches = list(heading.finditer(_mask_code_fences(text))) + + if len(matches) >= 2: + for index, match in enumerate(matches): + start = match.end() + end = matches[index + 1].start() if index + 1 < len(matches) else len(text) + body = text[start:end].strip() + # A heading with a near-empty body is a section marker, not a + # memory record. Admitting it would inflate every count below. + if len(body.split()) >= MIN_RECORD_WORDS: + records.append( + { + "source": source, + "title": match.group(2).strip(), + "text": body, + } + ) + return records + + for block in re.split(r"\n\s*\n", text): + block = block.strip() + if len(block) >= 40: + records.append({"source": source, "title": "", "text": block}) + return records + + +def _score(patterns: list, text: str) -> int: + return sum(1 for pattern in patterns if pattern.search(text)) + + +def classify(text: str) -> tuple[str, dict]: + """Classify a record as LOG, SKILL, FACT, or PROSE with its signal counts. + + A record is only called LOG when it carries a positive event signal. + Records with no signal at all are PROSE, not LOG -- narrative documentation + is neither an event log nor a retrievable fact, and calling it LOG would + fire the log-heavy finding on every prose-shaped store. + """ + signals = { + "log": _score(LOG_PATTERNS, text), + "skill": _score(SKILL_PATTERNS, text), + "fact": _score(FACT_PATTERNS, text), + } + # LOG wins ties: mistaking an event for knowledge is the costly direction. + if signals["log"] > 0 and signals["log"] >= max(signals["skill"], signals["fact"]): + return "LOG", signals + if signals["skill"] > signals["fact"]: + return "SKILL", signals + if signals["fact"] > 0: + return "FACT", signals + return "PROSE", signals + + +def shingles(text: str) -> set: + words = WORD_PATTERN.findall(text.lower()) + if len(words) < SHINGLE_SIZE: + return {" ".join(words)} if words else set() + return { + " ".join(words[i : i + SHINGLE_SIZE]) + for i in range(len(words) - SHINGLE_SIZE + 1) + } + + +def jaccard(left: set, right: set) -> float: + if not left or not right: + return 0.0 + intersection = len(left & right) + union = len(left | right) + return intersection / union if union else 0.0 + + +def find_duplicates(records): + """Pairwise near-duplicate detection over word shingles. + + Returns (pairs, participants, redundant, scanned, skipped). + + Two distinct counts, because they answer different questions and reporting + one under the other's name is misleading: + + participants -- records having at least one near-duplicate. BOTH members + of a matching pair count. This is what "N records have a + near-duplicate" means, and it drives duplicate_share. + redundant -- copies that could actually be deleted: participants minus + one survivor per connected cluster. For a cluster of k + mutually-duplicate records this is k-1, not k. + + Clusters are resolved with union-find rather than by counting pair + endpoints: a 3-record cluster produces pairs (i,j), (i,k), (j,k), so any + endpoint-counting shortcut gets the redundant count wrong. + """ + fingerprints = [shingles(record["text"]) for record in records] + # Only records long enough to have a meaningful fingerprint are compared; + # short fragments share shingle sets trivially. + eligible_ix = [ + i + for i, record in enumerate(records) + if len(record["text"].split()) >= MIN_DUPLICATE_WORDS + ] + + # Comparison is O(n^2). Cap it, and report the cap rather than truncating + # silently -- a quiet cap reads as "no duplicates found". + skipped = 0 + if len(eligible_ix) > MAX_DUPLICATE_SCAN: + skipped = len(eligible_ix) - MAX_DUPLICATE_SCAN + eligible_ix = eligible_ix[:MAX_DUPLICATE_SCAN] + + parent = {i: i for i in eligible_ix} + + def find(x): + while parent[x] != x: + parent[x] = parent[parent[x]] + x = parent[x] + return x + + def union(a, b): + ra, rb = find(a), find(b) + if ra != rb: + parent[rb] = ra + + pairs = [] + participants = set() + for pos, i in enumerate(eligible_ix): + for j in eligible_ix[pos + 1 :]: + score = jaccard(fingerprints[i], fingerprints[j]) + if score >= DUPLICATE_THRESHOLD: + pairs.append( + { + "similarity": round(score, 3), + "a": { + "source": records[i]["source"], + "title": records[i].get("title", ""), + }, + "b": { + "source": records[j]["source"], + "title": records[j].get("title", ""), + }, + } + ) + participants.add(i) + participants.add(j) + union(i, j) + + clusters = {find(i) for i in participants} + redundant = len(participants) - len(clusters) + return pairs, len(participants), redundant, len(eligible_ix), skipped + + +def newest_date(text: str): + newest = None + for match in DATE_PATTERN.finditer(text): + try: + found = datetime( + int(match.group(1)), + int(match.group(2)), + int(match.group(3)), + tzinfo=timezone.utc, + ) + except ValueError: + continue + if newest is None or found > newest: + newest = found + return newest + + +def load_records(args) -> list[dict]: + records = [] + if args.jsonl: + try: + with open(args.jsonl, "r", encoding="utf-8") as handle: + for number, line in enumerate(handle, start=1): + line = line.strip() + if not line: + continue + try: + payload = json.loads(line) + except json.JSONDecodeError as exc: + _fail(f"{args.jsonl}:{number} is not valid JSON: {exc}") + if not isinstance(payload, dict) or "text" not in payload: + _fail(f"{args.jsonl}:{number} must be an object with a 'text' field") + records.append( + { + "source": payload.get("source", f"{args.jsonl}:{number}"), + "title": payload.get("title", ""), + "text": str(payload["text"]), + } + ) + except FileNotFoundError: + _fail(f"jsonl file not found: {args.jsonl}") + return records + + if not os.path.isdir(args.dir): + _fail(f"not a directory: {args.dir}") + for root, dirnames, filenames in os.walk(args.dir): + dirnames[:] = [d for d in dirnames if not d.startswith(".")] + for filename in sorted(filenames): + if os.path.splitext(filename)[1].lower() not in TEXT_SUFFIXES: + continue + path = os.path.join(root, filename) + try: + with open(path, "r", encoding="utf-8", errors="replace") as handle: + content = handle.read() + except OSError: + continue + relative = os.path.relpath(path, args.dir) + records.extend(split_records(content, relative)) + return records + + +def audit(records: list[dict], stale_days: int) -> dict: + if not records: + _fail("no records found -- check the path, or that files are .md/.txt") + + now = datetime.now(timezone.utc) + counts = {"FACT": 0, "SKILL": 0, "LOG": 0, "PROSE": 0} + total_tokens = 0 + stale = [] + volatile = [] + + for record in records: + kind, signals = classify(record["text"]) + record["kind"] = kind + record["signals"] = signals + tokens = estimate_tokens(record["text"]) + record["tokens"] = tokens + counts[kind] += 1 + total_tokens += tokens + + found = newest_date(record["text"]) + if found is not None: + age = (now - found).days + record["age_days"] = age + if age > stale_days: + stale.append( + { + "source": record["source"], + "title": record.get("title", ""), + "age_days": age, + } + ) + if any(pattern.search(record["text"]) for pattern in VOLATILE_PATTERNS): + volatile.append( + { + "source": record["source"], + "title": record.get("title", ""), + "why": "contains time-relative wording that rots silently", + } + ) + + ( + duplicate_pairs, + duplicate_records, + redundant_copies, + scanned, + skipped, + ) = find_duplicates(records) + total = len(records) + knowledge = counts["FACT"] + counts["SKILL"] + log_share = counts["LOG"] / total + duplicate_share = duplicate_records / total + density = knowledge / (total_tokens / 1000.0) if total_tokens else 0.0 + + findings = [] + if log_share > LOG_HEAVY_SHARE: + findings.append( + { + "code": "LOG_HEAVY", + "severity": "high", + "detail": ( + f"{counts['LOG']}/{total} records ({log_share:.0%}) read as " + "event logs rather than facts or skills." + ), + "action": ( + "Extract the facts and skills out of these transcripts, " + "then drop the transcripts. Storing the event is what makes " + "retrieval drown." + ), + } + ) + if duplicate_share > DUPLICATE_SHARE: + findings.append( + { + "code": "DUPLICATE_BLOATED", + "severity": "high", + "detail": ( + f"{duplicate_records}/{total} records ({duplicate_share:.0%}) " + f"have a near-duplicate at >= {DUPLICATE_THRESHOLD:.0%} " + f"similarity; {redundant_copies} of them are redundant " + "copies that could be deleted." + ), + "action": ( + "Dedup at write time. Duplicates do not just waste tokens -- " + "they let a stale copy outrank a corrected one." + ), + } + ) + if stale: + findings.append( + { + "code": "STALE_RECORDS", + "severity": "medium", + "detail": ( + f"{len(stale)} records carry a date older than {stale_days} " + "days." + ), + "action": "Re-verify or expire them. A memory that was true is still wrong.", + } + ) + prose_share = counts["PROSE"] / total + if prose_share > PROSE_HEAVY_SHARE: + findings.append( + { + "code": "PROSE_HEAVY", + "severity": "medium", + "detail": ( + f"{counts['PROSE']}/{total} records ({prose_share:.0%}) carry " + "no fact, skill, or event signal -- they read as narrative " + "documentation." + ), + "action": ( + "Prose is what a human re-reads, not what an agent " + "retrieves. Distill each block into the fact or the skill " + "it is trying to convey, or move it out of the memory " + "store and into docs." + ), + } + ) + + if volatile: + findings.append( + { + "code": "VOLATILE_WORDING", + "severity": "medium", + "detail": ( + f"{_plural(len(volatile), 'record')} " + f"{'uses' if len(volatile) == 1 else 'use'} time-relative " + "wording ('currently', 'latest') that becomes false without " + "editing." + ), + "action": ( + "Rewrite with an explicit date or version, so staleness is " + "detectable instead of invisible." + ), + } + ) + + if any(f["severity"] == "high" for f in findings): + verdict = "LOG-HEAVY" if log_share > LOG_HEAVY_SHARE else "DUPLICATE-BLOATED" + elif prose_share > PROSE_HEAVY_SHARE: + verdict = "PROSE-HEAVY" + elif findings: + verdict = "NEEDS-MAINTENANCE" + else: + verdict = "KNOWLEDGE-DENSE" + + return { + "verdict": verdict, + "totals": { + "records": total, + "estimated_tokens": total_tokens, + "fact": counts["FACT"], + "skill": counts["SKILL"], + "log": counts["LOG"], + "prose": counts["PROSE"], + "log_share": round(log_share, 4), + "prose_share": round(prose_share, 4), + }, + "density": { + "knowledge_records_per_1k_tokens": round(density, 3), + "note": ( + "Optimize decision-relevant information per token of context " + "it costs, not how much you managed to store." + ), + }, + "duplicates": { + "records_with_a_duplicate": duplicate_records, + "redundant_copies": redundant_copies, + "share": round(duplicate_share, 4), + "scanned": scanned, + "skipped_over_scan_cap": skipped, + "pairs": duplicate_pairs[:20], + "pairs_truncated": max(0, len(duplicate_pairs) - 20), + }, + "stale_records": stale[:20], + "volatile_records": volatile[:20], + "findings": findings, + } + + +def render(report: dict) -> str: + lines = [] + totals = report["totals"] + lines.append("MEMORY DENSITY AUDIT") + lines.append("=" * 68) + lines.append(f"VERDICT: {report['verdict']}") + lines.append("") + lines.append("What the store actually holds") + lines.append("-" * 68) + lines.append(f" records {totals['records']}") + lines.append(f" estimated tokens {totals['estimated_tokens']:,}") + lines.append(f" FACT {totals['fact']}") + lines.append(f" SKILL {totals['skill']}") + lines.append( + f" LOG {totals['log']} ({totals['log_share']:.0%} of records)" + ) + lines.append( + f" PROSE {totals['prose']} " + f"({totals['prose_share']:.0%} of records, no signal either way)" + ) + lines.append("") + lines.append( + f"Knowledge density: " + f"{report['density']['knowledge_records_per_1k_tokens']} " + "fact-or-skill records per 1k tokens" + ) + lines.append("") + + duplicates = report["duplicates"] + if duplicates["records_with_a_duplicate"]: + lines.append( + f"Near-duplicates: " + f"{_plural(duplicates['records_with_a_duplicate'], 'record')} " + f"({duplicates['share']:.0%}), of which " + f"{duplicates['redundant_copies']} redundant" + ) + for pair in duplicates["pairs"][:5]: + left = f"{pair['a']['source']} {pair['a']['title']}".strip() + right = f"{pair['b']['source']} {pair['b']['title']}".strip() + lines.append(f" {pair['similarity']:.2f} {left} <-> {right}") + if duplicates["pairs_truncated"]: + lines.append(f" ... {duplicates['pairs_truncated']} more pairs") + if duplicates["skipped_over_scan_cap"]: + lines.append( + f" NOTE: {duplicates['skipped_over_scan_cap']} eligible records " + f"were not scanned (cap {MAX_DUPLICATE_SCAN}); duplicate counts " + "are a lower bound." + ) + lines.append("") + + if report["findings"]: + lines.append(f"Findings ({len(report['findings'])})") + lines.append("-" * 68) + for finding in report["findings"]: + lines.append(f" [{finding['severity'].upper()}] {finding['code']}") + lines.append(f" {finding['detail']}") + lines.append(f" -> {finding['action']}") + lines.append("") + else: + lines.append("No findings. This store is holding knowledge, not history.") + lines.append("") + + return "\n".join(lines) + + +SAMPLE_RECORDS = [ + { + "source": "sample/onboarding.md", + "title": "Deploy procedure", + "text": ( + "To deploy the api service, run `make release` from main. Always " + "wait for the migration job to report green before promoting. " + "Never deploy on a Friday after 16:00 UTC.\n" + "1. Tag the release\n2. Run the migration\n3. Promote" + ), + }, + { + "source": "sample/infra.md", + "title": "Service ownership", + "text": ( + "The billing service is owned by the payments team. Its production " + "endpoint is https://api.internal/billing and it runs on port 8443. " + "Repo: org/billing-service." + ), + }, + { + "source": "sample/session-2024-01-14.md", + "title": "Debugging session", + "text": ( + "2024-01-14 09:12 User: the billing job is failing again\n" + "Assistant: let me look at the logs\n" + "Then I ran the migration by hand and it worked. The user said " + "they would file a ticket about it later." + ), + }, + { + "source": "sample/session-2024-02-02.md", + "title": "Another debugging session", + "text": ( + "2024-02-02 14:40 User: billing job failing\n" + "Assistant: checking the logs now\n" + "Then I ran the migration by hand and it worked. The user said " + "they would file a ticket about it later." + ), + }, + { + "source": "sample/stack.md", + "title": "Current stack", + "text": ( + "We are currently on Postgres 14 and the latest Redis. This is the " + "most recent setup as of now." + ), + }, + { + # The same fact written twice in two files -- the most common way a + # memory store bloats, and the way a stale copy outranks a fixed one. + "source": "sample/teams.md", + "title": "Billing ownership", + "text": ( + "The billing service is owned by the payments team. Its production " + "endpoint is https://api.internal/billing and it runs on port 8443. " + "Repo: org/billing-service." + ), + }, +] + + +def main() -> int: + parser = argparse.ArgumentParser( + description=( + "Classify memory records as FACT / SKILL / LOG, find near-duplicates " + "and staleness, and score knowledge density." + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=( + "Examples:\n" + " memory_density_auditor.py --sample\n" + " memory_density_auditor.py --dir ~/.claude/memory\n" + " memory_density_auditor.py --jsonl records.jsonl --output json\n" + ), + ) + source = parser.add_mutually_exclusive_group(required=True) + source.add_argument("--dir", help="directory of markdown/text memory files") + source.add_argument("--jsonl", help="JSONL file of records with a 'text' field") + source.add_argument( + "--sample", + action="store_true", + help="audit the built-in sample store (no input needed)", + ) + parser.add_argument( + "--stale-days", + type=int, + default=DEFAULT_STALE_DAYS, + help=f"age in days past which a dated record is stale (default: {DEFAULT_STALE_DAYS})", + ) + parser.add_argument( + "--output", + choices=["text", "json"], + default="text", + help="output format (default: text)", + ) + args = parser.parse_args() + + if args.stale_days < 1: + _fail("--stale-days must be >= 1") + + records = list(SAMPLE_RECORDS) if args.sample else load_records(args) + report = audit(records, args.stale_days) + + if args.output == "json": + print(json.dumps(report, indent=2)) + else: + print(render(report)) + + return 2 if report["findings"] else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/engineering/prompt-governance/skills/prompt-governance/SKILL.md b/engineering/prompt-governance/skills/prompt-governance/SKILL.md index c517fe62..00584138 100644 --- a/engineering/prompt-governance/skills/prompt-governance/SKILL.md +++ b/engineering/prompt-governance/skills/prompt-governance/SKILL.md @@ -77,7 +77,7 @@ prompts: - id: summarizer description: "Summarize support tickets for agent triage" owner: platform-team - model: claude-sonnet-4-5 + model: claude-sonnet-5 versions: - version: 1.1.0 file: summarizer/v1.1.0.md diff --git a/engineering/security-guidance/.claude-plugin/authoring-notes.json b/engineering/security-guidance/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..d06c9790 --- /dev/null +++ b/engineering/security-guidance/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "upstream": "https://github.com/alirezarezvani/aeo-box/tree/main/.claude/plugins/security-guidance", + "upstream_author": "David Dworken (dworken@anthropic.com)", + "upstream_license": "MIT", + "modifications": "12 patterns preserved verbatim. Added 3 patterns (subprocess shell=True, SQL injection via f-string/.format, yaml.unsafe_load). Debug log moved from /tmp to ~/.claude/security-warnings-log.txt for persistence. Added documentation reference under skills/security-guidance/." + } +} diff --git a/engineering/security-guidance/.claude-plugin/plugin.json b/engineering/security-guidance/.claude-plugin/plugin.json index e3ffd392..c6e01ac4 100644 --- a/engineering/security-guidance/.claude-plugin/plugin.json +++ b/engineering/security-guidance/.claude-plugin/plugin.json @@ -9,11 +9,7 @@ "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/engineering/security-guidance", "repository": "https://github.com/alirezarezvani/claude-skills", "license": "MIT", - "skills": ["./skills/security-guidance"], - "attribution": { - "upstream": "https://github.com/alirezarezvani/aeo-box/tree/main/.claude/plugins/security-guidance", - "upstream_author": "David Dworken (dworken@anthropic.com)", - "upstream_license": "MIT", - "modifications": "12 patterns preserved verbatim. Added 3 patterns (subprocess shell=True, SQL injection via f-string/.format, yaml.unsafe_load). Debug log moved from /tmp to ~/.claude/security-warnings-log.txt for persistence. Added documentation reference under skills/security-guidance/." - } + "skills": [ + "./skills/security-guidance" + ] } diff --git a/engineering/security-guidance/hooks/hooks.json b/engineering/security-guidance/hooks/hooks.json index a86cd8b4..229f20c4 100644 --- a/engineering/security-guidance/hooks/hooks.json +++ b/engineering/security-guidance/hooks/hooks.json @@ -7,7 +7,7 @@ "hooks": [ { "type": "command", - "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py" + "command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"" } ] } diff --git a/engineering/security-guidance/skills/security-guidance/SKILL.md b/engineering/security-guidance/skills/security-guidance/SKILL.md index 21382e7c..b6bf4f05 100644 --- a/engineering/security-guidance/skills/security-guidance/SKILL.md +++ b/engineering/security-guidance/skills/security-guidance/SKILL.md @@ -120,7 +120,7 @@ This plugin is ported from David Dworken's MIT-licensed implementation in [`alir **Modifications:** - Added 3 patterns: `subprocess shell=True`, SQL injection via f-string or `.format`, `yaml.unsafe_load` - Debug log moved from `/tmp/security-warnings-log.txt` → `~/.claude/security-warnings-log.txt` -- Restructured as a claude-skills plugin with `attribution` block in `plugin.json` +- Restructured as a claude-skills plugin with `attribution` block in `.claude-plugin/authoring-notes.json` (originally in `plugin.json`; relocated when issue #954 showed Claude Code rejects manifests carrying extension keys) ## Anti-Patterns diff --git a/engineering/skillopt-sleep/.claude-plugin/authoring-notes.json b/engineering/skillopt-sleep/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..4eef6f40 --- /dev/null +++ b/engineering/skillopt-sleep/.claude-plugin/authoring-notes.json @@ -0,0 +1,9 @@ +{ + "attribution": { + "upstream": "https://github.com/microsoft/SkillOpt", + "upstream_path": "skillopt_sleep/ (engine) + plugins/claude-code/ (Claude Code plugin surface) + plugins/run-sleep.sh (shared launcher)", + "upstream_author": "Yifan Yang (yifanyang@microsoft.com), Microsoft Corporation", + "upstream_license": "MIT", + "derivation_note": "Started as a verbatim byte-for-byte copy of the skillopt_sleep Python engine, its Claude Code plugin skill/hooks/commands, and the shared scripts/run-sleep.sh + scripts/sleep.sh launchers. 23 targeted patches (6 cosmetic, 17 safety/hardening) were made afterward across staging.py, scheduler.py, cycle.py, state.py, backend.py, __main__.py, SKILL.md, commands/skillopt-sleep.md, sleep.sh, run-sleep.sh, and install-cron.sh, found across ten rounds of adversarial code review rather than assumed safe from the surface docs -- see the numbered 'Deviations from upstream' section in README.md for the authoritative, exact list (secret redaction covering proposed_SKILL.md/proposed_CLAUDE.md/the task archive/report.md/report.json, not just diagnostics; shell-quoting the generated crontab line including the extra param; adopt() re-redacting as defense-in-depth; wiring the previously-dead max_tokens_per_night budget; a loud warning that replay_mode:'fresh' is an unimplemented no-op; removing a hardcoded internal Azure OpenAI backend with Microsoft-internal endpoint hostnames and a Managed Identity client ID; validating tool names against a safe-identifier allowlist before they're used as a shim filename or interpolated into generated shell text; a dead SKILL.md cross-reference to a non-vendored design doc, now pointed at the real upstream URL; making the schedule command's confirm-before-installing behavior explicit instead of contradicting itself; chmod 0700/0600 on state and staging directories/files; correcting stale upstream-layout path assumptions in sleep.sh/run-sleep.sh's fallback branches to match this repo's actual scripts/+skillopt_sleep/ sibling layout; routing __main__.py's cmd_run/cmd_harvest console/--json/--output output through redact_secrets, since that bypassed every file-level redaction fix above, plus chmod 0700/0600 on cron.log which those fixes never covered; anchoring scheduler.py's per-project cron-line marker match on end-of-line instead of a bare substring test, which could silently drop a sibling project's scheduled job whose path happened to be a prefix of the one being (un)scheduled; quoting install-cron.sh's printed --backend value; requiring --yes for schedule at the CLI layer (not just in the driving agent's chat-confirmation instructions), refusing non-interactively without it; passing mode=0o700 to the os.makedirs() calls that create state/staging/backup dirs to close the create-then-chmod race window) -- re-apply all of them on re-vendor, and treat any other document (including this note) that repeats the count as a summary of that list, not a second source of truth: if counts ever disagree again, README.md's numbered list wins. skillopt_sleep has zero third-party dependencies (stdlib only) -- the heavier skillopt package it derives its ideas from (numpy/openai/azure, benchmark training loops) was deliberately NOT vendored, since this repo's skills are broad domain-expertise packages without labeled benchmarks, not narrow scoreable tasks. Re-vendor by re-copying skillopt_sleep/, plugins/claude-code/{skills,hooks,commands,scripts}/, and plugins/run-sleep.sh from a fresh clone of microsoft/SkillOpt, then re-applying the README's deviation list." + } +} diff --git a/engineering/skillopt-sleep/.claude-plugin/plugin.json b/engineering/skillopt-sleep/.claude-plugin/plugin.json index 60bc4c0b..0a64f14d 100644 --- a/engineering/skillopt-sleep/.claude-plugin/plugin.json +++ b/engineering/skillopt-sleep/.claude-plugin/plugin.json @@ -11,12 +11,5 @@ "license": "MIT", "skills": [ "./skills/skillopt-sleep" - ], - "attribution": { - "upstream": "https://github.com/microsoft/SkillOpt", - "upstream_path": "skillopt_sleep/ (engine) + plugins/claude-code/ (Claude Code plugin surface) + plugins/run-sleep.sh (shared launcher)", - "upstream_author": "Yifan Yang (yifanyang@microsoft.com), Microsoft Corporation", - "upstream_license": "MIT", - "derivation_note": "Started as a verbatim byte-for-byte copy of the skillopt_sleep Python engine, its Claude Code plugin skill/hooks/commands, and the shared scripts/run-sleep.sh + scripts/sleep.sh launchers. 23 targeted patches (6 cosmetic, 17 safety/hardening) were made afterward across staging.py, scheduler.py, cycle.py, state.py, backend.py, __main__.py, SKILL.md, commands/skillopt-sleep.md, sleep.sh, run-sleep.sh, and install-cron.sh, found across ten rounds of adversarial code review rather than assumed safe from the surface docs -- see the numbered 'Deviations from upstream' section in README.md for the authoritative, exact list (secret redaction covering proposed_SKILL.md/proposed_CLAUDE.md/the task archive/report.md/report.json, not just diagnostics; shell-quoting the generated crontab line including the extra param; adopt() re-redacting as defense-in-depth; wiring the previously-dead max_tokens_per_night budget; a loud warning that replay_mode:'fresh' is an unimplemented no-op; removing a hardcoded internal Azure OpenAI backend with Microsoft-internal endpoint hostnames and a Managed Identity client ID; validating tool names against a safe-identifier allowlist before they're used as a shim filename or interpolated into generated shell text; a dead SKILL.md cross-reference to a non-vendored design doc, now pointed at the real upstream URL; making the schedule command's confirm-before-installing behavior explicit instead of contradicting itself; chmod 0700/0600 on state and staging directories/files; correcting stale upstream-layout path assumptions in sleep.sh/run-sleep.sh's fallback branches to match this repo's actual scripts/+skillopt_sleep/ sibling layout; routing __main__.py's cmd_run/cmd_harvest console/--json/--output output through redact_secrets, since that bypassed every file-level redaction fix above, plus chmod 0700/0600 on cron.log which those fixes never covered; anchoring scheduler.py's per-project cron-line marker match on end-of-line instead of a bare substring test, which could silently drop a sibling project's scheduled job whose path happened to be a prefix of the one being (un)scheduled; quoting install-cron.sh's printed --backend value; requiring --yes for schedule at the CLI layer (not just in the driving agent's chat-confirmation instructions), refusing non-interactively without it; passing mode=0o700 to the os.makedirs() calls that create state/staging/backup dirs to close the create-then-chmod race window) -- re-apply all of them on re-vendor, and treat any other document (including this note) that repeats the count as a summary of that list, not a second source of truth: if counts ever disagree again, README.md's numbered list wins. skillopt_sleep has zero third-party dependencies (stdlib only) -- the heavier skillopt package it derives its ideas from (numpy/openai/azure, benchmark training loops) was deliberately NOT vendored, since this repo's skills are broad domain-expertise packages without labeled benchmarks, not narrow scoreable tasks. Re-vendor by re-copying skillopt_sleep/, plugins/claude-code/{skills,hooks,commands,scripts}/, and plugins/run-sleep.sh from a fresh clone of microsoft/SkillOpt, then re-applying the README's deviation list." - } + ] } diff --git a/engineering/skills/agent-designer/README.md b/engineering/skills/agent-designer/README.md index 5a023e71..47a4e902 100644 --- a/engineering/skills/agent-designer/README.md +++ b/engineering/skills/agent-designer/README.md @@ -358,7 +358,7 @@ with open('my_tools_openai.json') as f: # Use with OpenAI function calling response = openai.ChatCompletion.create( - model="gpt-4", + model=OPENAI_MODEL, # from config; don't hardcode a model ID messages=[{"role": "user", "content": "Search for AI news"}], functions=schemas['functions'] ) @@ -377,7 +377,7 @@ with open('my_tools_anthropic.json') as f: # Use with Anthropic tool use client = anthropic.Anthropic() response = client.messages.create( - model="claude-3-opus-20240229", + model="claude-opus-5", messages=[{"role": "user", "content": "Search for AI news"}], tools=schemas['tools'] ) diff --git a/engineering/skills/agent-designer/agent_evaluator.py b/engineering/skills/agent-designer/agent_evaluator.py index 8d86c56a..f76eca5e 100644 --- a/engineering/skills/agent-designer/agent_evaluator.py +++ b/engineering/skills/agent-designer/agent_evaluator.py @@ -133,7 +133,6 @@ class AgentEvaluator: def __init__(self): self.error_patterns = self._define_error_patterns() self.performance_thresholds = self._define_performance_thresholds() - self.cost_benchmarks = self._define_cost_benchmarks() def _define_error_patterns(self) -> Dict[str, Dict[str, Any]]: """Define common error patterns and their classifications""" @@ -217,23 +216,15 @@ class AgentEvaluator: "throughput": {"excellent": 100, "good": 50, "acceptable": 20, "poor": 5} # tasks per hour } - def _define_cost_benchmarks(self) -> Dict[str, Any]: - """Define cost benchmarks for different operations""" - return { - "token_costs": { - "gpt-4": {"input": 0.00003, "output": 0.00006}, - "gpt-3.5-turbo": {"input": 0.000002, "output": 0.000002}, - "claude-3": {"input": 0.000015, "output": 0.000075} - }, - "operation_costs": { - "simple_task": 0.005, - "complex_task": 0.050, - "research_task": 0.020, - "analysis_task": 0.030, - "generation_task": 0.015 - } - } - + # _define_cost_benchmarks() was removed. It hardcoded per-token prices for + # gpt-4, gpt-3.5-turbo and claude-3 — all retired, all priced at 2024 + # rates — and the result was assigned to self.cost_benchmarks and never + # read by anything. Cost analysis in this tool uses the cost_usd field the + # caller supplies in each execution log, which is the only figure that can + # be accurate. See engineering-team/skills/senior-prompt-engineer/scripts/ + # prompt_optimizer.py for the --price-per-mtok pattern if a price is + # genuinely needed. + def parse_execution_logs(self, logs_data: List[Dict[str, Any]]) -> List[ExecutionLog]: """Parse raw execution logs into structured format""" logs = [] diff --git a/engineering/skills/agent-designer/assets/sample_execution_logs.json b/engineering/skills/agent-designer/assets/sample_execution_logs.json index 13ec29bd..0f7b45bb 100644 --- a/engineering/skills/agent-designer/assets/sample_execution_logs.json +++ b/engineering/skills/agent-designer/assets/sample_execution_logs.json @@ -38,7 +38,7 @@ } ], "results": { - "summary": "Found 15 relevant sources covering recent AI developments including GPT-4 improvements, autonomous vehicle progress, and medical AI applications.", + "summary": "Found 15 relevant sources covering recent AI developments including frontier model improvements, autonomous vehicle progress, and medical AI applications.", "sources_found": 15, "quality_score": 0.92 }, diff --git a/engineering/skills/agent-designer/references/evaluation_methodology.md b/engineering/skills/agent-designer/references/evaluation_methodology.md index 3b430f5b..24920fe9 100644 --- a/engineering/skills/agent-designer/references/evaluation_methodology.md +++ b/engineering/skills/agent-designer/references/evaluation_methodology.md @@ -653,8 +653,8 @@ trend_analysis: ### API Usage - **Token Consumption**: 2.4M tokens/day - **Cost Breakdown**: - - GPT-4: 68% of token costs - - GPT-3.5: 28% of token costs + - Large-tier model: 68% of token costs + - Small-tier model: 28% of token costs - Other models: 4% of token costs ``` diff --git a/engineering/skills/api-design-reviewer/scripts/api_linter.py b/engineering/skills/api-design-reviewer/scripts/api_linter.py index 6bd4c919..61c08272 100644 --- a/engineering/skills/api-design-reviewer/scripts/api_linter.py +++ b/engineering/skills/api-design-reviewer/scripts/api_linter.py @@ -22,6 +22,15 @@ from typing import Any, Dict, List, Tuple, Optional, Set from urllib.parse import urlparse from dataclasses import dataclass, field +# Windows consoles often default to a legacy codepage (e.g. cp1252) that cannot +# encode the Unicode glyphs this script prints (issue #969). Re-encode +# stdout/stderr as UTF-8 with replacement so output never crashes at print time. +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8", errors="replace") + + @dataclass class LintIssue: diff --git a/engineering/skills/api-design-reviewer/scripts/api_scorecard.py b/engineering/skills/api-design-reviewer/scripts/api_scorecard.py index dc673363..e98e2d36 100644 --- a/engineering/skills/api-design-reviewer/scripts/api_scorecard.py +++ b/engineering/skills/api-design-reviewer/scripts/api_scorecard.py @@ -24,6 +24,15 @@ from dataclasses import dataclass, field from enum import Enum import math +# Windows consoles often default to a legacy codepage (e.g. cp1252) that cannot +# encode the Unicode glyphs this script prints (issue #969). Re-encode +# stdout/stderr as UTF-8 with replacement so output never crashes at print time. +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8", errors="replace") + + class ScoreCategory(Enum): """Scoring categories.""" diff --git a/engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py b/engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py index 6f2736a9..df5e6e81 100644 --- a/engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py +++ b/engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py @@ -22,6 +22,15 @@ from typing import Any, Dict, List, Set, Optional, Tuple, Union from dataclasses import dataclass, field from enum import Enum +# Windows consoles often default to a legacy codepage (e.g. cp1252) that cannot +# encode the Unicode glyphs this script prints (issue #969). Re-encode +# stdout/stderr as UTF-8 with replacement so output never crashes at print time. +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8", errors="replace") + + class ChangeType(Enum): """Types of API changes.""" diff --git a/engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py b/engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py index 205d833b..86ad7567 100755 --- a/engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py +++ b/engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py @@ -27,6 +27,14 @@ from enum import IntEnum from pathlib import Path from typing import Optional +# Windows consoles often default to a legacy codepage (e.g. cp1252) that cannot +# encode the Unicode glyphs this script prints (issue #969). Re-encode +# stdout/stderr as UTF-8 with replacement so output never crashes at print time. +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8", errors="replace") +if hasattr(sys.stderr, "reconfigure"): + sys.stderr.reconfigure(encoding="utf-8", errors="replace") + class Severity(IntEnum): INFO = 0 diff --git a/engineering/skills/skill-tester/assets/sample-skill/SKILL.md b/engineering/skills/skill-tester/assets/sample-skill/SKILL.md index c717dba3..e04d1acf 100644 --- a/engineering/skills/skill-tester/assets/sample-skill/SKILL.md +++ b/engineering/skills/skill-tester/assets/sample-skill/SKILL.md @@ -1,16 +1,16 @@ +--- +name: sample-text-processor +description: "Reference BASIC-tier skill used as a fixture by skill-tester. Counts words and characters and applies basic text transformations. Use when validating skill-tester itself or when you need a minimal, known-good skill layout to copy. Not a production skill." +--- + # Sample Text Processor ---- +This file is the fixture skill_validator.py and script_tester.py run against. +It is deliberately minimal. Keep its frontmatter valid YAML and limited to the +fields Claude Code reads: anything else here gets copied into new skills by +authors treating it as a template. -**Name**: sample-text-processor -**Tier**: BASIC -**Category**: Text Processing -**Dependencies**: None (Python Standard Library Only) -**Author**: Claude Skills Engineering Team -**Version**: 1.0.0 -**Last Updated**: 2026-02-16 - ---- +Tier: BASIC. Dependencies: none, Python standard library only. ## Description diff --git a/engineering/skills/skill-tester/scripts/skill_validator.py b/engineering/skills/skill-tester/scripts/skill_validator.py index 53d93bda..37785720 100644 --- a/engineering/skills/skill-tester/scripts/skill_validator.py +++ b/engineering/skills/skill-tester/scripts/skill_validator.py @@ -132,14 +132,37 @@ class SkillValidator: } } - REQUIRED_SKILL_MD_SECTIONS = [ - "Name", "Description", "Features", "Usage", "Examples" + # Sections the repo actually uses. Measured across all 361 real SKILL.md + # files: no single heading appears in even 30% of them, so requiring a + # fixed list is not defensible. These are scored as a recommendation + # (RECOMMENDED_SECTIONS_THRESHOLD of them present earns full marks) and + # never raise an error. + RECOMMENDED_SKILL_MD_SECTIONS = [ + "References", "Quick Start", "Related Skills", "Workflow", "Workflows", + "When to Use", "Proactive Triggers", "Output Artifacts", + "Anti-Patterns", "Output Format", "Overview", "Core Capabilities", ] - - FRONTMATTER_REQUIRED_FIELDS = [ - "Name", "Tier", "Category", "Dependencies", "Author", "Version" + RECOMMENDED_SECTIONS_THRESHOLD = 2 + + # What Claude Code actually reads from SKILL.md frontmatter. `description` + # is what the skill listing matches against, so a skill without one is + # invisible to model invocation. + # + # This list previously read ["Name", "Tier", "Category", "Dependencies", + # "Author", "Version"] — the bold key/value convention used by the + # assets/sample-skill fixture, not YAML frontmatter and not a schema any + # real skill has ever followed. Every one of the 362 skills failed both + # checks identically, so the output was noise nobody acted on. + FRONTMATTER_REQUIRED_FIELDS = ["name", "description"] + + # Present on many skills and harmless, but no runtime reads them. + FRONTMATTER_OPTIONAL_FIELDS = [ + "when_to_use", "argument-hint", "arguments", "allowed-tools", + "disallowed-tools", "disable-model-invocation", "user-invocable", + "model", "effort", "context", "agent", "background", "hooks", + "paths", "shell", ] - + def __init__(self, skill_path: str, target_tier: Optional[str] = None, verbose: bool = False): self.skill_path = Path(skill_path).resolve() self.target_tier = target_tier @@ -283,23 +306,33 @@ class SkillValidator: self.report.add_error("SKILL.md must start with YAML frontmatter") def _validate_required_sections(self, content: str): - """Validate required sections in SKILL.md""" - self.log_verbose("Checking required sections...") - - missing_sections = [] - for section in self.REQUIRED_SKILL_MD_SECTIONS: + """Score SKILL.md against the repo's common section conventions. + + Advisory only: the repo has no universal section schema, so a miss is + a hint to the author, not a validation error. + """ + self.log_verbose("Checking recommended sections...") + + present = [] + for section in self.RECOMMENDED_SKILL_MD_SECTIONS: pattern = rf'^#+\s*{re.escape(section)}\s*$' - if not re.search(pattern, content, re.MULTILINE | re.IGNORECASE): - missing_sections.append(section) - - if not missing_sections: - self.report.add_check("required_sections", True, - "All required sections present", 1.0) + if re.search(pattern, content, re.MULTILINE | re.IGNORECASE): + present.append(section) + + threshold = self.RECOMMENDED_SECTIONS_THRESHOLD + if len(present) >= threshold: + self.report.add_check("recommended_sections", True, + f"{len(present)} recommended section(s) present: " + f"{', '.join(present)}", 1.0) else: - self.report.add_check("required_sections", False, - f"Missing sections: {', '.join(missing_sections)}", 0.0) - self.report.add_error(f"Missing required sections: {', '.join(missing_sections)}") - + self.report.add_check("recommended_sections", False, + f"Only {len(present)} recommended section(s) present " + f"(suggest at least {threshold} of: " + f"{', '.join(self.RECOMMENDED_SKILL_MD_SECTIONS)})", 0.0) + self.report.add_warning( + f"SKILL.md has {len(present)} of the repo's common sections; " + f"consider adding at least {threshold}") + def _validate_readme(self): """Validate README.md content""" self.log_verbose("Validating README.md...") @@ -469,22 +502,19 @@ class SkillValidator: return False def _check_external_imports(self, tree: ast.AST) -> List[str]: - """Check for external (non-stdlib) imports""" - # Simplified check - a more comprehensive solution would use a stdlib module list - stdlib_modules = { - 'argparse', 'ast', 'json', 'os', 'sys', 'pathlib', 'datetime', 'typing', - 'collections', 're', 'math', 'random', 'itertools', 'functools', 'operator', - 'csv', 'sqlite3', 'urllib', 'http', 'html', 'xml', 'email', 'base64', - 'hashlib', 'hmac', 'secrets', 'tempfile', 'shutil', 'glob', 'fnmatch', - 'subprocess', 'threading', 'multiprocessing', 'queue', 'time', 'calendar', - 'zoneinfo', 'locale', 'gettext', 'logging', 'warnings', 'unittest', - 'doctest', 'pickle', 'copy', 'pprint', 'reprlib', 'enum', 'dataclasses', - 'contextlib', 'abc', 'atexit', 'traceback', 'gc', 'weakref', 'types', - 'copy', 'pprint', 'reprlib', 'enum', 'decimal', 'fractions', 'statistics', - 'cmath', 'platform', 'errno', 'io', 'codecs', 'unicodedata', 'stringprep', - 'textwrap', 'string', 'struct', 'difflib', 'heapq', 'bisect', 'array', - 'weakref', 'types', 'copyreg', 'uuid', 'mmap', 'ctypes' - } + """Check for external (non-stdlib) imports. + + Uses the interpreter's own module list rather than a hand-maintained + set, which is what this function's original comment asked for. The old + set omitted `__future__`, so every script using + `from __future__ import annotations` was reported as carrying an + external dependency. + """ + stdlib_modules = set(getattr(sys, "stdlib_module_names", ())) + if not stdlib_modules: # Python < 3.10 has no sys.stdlib_module_names + stdlib_modules = set(sys.builtin_module_names) + # A compiler directive, not a dependency. + stdlib_modules.add('__future__') external_imports = [] for node in ast.walk(tree): diff --git a/engineering/universal-scraping-architect/.claude-plugin/authoring-notes.json b/engineering/universal-scraping-architect/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..1de8ca08 --- /dev/null +++ b/engineering/universal-scraping-architect/.claude-plugin/authoring-notes.json @@ -0,0 +1,7 @@ +{ + "attribution": { + "author": "Mehansh Barthwal", + "source": "https://github.com/mehanshbarthwal-lab", + "license": "MIT" + } +} diff --git a/engineering/universal-scraping-architect/.claude-plugin/plugin.json b/engineering/universal-scraping-architect/.claude-plugin/plugin.json index e84d4bb2..320236a1 100644 --- a/engineering/universal-scraping-architect/.claude-plugin/plugin.json +++ b/engineering/universal-scraping-architect/.claude-plugin/plugin.json @@ -11,10 +11,5 @@ "license": "MIT", "skills": [ "./skills" - ], - "attribution": { - "author": "Mehansh Barthwal", - "source": "https://github.com/mehanshbarthwal-lab", - "license": "MIT" - } + ] } diff --git a/engineering/workflow-builder/.claude-plugin/authoring-notes.json b/engineering/workflow-builder/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..58cef89d --- /dev/null +++ b/engineering/workflow-builder/.claude-plugin/authoring-notes.json @@ -0,0 +1,7 @@ +{ + "attribution": { + "inspired_by": "https://github.com/ray-amjad/claude-code-workflow-creator", + "original_author": "Ray Amjad", + "derivation_note": "Original content written for this repo from Claude Code's publicly-documented Workflow tool API. Ray Amjad's claude-code-workflow-creator (no LICENSE file at time of authoring) is credited as the conceptual inspiration for the workflow-authoring skill pattern; no text was copied verbatim." + } +} diff --git a/engineering/workflow-builder/.claude-plugin/plugin.json b/engineering/workflow-builder/.claude-plugin/plugin.json index 1a7a4ea3..980aaa82 100644 --- a/engineering/workflow-builder/.claude-plugin/plugin.json +++ b/engineering/workflow-builder/.claude-plugin/plugin.json @@ -9,10 +9,7 @@ "homepage": "https://github.com/alirezarezvani/claude-skills/tree/main/engineering/workflow-builder", "repository": "https://github.com/alirezarezvani/claude-skills", "license": "MIT", - "skills": ["./skills/workflow-builder"], - "attribution": { - "inspired_by": "https://github.com/ray-amjad/claude-code-workflow-creator", - "original_author": "Ray Amjad", - "derivation_note": "Original content written for this repo from Claude Code's publicly-documented Workflow tool API. Ray Amjad's claude-code-workflow-creator (no LICENSE file at time of authoring) is credited as the conceptual inspiration for the workflow-authoring skill pattern; no text was copied verbatim." - } + "skills": [ + "./skills/workflow-builder" + ] } diff --git a/engineering/write-a-skill/.claude-plugin/authoring-notes.json b/engineering/write-a-skill/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..c5fd3e90 --- /dev/null +++ b/engineering/write-a-skill/.claude-plugin/authoring-notes.json @@ -0,0 +1,8 @@ +{ + "attribution": { + "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/write-a-skill", + "original_author": "Matt Pocock (@mattpocock)", + "original_license": "MIT", + "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib validation tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's voice and 3-phase workflow preserved verbatim." + } +} diff --git a/engineering/write-a-skill/.claude-plugin/plugin.json b/engineering/write-a-skill/.claude-plugin/plugin.json index 134a4c82..c9c7ea16 100644 --- a/engineering/write-a-skill/.claude-plugin/plugin.json +++ b/engineering/write-a-skill/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "write-a-skill", - "description": "Skill-author skill: create new agent skills with proper structure, progressive disclosure, and bundled resources. Enhanced from Matt Pocock's MIT-licensed write-a-skill (https://github.com/mattpocock/skills) with: (1) stdlib Python validation tools (description validator, structure validator, review-checklist runner), (2) 3 reference docs citing 5+ authoritative sources each (progressive disclosure principles, description design patterns, quality gates), (3) cs-skill-author persona agent + /cs:write-a-skill slash command. Matt's voice and 3-phase workflow (Gather \u2192 Draft \u2192 Review) preserved verbatim per his MIT license. Use when user wants to create, write, build, or author a new agent skill.", + "description": "Skill-author skill: create new agent skills with proper structure, progressive disclosure, and bundled resources. Enhanced from Matt Pocock's MIT-licensed write-a-skill (https://github.com/mattpocock/skills) with: (1) stdlib Python validation tools (description validator, structure validator, review-checklist runner), (2) 3 reference docs citing 5+ authoritative sources each (progressive disclosure principles, description design patterns, quality gates), (3) cs-skill-author persona agent + /cs:write-a-skill slash command. Matt's voice and 3-phase workflow (Gather → Draft → Review) preserved verbatim per his MIT license. Use when user wants to create, write, build, or author a new agent skill.", "version": "2.9.0", "author": { "name": "Alireza Rezvani", @@ -11,11 +11,5 @@ "license": "MIT", "skills": [ "./skills/write-a-skill" - ], - "attribution": { - "derived_from": "https://github.com/mattpocock/skills/tree/main/skills/productivity/write-a-skill", - "original_author": "Matt Pocock (@mattpocock)", - "original_license": "MIT", - "derivation_note": "Matt's SKILL.md content reproduced under MIT. Additions: stdlib validation tools, deep references, cs-* persona agent + /cs:* command wrapper. Matt's voice and 3-phase workflow preserved verbatim." - } + ] } diff --git a/engineering/write-a-skill/agents/cs-skill-author.md b/engineering/write-a-skill/agents/cs-skill-author.md index ba4c9238..50338103 100644 --- a/engineering/write-a-skill/agents/cs-skill-author.md +++ b/engineering/write-a-skill/agents/cs-skill-author.md @@ -97,7 +97,7 @@ python ../../karpathy-coder/skills/karpathy-coder/scripts/assumption_linter.py p ```bash # 1. Verify license + permissibility # 2. Copy upstream SKILL.md content verbatim where appropriate -# 3. Add attribution: README.md credits + plugin.json description note + SKILL.md derivation metadata +# 3. Add attribution: README.md credits + .claude-plugin/authoring-notes.json attribution block + SKILL.md derivation metadata (never in plugin.json — CI hard-fails extension keys there) # 4. Add wrapper layer per this repo's pattern (validators + references + cs-* + /cs:*) # 5. Validate per Workflow 1 ``` diff --git a/engineering/write-a-skill/skills/write-a-skill/references/quality_gates_for_skills.md b/engineering/write-a-skill/skills/write-a-skill/references/quality_gates_for_skills.md index abc8c21b..16000f42 100644 --- a/engineering/write-a-skill/skills/write-a-skill/references/quality_gates_for_skills.md +++ b/engineering/write-a-skill/skills/write-a-skill/references/quality_gates_for_skills.md @@ -58,7 +58,7 @@ Skills derived from external sources (MIT-licensed or public-domain) must: - State the license - Note what's preserved vs added -Tool: presence-of-attribution grep in plugin.json + README.md. +Tool: presence-of-attribution grep in `.claude-plugin/authoring-notes.json` + README.md. (The `attribution` block moved out of `plugin.json` when issue #954 showed Claude Code rejects manifests with extension keys — `check_plugin_json.py` now hard-fails it there; the sidecar `authoring-notes.json` is its home. Upstream credit must also remain in the plugin's README.md/LICENSE — a sidecar JSON file is not a license notice.) ## Quality Gate Sequencing @@ -126,7 +126,7 @@ The pragmatic split: | **Legacy skills (pre-v2.6.0)** | **Advisory** — WARN/FAIL surfaced but non-blocking | Track in audit report; fix opportunistically | How to tell which cohort a skill belongs to: -- New: matches the `engineering//skills//` wrapper pattern with `attribution` in plugin.json, OR was added in a PR tagged for v2.6.0+ +- New: matches the `engineering//skills//` wrapper pattern with `attribution` in `.claude-plugin/authoring-notes.json`, OR was added in a PR tagged for v2.6.0+ - Legacy: pre-existing structure without the wrapper pattern, or pre-v2.6.0 git history Re-running `scripts/audit_skills.py` periodically captures the legacy backlog drift. The numerator (PASS count) is the metric to grow over time, not "force every skill to PASS by Friday." diff --git a/engineering/zero-hallucination-coder/.claude-plugin/authoring-notes.json b/engineering/zero-hallucination-coder/.claude-plugin/authoring-notes.json new file mode 100644 index 00000000..f5f75305 --- /dev/null +++ b/engineering/zero-hallucination-coder/.claude-plugin/authoring-notes.json @@ -0,0 +1,12 @@ +{ + "attribution": { + "contributed_by": "mehanshbarthwal-lab (https://github.com/mehanshbarthwal-lab), PR #854", + "synthesizes": [ + "Ralph — @snarktank (https://github.com/snarktank/ralph): atomic PRD loop, fresh-context per story", + "GSD Core — @open-gsd (https://github.com/open-gsd/gsd-core): phase loop, context-rot prevention, STATE.md memory", + "Graphify — @safishamsi (https://github.com/safishamsi/graphify): KNOWN/INFERRED/UNKNOWN codebase mapping", + "Ponytail — @DietrichGebert (https://github.com/DietrichGebert/ponytail): lazy-senior-dev six-rung hierarchy" + ], + "derivation_note": "Concept + SKILL.md contributed via PR #854. Hardened for this repo: scoped to opt-in activation, embedded multi-method install guide trimmed, plugin.json and layout aligned to the engineering standalone-plugin convention." + } +} diff --git a/engineering/zero-hallucination-coder/.claude-plugin/plugin.json b/engineering/zero-hallucination-coder/.claude-plugin/plugin.json index 3a0a382e..fc8aed2c 100644 --- a/engineering/zero-hallucination-coder/.claude-plugin/plugin.json +++ b/engineering/zero-hallucination-coder/.claude-plugin/plugin.json @@ -11,15 +11,5 @@ "license": "MIT", "skills": [ "./skills/zero-hallucination-coder" - ], - "attribution": { - "contributed_by": "mehanshbarthwal-lab (https://github.com/mehanshbarthwal-lab), PR #854", - "synthesizes": [ - "Ralph — @snarktank (https://github.com/snarktank/ralph): atomic PRD loop, fresh-context per story", - "GSD Core — @open-gsd (https://github.com/open-gsd/gsd-core): phase loop, context-rot prevention, STATE.md memory", - "Graphify — @safishamsi (https://github.com/safishamsi/graphify): KNOWN/INFERRED/UNKNOWN codebase mapping", - "Ponytail — @DietrichGebert (https://github.com/DietrichGebert/ponytail): lazy-senior-dev six-rung hierarchy" - ], - "derivation_note": "Concept + SKILL.md contributed via PR #854. Hardened for this repo: scoped to opt-in activation, embedded multi-method install guide trimmed, plugin.json and layout aligned to the engineering standalone-plugin convention." - } + ] } diff --git a/finance/skills/stock-analysis/SKILL.md b/finance/skills/stock-analysis/SKILL.md new file mode 100644 index 00000000..c32c0046 --- /dev/null +++ b/finance/skills/stock-analysis/SKILL.md @@ -0,0 +1,318 @@ +--- +name: stock-analysis +description: Produce a rigorous, sector-relative, multi-factor fundamental analysis of a publicly listed company — Indian (NSE/BSE) or US/global. Use when the user asks to analyse, research, evaluate, or value a stock, ticker, or listed company; asks whether a business is fundamentally strong, cheap, or expensive; compares companies or benchmarks one against its sector; or mentions OPM, ROCE, ROE, ROIC, P/E, EV/EBITDA, free cash flow, NIM, GNPA, CASA, promoter holding or pledging. Use it for accounting-quality and forensic questions — "is the profit real", "why is profit rising but cash isn't", auditor qualifications, related-party concerns — which route to the forensic-only mode, and for IPOs and not-yet-listed companies — "should I apply to this IPO", DRHP/RHP or S-1 questions, price band, grey market premium — which route to the IPO mode. Use it even when the request sounds casual ("is Infosys any good?"). Do not use it for personalised investment advice, portfolio allocation, or trading signals. +--- + +# Stock Analysis + +Produce an evidence-backed fundamental analysis of one company, benchmarked against the right peers, and delivered as a written report plus a sector-relative scorecard. + +## The principle that governs everything here + +**A financial metric carries no meaning until you know the sector it came from and the company's own history.** + +If X earns a 20% operating margin and Y earns 30%, that tells you nothing about which is the better business. Y may be in software (where 30% is mediocre) and X in distribution (where 20% is exceptional). Y's 30% may need three times the capital to produce, so X earns a far higher return on the money invested. Y's margin may be eroding while X's compounds. + +Two consequences shape this whole skill: + +1. **Never rank companies on a single metric.** Every judgement combines profitability, returns on capital, cash conversion, balance sheet, growth durability, governance, and price. +2. **Compare like with like.** Benchmark against sector peers or against the company's own multi-year record — never a raw cross-industry number. For banks, insurers, REITs and miners the standard ratios are not merely less useful, they are *undefined or inverted*; those sectors need their own metric set entirely. + +Read `references/05-returns-and-dupont.md` for why return on capital, not margin, is the metric that actually determines compounding. + +## Non-negotiables + +### Never invent a number + +This is the failure mode that destroys the value of the whole analysis. A fabricated revenue figure or a hallucinated ROCE produces a confident, well-formatted, *useless* report — and the user may act on it. + +- Every figure carries a **source and a period** ("FY25 annual report, consolidated, p.112" / "10-K FY2024, Item 8" / "Q3 FY26 quarterly results filing, BSE"). +- If a number cannot be sourced, write `not available` and say what would be needed. An analysis with acknowledged gaps is far more valuable than one with invented precision. +- Cross-check headline figures (revenue, net profit, debt, cash) against a second source when possible — at least one of the two must be a primary document. +- **Every financial figure in the analysis must trace to a primary document** — annual report, 10-K/10-Q, quarterly results filing, concall transcript, investor presentation, DRHP/RHP, exchange filing, or rating rationale. Aggregator websites (screener.in, Yahoo Finance, Tikr, etc.) are navigation aids for locating documents and optional labelled cross-checks — they are never a source of record. The one exception is current share price and market cap, which are inherently sourced from exchange or finance websites and must carry an as-of date. +- State **consolidated vs standalone** explicitly — for any company with subsidiaries these differ materially, and mixing them silently invalidates every ratio. +- State **currency and units**. Indian filings use crore/lakh; US filings use millions/billions. Getting this wrong by 10x is a common and embarrassing error. +- Flag stale data. A price or multiple without an as-of date is not usable. + +Detailed sourcing routes and a verification protocol: `references/01-data-sourcing.md`. + +### Official records are the source — and they hold far more than the financial statements + +Two failure modes hide behind a report that looks well-sourced. Guard against both. + +**First: the source of record is the company's own filings — nothing else is.** Rank sources by how many hands the number has passed through, and cite only the primary one: + +1. **Primary filings** — annual report / 10-K, exchange filings (NSE/BSE, SEC EDGAR), quarterly results, the offer document (DRHP/RHP/S-1), audited statements. +2. **Company-published secondary** — concall transcripts, investor presentations, earnings releases. +3. **Regulator / third-party primary** — SEBI/MCA/ROC records, credit-rating rationales, exchange shareholding and pledge data. + +Third-party research notes, brokerage reports, news articles and data aggregators (screener.in, Tikr, Yahoo/Google Finance, trendlyne) are **navigation and cross-check aids only** — they exist to help you *locate* the filing and to flag an outlier worth investigating. An aggregator or news figure must never be the thing you cite; when it disagrees with the filing, the filing wins and the disagreement is itself a finding. The one standing exception is live share price and market cap, which carry an as-of date. If a figure exists only in an aggregator and cannot be traced to a filing, it is `not sourced` — say so. + +**Second: a filing is not just its three financial statements.** Most of what actually decides an analysis is the **non-financial** disclosure wrapped around the numbers, and it must be read and used as a first-class input — not skimmed on the way to the P&L: + +- the **business, strategy and risk-factor** sections — what is sold and to whom, the stated moat, and the risks management is legally obliged to admit; +- **MD&A** read across 3–5 years — growth decomposed into volume / price / mix, capacity, capex plans, order book, guidance, and the drift between what was promised and what was delivered; +- the **auditor's report, CARO annexure, Key Audit Matters and emphasis-of-matter** — the auditor's own map of where the numbers are fragile; +- **related-party transactions, contingent liabilities, litigation and capital commitments** — the commonest routes for value to leave a minority shareholder, and quantifiable in one sitting; +- **governance and ownership** — board and audit-committee composition and independence, promoter holding trend and pledge, remuneration versus profit, auditor tenure and any resignation, AGM voting dissent, ESOP dilution; +- **segment and operational data** — segment-level revenue, EBIT and capital employed (segment ROCE is usually the report's most surprising number), plus the sector KPIs — capacity utilisation, occupancy/ARPOB, ANDA filings, same-store growth, order-book conversion — that never appear in the income statement; +- **ESG/BRSR, secretarial audit (MR-3), and subsidiary (AOC-1) disclosures.** + +`references/15-document-diligence.md` is the runbook for extracting all of this, with a time-boxed reading order. Treat it as part of the core workflow, not an optional deep-dive: an analysis built only on the income statement, balance sheet and cash flow has read perhaps a fifth of the official record and skipped the four-fifths where the moat, the governance and the landmines live. + +### Analysis, not advice + +Produce analysis, evidence, and a reasoned view of business quality and valuation. Do not produce personalised investment advice, position sizing for the user, or buy/sell instructions framed as recommendations for their money. State clearly that the output is research, not licensed financial advice, and that the user is responsible for their own decisions. + +Presenting a bull case, a bear case, a valuation range, and what would falsify the thesis is genuinely useful and stays on the right side of this line. "You should buy 50 shares" does not. + +### Show the reasoning and the uncertainty + +Where an estimate is used (normalised earnings, maintenance capex, mid-cycle margins), say it is an estimate, give the assumption, and show what changes if the assumption is wrong. False precision — a target price to two decimals off a hand-waved growth rate — is worse than an honest range. + +## Choose a depth mode + +Match effort to what the user asked for. Announce which mode you are running so expectations are set. + +| Mode | When | What it covers | +|---|---|---| +| **Screen** | "quick take", "is this worth looking at" | Stages 0–3 plus valuation sanity check. Kill criteria, headline quality metrics, obvious red flags. Short verdict. | +| **Standard** (default) | "analyse this stock" | All stages, moderate depth per stage, full scorecard and report. | +| **Deep dive** | "detailed", "thorough", "maximum depth", or a position the user intends to size | All stages at full depth, situation playbook, document-level diligence, forensic pass, scenario valuation, explicit bear case. | +| **Forensic** | "is the profit real", "are they cooking the books", "cash flow doesn't match profit", "check the accounting" | A different question entirely — *can these accounts bear weight?* Skips business quality, growth and valuation. Follow `references/18-forensic-mode.md`. | +| **IPO** | The company is **not yet trading** — an open or upcoming IPO, a filed DRHP/RHP, "should I apply to X's IPO" | No market price and no public track record, so own-history benchmarking and market-price valuation are both unavailable. Follow `references/19-ipo-mode.md`. | + +## The workflow + +If you are running **Forensic mode**, stop here and follow `references/18-forensic-mode.md` instead — it has its own stages (F0–F5) and its own verdict scale, because "can I trust these numbers?" is not answered by a shorter version of "is this a good investment?". + +If the company is **not yet listed**, stop here and follow `references/19-ipo-mode.md` — stages I0–I7. The workflow below assumes a traded security with a price and a public reporting history, and an IPO has neither. Note the boundary: a company that has *already listed* within the last two years uses this workflow with the recent-IPO overlay in `references/13-situations.md` §8, not IPO mode. + +Otherwise work through these stages in order. Later stages depend on earlier ones — classifying the sector before you compute ratios is what stops you applying the wrong metric set. + +### Stage 0 — Establish identity + +Pin down exactly what is being analysed before touching numbers: + +- Company, exchange, ticker, ISIN. Resolve ambiguity (many names collide across exchanges). +- **Which security**: ordinary shares, dual-class/DVR line, ADR/GDR, or a holdco that owns the operating company. These trade at different prices and confer different rights. +- Reporting currency and fiscal year end (needed to align peers). +- Consolidated or standalone basis for the analysis (consolidated is almost always correct). +- Market cap, enterprise value, free float. + +If any of these do not exist because the company has not begun trading, you are in IPO mode — go to `references/19-ipo-mode.md`. + +### Stage 1 — Acquire data + +Follow `references/01-data-sourcing.md`. This is a **document-first** workflow: obtain the raw company documents before extracting any numbers. + +**Step 1a — Document acquisition.** Before touching any numbers, identify and obtain the following documents (or as many as are available): + +- Latest annual report or 10-K (and ideally the prior 4 years) +- Last 4–8 quarterly results filings from the exchange +- Latest 2 concall / earnings-call transcripts +- Latest investor presentation +- Quarterly shareholding pattern filings (last 4–8 quarters) +- Latest credit rating rationale +- DRHP/RHP if listed within the last 3–4 years + +Source these from the company's investor-relations page, NSE/BSE corporate filings, SEC EDGAR, or equivalent primary repositories. Aggregator websites (screener.in, Tikr, Yahoo Finance) may be used to *locate* these documents — for example, screener.in links to underlying annual reports and concall transcripts — but the aggregator page itself is not the document. + +**Step 1b — Extract the financials.** From the documents obtained above, gather at minimum 5 years of income statement, balance sheet and cash flow; quarterly trend for the last 8 quarters; and the shareholding pattern. Every figure must cite the specific document and page/section it was extracted from. + +**Step 1c — Extract the non-financial record too.** The financial statements are only part of what these documents contain, and often not the part that decides the analysis. From the *same official documents*, extract and carry forward — each with its document and page/section cite: + +- **Business & strategy** — the business-overview and MD&A narrative: what is sold, to whom, the stated moat and strategy, capacity and utilisation, capex plans, order book / backlog. +- **Risk factors** — the management-admitted risks, diffed across years (a risk that silently disappears is a disclosure decision, not a solved problem). +- **Auditor's report, CARO, KAMs, emphasis-of-matter** — opinion type for standalone *and* consolidated, and the specific line items the auditor itself flagged as fragile. +- **Related-party transactions, contingent liabilities, litigation, capital commitments** — including year-end outstanding balances, not just the year's flows. +- **Governance & ownership** — board/audit-committee composition and independence, promoter holding trend and pledge %, remuneration versus PAT, auditor tenure/resignation, AGM voting dissent, ESOP dilution. +- **Segment & operational KPIs** — segment-level revenue / EBIT / capital employed, and the sector operating metrics that never reach the P&L. + +Walk the **entire** annual report section by section — not just the financials, and not only the shortlist above. Almost every section carries something an investor should weigh (the strategy in the chairman's letter, the pay ratio in an annexure, a covenant in a borrowings note, the one live case in an otherwise-routine litigation schedule), so the rule is **consider all of it, then report selectively**: read comprehensively, extract what is material, and let the write-up stay focused — a section that is genuinely empty this year is recorded as "read — nothing material", never skipped unread. `references/15-document-diligence.md` gives both a **complete annual-report contents map** (§0) and the time-boxed reading order (§1) for when to prioritise what. This step is **mandatory in Standard and Deep-dive modes**; even in Screen mode, read at least the auditor's report/opinion, the CARO fraud/statutory-dues/default clauses, and the shareholding-and-pledge pattern before forming a view. An analysis that quotes ratios but never opened the auditor's report or the related-party note is not finished. + +If a required document cannot be obtained, ask the user for it **by name** — not "can you give me more data" but "please upload the FY25 annual report PDF and the last two concall transcripts". If the user provides numbers from an aggregator instead of the document, note them as `aggregator-sourced, unverified` and flag the gap. Do not fill gaps with recalled figures; recalled financials are frequently wrong and always stale. + +**Then run the recency gate before you analyse anything.** This is the most common way a well-built analysis turns out wrong: not bad arithmetic, but a conclusion drawn from data that was already superseded when it was written. Adversarial review of real reports found verdict-level failures caused by results, regulatory decisions and deal approvals that were public *days before* the analysis date and simply absent from it. + +So establish explicitly, and state in the report: + +- **What is the latest period the company has actually reported**, and has a quarter been published since the annual figures you are using? Search for results dated after your newest data point rather than assuming your source is current. +- **What has happened since that period end** — earnings releases, rating actions, regulatory or court decisions, M&A approvals, block deals, management changes, guidance updates. +- **Do any of these already trip the invalidation triggers you are about to write?** A trigger that has already fired is not a future risk; it is a present finding. + +Record the answer as one line: *"Most recent period incorporated: Q1 FY27, published 11-Jul-2026; checked for events to 22-Jul-2026."* A reader cannot judge staleness you have not disclosed. + +**Then verify the data before you compute on it.** Assemble what you gathered into an intake file and run `python scripts/verify_data.py .json` (see `references/21-data-integrity-tools.md`). It is the mechanical enforcement of the sourcing rules above: it catches figures with no source or period, cross-source disagreements (the check that stops a wrong peer number reaching the verdict), silent consolidated/standalone mixing, crore-vs-million unit traps, and periods that a newer release has already superseded. Fix every error-level finding before proceeding; a fast, clean intake is worth more than a fast analysis built on an unchecked one. + +### Stage 2 — Classify sector and situation + +This is the hinge of the whole analysis, because it determines which metrics even apply. + +**Sector** — pick the playbook from the router below and read it before computing anything. +**Situation** — check `references/13-situations.md` for lifecycle overlays (loss-making growth, deep cyclical, turnaround, spin-off, holdco, recent IPO, PSU, serial acquirer, promoter-controlled). A deep cyclical at a trailing P/E of 5 is usually expensive, not cheap; the situation playbook is what stops that error. + +### Stage 3 — Kill-criteria and red-flag screen + +Run this early. Most candidates fail here, and finding out cheaply is the point. + +Read `references/07-forensic-red-flags.md` and `references/08-governance.md`. Screen for: cash flow persistently below profit, receivables growing faster than sales, auditor qualifications or resignations, high or rising promoter pledging, related-party leakage, frequent "one-off" charges, restatements, opaque group structure, and unsustainable leverage. The **anomaly scan** in `references/15-document-diligence.md` §0 maps these to the exact annual-report sections and the abnormal pattern to look for in each — legal-dispute and contingent-liability sizing, related-party tunnelling, and the shareholding-and-pledge trend especially, since these three often surface in the annual report before they surface anywhere else. + +If something serious surfaces, say so prominently and early in the report rather than burying it. A governance red flag can outweigh every positive on the scorecard, and the report should reflect that rather than averaging it away. + +**Escalate to Forensic mode** when a Stage 3 finding is severe enough that valuation becomes pointless until it is resolved — an adverse or qualified audit opinion, cumulative cash flow far below cumulative profit, cash that cannot be evidenced, or related-party leakage. Tell the user you are switching, and why. Valuing a company whose reported earnings you do not believe is wasted work. + +### Stage 4 — Core analysis + +Work through `references/02-core-factors.md`, drawing on: + +- `references/03-earnings-quality.md` — revenue growth decomposition, margin trends, accruals, one-offs, tax normalcy, SBC and dilution +- `references/04-balance-sheet-and-cashflow.md` — leverage, coverage, maturity wall, working capital, OCF vs profit, FCF, capex split +- `references/05-returns-and-dupont.md` — ROIC vs WACC, DuPont decomposition, incremental returns, normalisation +- `references/15-document-diligence.md` — the qualitative record extracted at Stage 1c, now *synthesised alongside the ratios*: MD&A promise-versus-delivery, related-party leakage, contingent liabilities, segment ROCE, governance and auditor signals. The numbers and the narrative are analysed together, not in separate silos. +- The **sector playbook**, which overrides or replaces generic metrics where they do not apply + +Business quality and moat, growth durability and reinvestment runway sit inside `02-core-factors.md`. + +### Stage 5 — Build the peer set and benchmark + +Follow `references/10-peer-set.md`. A wrong peer set produces confidently wrong conclusions, so construct it explicitly and state the basis: same sector and sub-sector, comparable business model and capital intensity, similar accounting regime, aligned fiscal periods. + +Benchmark every key metric two ways — **against peers** and **against the company's own 5–10 year history**. Both matter: a company can beat its peers while decaying against itself. + +### Stage 6 — Value it + +Follow `references/06-valuation.md`. Use the method the **sector playbook** specifies (P/B and ROE for banks, P/EV for life insurers, AFFO and cap rates for REITs, mid-cycle EV/EBITDA for miners, EV/EBITDAR for airlines). Applying a generic P/E across sectors is the valuation equivalent of the OPM mistake. + +Include a reverse-DCF style check — what growth and margin does the current price already assume? — because it converts valuation from an opinion into a testable question. Run `scripts/valuation.py` for the EV bridge, trailing multiples, the reverse-DCF implied growth and the probability-weighted scenario table rather than computing them by hand — it removes arithmetic slips and flags aggressive assumptions (e.g. terminal growth above nominal GDP). + +### Stage 7 — Risk, bear case, invalidation + +Read `references/09-risk-and-macro.md`. Write a genuine bear case, not a strawman: the most credible argument that this is a bad investment. Then state the specific, observable events that would prove the positive thesis wrong. + +### Stage 8 — Score and write + +Score using `references/11-scoring-rubric.md` (run `scripts/score.py` for the arithmetic), then write the report using the template in `references/12-report-template.md`. Before writing, read the worked exemplars in `examples/` to calibrate the target quality: `examples/standard-analysis-example.md` (a full Standard-mode report that passes the linter and embeds real `valuation.py` output) and `examples/forensic-analysis-example.md` (a Forensic-mode review following the F0–F5 template). They are fictional by design — models of *how*, never sources of figures. + +### Stage 9 — Challenge the draft before delivering it + +You wrote the thesis, so you will not attack it as hard as someone else would. Follow `references/20-challenge-pass.md`: identify what the verdict actually rests on, attack those claims, verify the numbers trace to their sources, and test whether the conclusion survives a different peer set and a different weight preset. + +Mandatory in Deep dive. Recommended in Standard. Skip in Screen, where the conclusion is explicitly provisional. **If you can spawn subagents, use them** — independence is the mechanism, and an author reviewing their own work is a weak substitute. + +The point is that the verdict can move. A challenge pass that only ever adds caveats to an already-written conclusion manufactures false confidence and is worse than none. + +### Stage 10 — Lint before delivering + +Run `python scripts/lint_report.py .md` (see `references/21-data-integrity-tools.md`). It is a mechanical last check that the report honours the non-negotiables: a recency statement and data-quality note are present, basis and units are stated, a scorecard is not shown without its gate disclosure, a bear case and disclaimer exist, and — the core check — that financial figures sit near a source rather than floating free. Treat error-level findings as blocking and fix them; a low figure-sourcing ratio means go back and cite, not ship. The linter is a floor, not a substitute for judgement. + +Save the report as a markdown file named `-analysis-.md` unless the user asks otherwise, and summarise the key findings in chat. + +## Sector router + +Read the matching playbook at Stage 2. When a company spans several sectors, use the segment that drives most of the profit and note the others; conglomerates go to the holdco playbook and are valued sum-of-the-parts. + +| If the company is… | Read | +|---|---| +| A bank or lender taking deposits | `references/sectors/banks.md` | +| An NBFC, housing finance or non-bank lender | `references/sectors/nbfc.md` | +| A mortgage REIT, BDC, private-credit vehicle, equipment lessor or leasing company | `references/sectors/mortgage-reit-specialty-finance.md` | +| A life, general, health or P&C insurer | `references/sectors/insurance.md` | +| An insurance broker, MGA, TPA or distribution platform — places risk but underwrites none | `references/sectors/insurance-brokers-services.md` | +| IT services, software, SaaS, internet platform | `references/sectors/it-saas.md` | +| Staffing, consulting, advertising, outsourced professional and business services | `references/sectors/people-businesses.md` | +| Pharma, CDMO, hospitals, diagnostics, medical devices | `references/sectors/pharma-healthcare.md` | +| A pre-revenue, clinical-stage drug developer with no approved product | `references/sectors/biotech-clinical.md` | +| FMCG, consumer staples, branded consumer, QSR | `references/sectors/fmcg-consumer.md` | +| Automobiles, auto components, tyres | `references/sectors/auto.md` | +| Steel, aluminium, mining, other commodity producers | `references/sectors/metals-mining.md` | +| Oil & gas — upstream, refining, marketing, gas utilities | `references/sectors/oil-gas.md` | +| Power generation, transmission, regulated utilities | `references/sectors/utilities-power.md` | +| Waste collection and disposal, landfills, recycling, water and wastewater treatment | `references/sectors/waste-environmental.md` | +| Real estate developers, REITs, InvITs | `references/sectors/realestate-reit.md` | +| Infrastructure, EPC, capital goods, defence | `references/sectors/infra-capitalgoods.md` | +| Telecom, towers, broadcasting, media, OTT | `references/sectors/telecom-media.md` | +| Airlines, hotels, travel, restaurants, OTAs | `references/sectors/aviation-hotels.md` | +| Retail chains, e-commerce, marketplaces, quick commerce | `references/sectors/retail-ecommerce.md` | +| Specialty chemicals, agrochemicals, fertilisers, cement | `references/sectors/chemicals-cement.md` | +| Holding companies, conglomerates, AMCs, alternative managers | `references/sectors/holdco-assetmgr.md` | +| Shipping, tankers, dry bulk, ports, trucking, logistics | `references/sectors/shipping-logistics.md` | +| Railroads and rail freight networks | `references/sectors/rail-freight.md` | +| Exchanges, depositories, clearing houses, rating agencies, card and payment networks | `references/sectors/exchanges-payments.md` | +| Semiconductors, fabs, equipment, capital-intensive hardware | `references/sectors/semiconductors.md` | + +If none fits cleanly, use `references/02-core-factors.md` with the generic ratio set and say in the report that no specialised playbook applied — then be extra careful about which standard metrics are actually meaningful for that business model. + +## Bundled scripts + +Run these rather than recomputing by hand; they remove arithmetic slips and keep results consistent between analyses. + +- `scripts/ratios.py` — takes a small JSON of raw financials and returns the full ratio set, DuPont decomposition, accrual and cash-conversion checks. `python scripts/ratios.py --help` +- `scripts/score.py` — sector-relative multi-factor scoring with editable benchmarks and category weights. `python scripts/score.py --help` + - For a company with materially different businesses, pass a `segments` array and each segment is scored against its own sector's benchmarks and blended by profit — `python scripts/score.py --example-segments` prints a runnable example. The blend is a quality summary, never a substitute for sum-of-the-parts valuation. +- `scripts/valuation.py` — Stage-6 valuation calculator: EV bridge, trailing multiples, the reverse-DCF implied-growth solve, a forward 2-stage DCF, and a probability-weighted scenario table. Runs only the sections whose inputs you supply, and guards invalid assumptions (terminal growth ≥ WACC fails). `python scripts/valuation.py --template` / `--example` +- `scripts/verify_data.py` — data-intake gate. Validates gathered figures for provenance, **source tier (documents primary, aggregators navigation-only)**, cross-source agreement, basis/unit consistency and staleness before you compute on them. Run it at Stage 1. `python scripts/verify_data.py --template` +- `scripts/lint_report.py` — finished-report QA. Checks the non-negotiables and the figure-sourcing ratio before delivery. Run it at Stage 10. `python scripts/lint_report.py --help` + +Both are plain Python with no third-party dependencies. Sector benchmark tables live in `scripts/benchmarks.json` and are meant to be edited — treat the shipped values as reasonable defaults, not gospel, and override them when you have better peer data for the specific market and period. + +## Output contract + +Deliver two things, always: + +1. **The report** — follow `references/12-report-template.md`. It opens with the verdict and the key risks, because a reader who stops after the first screen should still get the substance. +2. **The scorecard** — sector-relative scores by category with the weights shown, plus the composite. Show the inputs so the reader can disagree with a specific number rather than the whole thing. + +Include the data-quality note: which figures are sourced, which are estimated, which are missing, and the as-of date. + +## Reference index + +Read these as needed; they are written to be consulted individually rather than all at once. + +| File | Use it for | +|---|---| +| `references/01-data-sourcing.md` | Where to get data for India and global markets, and how to verify it | +| `references/02-core-factors.md` | The universal multi-factor checklist: business, moat, industry, growth | +| `references/03-earnings-quality.md` | Income statement analysis and earnings quality | +| `references/04-balance-sheet-and-cashflow.md` | Solvency, liquidity, working capital, cash generation | +| `references/05-returns-and-dupont.md` | ROIC/ROCE/ROE, DuPont, incremental returns, why margin alone misleads | +| `references/06-valuation.md` | Every valuation method, EV bridge, WACC derivation, reverse DCF, scenarios | +| `references/07-forensic-red-flags.md` | Accounting manipulation and fraud detection | +| `references/08-governance.md` | Management, promoters, board, auditors, related parties | +| `references/09-risk-and-macro.md` | Company, macro, regulatory, ESG and tail risks | +| `references/10-peer-set.md` | Constructing a defensible like-for-like comparison set | +| `references/11-scoring-rubric.md` | The sector-relative multi-factor scoring method | +| `references/12-report-template.md` | The exact output structure | +| `references/13-situations.md` | Lifecycle overlays: cyclicals, turnarounds, holdcos, IPOs, PSUs | +| `references/14-accounting-comparability.md` | IFRS/GAAP/Ind-AS differences, leases, restatements, normalisation | +| `references/15-document-diligence.md` | Annual report, auditor's report, CARO, KAM, transcripts, rating rationales | +| `references/16-market-mechanics-and-tax.md` | Surveillance, corporate actions, dilution instruments, taxation | +| `references/17-process-and-epistemics.md` | Circle of competence, falsification, base rates, when to say no | +| `references/18-forensic-mode.md` | Forensic-only runbook: triage battery, verdict scale, output template | +| `references/19-ipo-mode.md` | Not-yet-listed companies: DRHP/RHP, seller motive, valuing the price band | +| `references/20-challenge-pass.md` | Adversarial review before delivery: attack the load-bearing claims | +| `references/21-data-integrity-tools.md` | The intake gate and report linter: how and when to run them | +| `references/sectors/_index.md` | Sector router with sub-sector guidance | + +## Anti-Patterns + +- Judging a bank, insurer, REIT, or miner on generic ratios — for these sectors the standard ratios are undefined or inverted; route through the sector playbook first. +- Inventing or interpolating a number instead of writing "not available" with the reason. +- Averaging a disqualifying red flag into a composite score instead of letting it cap or void the verdict. +- Treating aggregator or screener figures as primary evidence — they navigate; filings decide. +- Running every reference on every company — three or four factors decide most outcomes. +- Presenting output as investment advice — the deliverable is analysis, never an allocation or a trading signal. + +## Cross-References + +- `finance/skills/financial-analyst` — inside-out corporate FP&A, budgeting, and DCF modelling for a company you operate; this skill is the outside-in public-market view of a listed company. +- `finance/business-investment-advisor` — internal capex and project-ROI decisions; this skill values traded equity, not internal projects. +- `finance/skills/saas-metrics-coach` — operating SaaS metrics (NRR, CAC, burn) for internal steering, not listed-equity valuation. + +## A note on judgement + +These references are extensive, and working through all of them mechanically produces a long document rather than an insight. The point of the depth is that you can reach for the right tool, not that every tool gets used on every company. + +For most companies, three or four factors genuinely decide the outcome — a moat that is widening or narrowing, returns on incremental capital, whether cash follows profit, and whether the price already assumes success. Identify those, evidence them properly, and let the rest of the checklist do its real job: making sure nothing disqualifying was missed. + +If the business sits outside what can be understood with the available information, say so. Declining to analyse is a legitimate and useful answer. diff --git a/finance/skills/stock-analysis/evals/evals.json b/finance/skills/stock-analysis/evals/evals.json new file mode 100644 index 00000000..c02672b0 --- /dev/null +++ b/finance/skills/stock-analysis/evals/evals.json @@ -0,0 +1,132 @@ +{ + "skill_name": "stock-analysis", + "evals": [ + { + "id": 0, + "name": "bank-sector-routing", + "prompt": "can you take a look at HDFC Bank for me? want to know if it's fundamentally strong or if i'm better off elsewhere. people keep saying it's cheap now", + "expected_output": "A sector-aware analysis that routes to the banks playbook: uses NIM, CASA, ROA, GNPA/NNPA, slippages, credit cost, PCR, CAR/CET1, cost-to-income; explicitly declines to use OPM/ROCE/EV-EBITDA/FCF as inapplicable to a bank; values on P/B against ROE vs cost of equity rather than a generic P/E; cites sources with as-of dates; does not give personalised buy/sell advice.", + "files": [], + "assertions": [ + "Does NOT report OPM, ROCE, EV/EBITDA or free cash flow as headline metrics for the bank, or explicitly states they are inapplicable to a deposit-taking lender", + "Uses at least five bank-specific metrics from: NIM, CASA, ROA, GNPA, NNPA, slippage ratio, credit cost, PCR, CAR/CET1, cost-to-income, LCR", + "Anchors valuation on price-to-book (or price-to-adjusted-book) referenced to ROE versus cost of equity, rather than concluding from P/E alone", + "Every headline financial figure is accompanied by a source and a reporting period", + "Contains an explicit data-quality note covering as-of date and consolidated-vs-standalone basis", + "Addresses the user's 'people say it's cheap' premise directly rather than ignoring it", + "Includes a bear case or key-risks section", + "Contains a not-financial-advice disclaimer and gives no personalised buy/sell instruction" + ] + }, + { + "id": 1, + "name": "cross-sector-margin-trap", + "prompt": "TCS runs about 24% operating margin and Avenue Supermarts (DMart) is around 8%. TCS looks far better on margins so it should be the stronger business right?", + "expected_output": "Directly challenges the single-metric premise. Explains margin is sector-bound and not comparable across IT services and grocery retail; brings in asset turnover and DuPont to show a low-margin high-turnover retailer can earn comparable or superior returns on capital; compares ROIC/ROCE, cash conversion, growth durability and reinvestment runway; benchmarks each within its own sector and own history; refuses to declare a winner on margin alone.", + "files": [], + "assertions": [ + "Explicitly rejects the premise that a higher operating margin implies the stronger business", + "Explains why margins are structurally not comparable across these two sectors (e.g. gross-vs-net revenue recognition, value-add base, capital intensity)", + "Introduces asset turnover and/or an explicit DuPont decomposition", + "Compares return on capital (ROCE, ROIC or ROE) for both companies as the cross-sector-valid measure", + "Benchmarks each company against its OWN sector peers rather than against each other on margin", + "Separates the question of business quality from the question of valuation / which is the better buy", + "Does not declare a winner on the basis of margin alone" + ] + }, + { + "id": 2, + "name": "deep-dive-bear-case", + "prompt": "do a thorough fundamental analysis of Tata Motors - I want the full picture including what could go wrong. thinking about a reasonably sized position so don't sugarcoat it", + "expected_output": "Runs deep-dive mode: identifies the auto sector playbook and the situation overlay (cyclical, multi-segment, historically leveraged); separates automotive net debt from the captive finance arm; uses EBITDA per vehicle, volumes vs registrations, capex plus capitalised product development, mid-cycle ROIC; values sum-of-the-parts rather than a single consolidated multiple; includes a serious bear case and specific thesis-invalidation triggers.", + "files": [], + "assertions": [ + "Analyses the business by segment rather than as a single consolidated entity", + "Separates automotive net debt/cash from any captive finance or lending arm, or explains why that separation matters", + "Values using sum-of-the-parts or segment-level multiples rather than one consolidated P/E", + "Uses at least three auto-sector-specific metrics (e.g. EBITDA per vehicle, wholesale vs retail registrations, capex plus capitalised product development, mid-cycle ROIC, capacity utilisation, discount per unit)", + "Applies a cyclical or situation overlay, including the risk of capitalising peak or trough earnings", + "Contains a substantive bear case that is genuinely argued, not a token risk list", + "States specific, observable thesis-invalidation triggers", + "Includes a data-quality note with as-of dates and sources", + "Gives no personalised position sizing despite the user hinting at one" + ] + }, + { + "id": 3, + "name": "document-grounded-red-flags", + "prompt": "I've attached selected extracts from Kesar Agro Industries' FY26 annual report. Is this a fundamentally sound company worth investing in?", + "expected_output": "A document-grounded read that surfaces the planted abnormalities from the extracts rather than a generic bullish summary: the qualified audit opinion and the unprovided ₹180 cr interest-free related-party advance, the going-concern material uncertainty, related-party tunnelling (loans growing, below-market sales to promoter entities), contingent liabilities (₹420 cr) exceeding net worth (₹350 cr), promoter pledge rising to 71%, the CARO findings (bank returns disagreeing with books, evergreening, unpaid statutory dues, loan default), the CFO churn and mid-year auditor resignation, and the profit-vs-cash divergence. It should escalate these prominently, decline to give a clean bullish verdict, cite the document, and not fabricate figures not in the extract.", + "files": ["fixtures/synthetic-ar-excerpt.md"], + "assertions": [ + "Surfaces the qualified audit opinion and the unprovided related-party advance (~₹180 cr) to the promoter entity", + "Flags the going-concern material uncertainty and the term-loan default disclosed in CARO", + "Identifies related-party leakage / tunnelling (growing interest-free loans and/or below-market sales to promoter-linked entities)", + "Notes that contingent liabilities (~₹420 cr) exceed net worth (~₹350 cr)", + "Flags the promoter share pledge rising sharply (to ~71% of promoter holding)", + "Notes the profit-rising-while-CFO-negative divergence, or the CARO bank-returns-vs-books disagreement, or the CFO/auditor turnover", + "Does NOT conclude the company is fundamentally sound / a clear buy; treats governance and accounting findings as potentially disqualifying", + "Attributes findings to the annual-report extract and does not invent figures absent from it" + ] + }, + { + "id": 4, + "name": "forensic-mode-routing", + "prompt": "Profit at Kesar Agro keeps rising every year but I heard the cash flow is actually negative. Are they cooking the books? I've attached extracts from their FY26 annual report.", + "expected_output": "Routes to Forensic mode (the question is 'can these accounts bear weight?', not 'is this a good investment?'). Runs the cash-vs-earnings accruals work (cumulative CFO far below cumulative PAT), a proof-of-cash test (interest income of ~₹3 cr on ~₹200 cr of cash implies a ~1.5% yield versus much higher borrowing cost), reads the CARO bank-returns-vs-books disagreement and the receivables build, and reaches a forensic verdict about how much the numbers can be trusted. It should NOT pivot into a valuation, target price or buy/sell call, because valuing earnings you do not believe is wasted work.", + "files": ["fixtures/synthetic-ar-excerpt.md"], + "assertions": [ + "Explicitly frames this as a forensic / earnings-quality question rather than a standard buy-side analysis", + "Compares reported profit against operating cash flow over multiple years (accruals / cash-conversion gap)", + "Runs a proof-of-cash or interest-income-vs-cash check, or otherwise questions the reported cash balance", + "Uses the CARO bank-statement-vs-books disagreement and/or the receivables build as evidence", + "Reaches a verdict about the reliability of the accounts rather than a price target", + "Does NOT produce a valuation, target price, or personalised buy/sell recommendation" + ] + }, + { + "id": 5, + "name": "recency-gate-stale-data", + "prompt": "It's August 2026. A friend built this summary of Meridian Industries from their FY25 (year ended March 2025) annual report: revenue ₹8,400 cr, net profit ₹610 cr, net debt ₹1,200 cr, at a share price around ₹950. Is the stock cheap right now?", + "expected_output": "Runs the recency gate before answering: recognises that FY25 (March-2025) data is roughly 15+ months old as of August 2026, that FY26 annual results and at least one FY27 quarter have almost certainly been reported since, and that a 'cheap right now' judgement cannot rest on superseded figures or a stale price. It should state the most-recent-period problem explicitly, decline to deliver a current valuation verdict on the stale data, and say what it would need (the latest annual and quarterly filings, a current price with an as-of date).", + "files": [], + "assertions": [ + "Explicitly flags that the FY25 (March-2025) figures are stale as of August 2026 and that newer periods (FY26, and likely an FY27 quarter) should exist", + "Runs or references a recency check rather than analysing the provided numbers as if current", + "Does not deliver a definitive 'cheap' / 'expensive' verdict resting on the 15-month-old figures without flagging the staleness", + "States what current data would be needed (latest annual + quarterly filings, current price with an as-of date)", + "Treats the provided figures as needing verification against the primary filings rather than as established facts" + ] + }, + { + "id": 6, + "name": "ipo-mode-drhp", + "prompt": "Should I apply to the Vayu Mobility IPO? I've attached extracts from their DRHP. The price band is ₹590–620.", + "expected_output": "Routes to IPO mode (no market price history, no own-history benchmark). Flags that the offer is overwhelmingly an Offer for Sale (₹1,500 cr of ₹1,800 cr) with only ₹300 cr of fresh capital, i.e. insiders and the PE fund are cashing out; notes the ~3x pre-IPO price step-up within four months; scrutinises the bespoke 'Adjusted EBITDA' add-backs that recur every year; surfaces the promoter's pending criminal proceedings, customer concentration and negative operating cash flow; and assesses the ₹590–620 band on multiples / a forward view rather than any own-history or market-price method. No personalised apply/avoid instruction framed as advice.", + "files": ["fixtures/synthetic-drhp-excerpt.md"], + "assertions": [ + "Recognises IPO mode: no trading history, so own-history benchmarking and market-price valuation are unavailable", + "Flags that the offer is mostly an Offer for Sale (sellers cashing out) with little fresh capital entering the business", + "Notes the steep pre-IPO placement price step-up relative to the price band", + "Scrutinises the non-GAAP 'Adjusted EBITDA' add-backs, noting the excluded costs recur every year", + "Surfaces at least one of: promoter criminal litigation, customer concentration, negative operating cash flow, or the restatement adjustments", + "Assesses the price band using multiples or a forward view rather than own-history or market-price methods", + "Gives no personalised 'apply' / 'avoid' instruction framed as investment advice" + ] + }, + { + "id": 7, + "name": "aggregator-primary-source-discipline", + "prompt": "Here's what screener.in shows for Aarti Foods: revenue ₹4,200 cr, PAT ₹310 cr, ROCE 19%, total debt ₹500 cr. Based on this, is it a good business?", + "expected_output": "Treats the pasted aggregator figures as unverified and not a source of record: it explains that screener.in and similar aggregators are navigation aids for locating the actual filings, not citable sources, and that the analysis must trace these numbers to the company's own annual report and exchange filings (checking consolidated-vs-standalone basis, period, and units) before relying on them. It should proceed with the figures marked as aggregator-sourced / unverified, or ask for the primary documents by name, rather than delivering a confident verdict citing screener as the source.", + "files": [], + "assertions": [ + "States that aggregator data (screener.in) is a navigation aid, not a source of record, and should be verified against the primary filings", + "Does not present the pasted screener figures as sourced facts underpinning a final verdict", + "Marks the provided figures as aggregator-sourced / unverified, or asks for the annual report and exchange filings by name", + "Notes at least one verification concern that the aggregator figure hides (consolidated vs standalone, period/as-of, units, or definition of ROCE/debt)", + "Any provisional read is explicitly caveated as resting on unverified aggregator data" + ] + } + ] +} diff --git a/finance/skills/stock-analysis/evals/fixtures/synthetic-ar-excerpt.md b/finance/skills/stock-analysis/evals/fixtures/synthetic-ar-excerpt.md new file mode 100644 index 00000000..20e2f826 --- /dev/null +++ b/finance/skills/stock-analysis/evals/fixtures/synthetic-ar-excerpt.md @@ -0,0 +1,123 @@ +# Kesar Agro Industries Limited — Selected extracts from the FY26 Annual Report + +> **FICTIONAL TEST FIXTURE.** Kesar Agro Industries Ltd does not exist. These +> extracts were written to exercise the stock-analysis skill's red-flag, +> forensic and document-diligence behaviour against a document that contains +> several deliberately planted abnormalities. All figures are invented. Do not +> treat any number here as real, and do not reuse these figures for any real +> company. Consolidated basis, Ind-AS, ₹ crore unless stated. + +--- + +## 1. Five-year financial highlights (₹ crore, consolidated) + +| Metric | FY22 | FY23 | FY24 | FY25 | FY26 | +|---|---:|---:|---:|---:|---:| +| Revenue from operations | 1,420 | 1,610 | 1,880 | 2,190 | 2,560 | +| Reported net profit (PAT) | 34 | 41 | 48 | 55 | 61 | +| Cash flow from operations (CFO) | 6 | (18) | (30) | (52) | (70) | +| Trade receivables | 320 | 402 | 511 | 660 | 858 | +| Cash & bank balances | 90 | 128 | 165 | 190 | 210 | +| Total borrowings | 210 | 265 | 330 | 395 | 450 | +| Net worth | 250 | 285 | 312 | 335 | 350 | + +Interest and investment income for FY26 (Note 21, "Other income"): **₹3 cr**. +Finance cost for FY26 (Note 22): **₹47 cr** on average borrowings of ~₹430 cr. + +--- + +## 2. Extract from the Independent Auditor's Report (Consolidated) + +**Qualified Opinion.** In our opinion, except for the effects of the matter +described in the Basis for Qualified Opinion section, the consolidated financial +statements give a true and fair view… + +**Basis for Qualified Opinion.** The Group has an outstanding advance of +**₹180 crore** to Kesar Estates Private Limited, an entity in which the promoter +and his relatives hold a controlling interest. The advance is interest-free, has +no stipulated repayment schedule, and has been outstanding and growing for three +financial years. Management has not made any provision against this advance. We +are unable to obtain sufficient appropriate audit evidence regarding its +recoverability. Had a provision been made, profit before tax for the year would +have been lower by ₹180 crore and net worth would have been correspondingly +reduced. + +**Material Uncertainty Related to Going Concern.** We draw attention to Note 41. +A term loan of ₹95 crore was overdue for repayment as at the balance-sheet date, +and the Group's ability to continue as a going concern depends on successful +refinancing and continued support from lenders. These events indicate a material +uncertainty that may cast significant doubt on the Group's ability to continue as +a going concern. Our opinion is not further modified in respect of this matter. + +**Key Audit Matter — Recoverability of trade receivables.** Trade receivables of +₹858 crore include ₹210 crore outstanding for more than 365 days. The expected +credit loss allowance of ₹9 crore represents management's judgement… + +--- + +## 3. Extract from the CARO 2020 Annexure + +- **Clause 3(ii)(b).** The Group has been sanctioned working-capital limits in + excess of ₹5 crore on the security of current assets. The quarterly returns + filed by the Company with its banks **are not in agreement with the books of + account**; the receivables reported to lenders exceeded the books by + approximately **₹60 crore** in three of the four quarters. Management is in the + process of reconciling the difference. +- **Clause 3(iii)(e).** Fresh loans of ₹40 crore were granted to a related party + during the year to settle earlier loans that had become overdue (evergreening). +- **Clause 3(vii)(a).** Undisputed statutory dues of **₹22 crore** (goods and + services tax ₹14 crore, provident fund ₹5 crore, tax deducted at source ₹3 + crore) were **in arrears for more than six months** as at 31 March 2026. +- **Clause 3(ix)(a).** The Group **defaulted** in repayment of a term loan of + ₹95 crore to a bank; the default has continued for 120 days as at year-end. +- **Clause 3(xviii).** The statutory auditors for the previous year **resigned** + during the current year. The incoming auditor has considered the issues raised + by the outgoing firm in its resignation letter, which cited "information and + explanations sought not being made available in a timely manner." + +--- + +## 4. Related-party transactions (Note 38, extract) + +| Related party | Nature | FY24 | FY25 | FY26 | +|---|---|---:|---:|---:| +| Kesar Estates Pvt Ltd (promoter-controlled) | Advance / loan given, year-end balance | 40 | 95 | 180 | +| Kesar Estates Pvt Ltd | Interest charged on above | 0 | 0 | 0 | +| Sunrise Distributors LLP (promoter relative) | Sales of goods | 180 | 240 | 300 | +| — of which gross margin realised | | 4% | 3% | 2% | +| Third-party distributor sales — gross margin | | 11% | 11% | 10% | +| Promoter & relatives | Managerial remuneration | 9 | 12 | 18 | + +Managerial remuneration to the promoter family rose to ₹18 crore in FY26 +(FY25: ₹12 crore), i.e. ~30% of consolidated PAT. + +--- + +## 5. Contingent liabilities and commitments (Note 39, extract) + +| Item | FY26 (₹ cr) | +|---|---:| +| Disputed tax demands (income tax + GST), matters in appeal | 120 | +| Corporate guarantee given for borrowings of Kesar Estates Pvt Ltd | 300 | +| **Total contingent liabilities** | **420** | + +(Net worth as at 31 March 2026: ₹350 crore.) + +--- + +## 6. Shareholding pattern and promoter encumbrance (last four quarters) + +| Quarter | Promoter holding (% of equity) | Pledged (% of promoter holding) | +|---|---:|---:| +| Jun 2025 | 58.0% | 18% | +| Sep 2025 | 58.0% | 34% | +| Dec 2025 | 57.6% | 55% | +| Mar 2026 | 57.6% | 71% | + +--- + +## 7. Board and management (Corporate Governance Report, extract) + +The Company has had **three Chief Financial Officers in the last four years**. +The current CFO was appointed in January 2026. The Audit Committee met twice +during FY26. The Chairman is also the Managing Director and promoter. diff --git a/finance/skills/stock-analysis/evals/fixtures/synthetic-drhp-excerpt.md b/finance/skills/stock-analysis/evals/fixtures/synthetic-drhp-excerpt.md new file mode 100644 index 00000000..9f38b0e4 --- /dev/null +++ b/finance/skills/stock-analysis/evals/fixtures/synthetic-drhp-excerpt.md @@ -0,0 +1,81 @@ +# Vayu Mobility Limited — Selected extracts from the DRHP (Draft Red Herring Prospectus) + +> **FICTIONAL TEST FIXTURE.** Vayu Mobility Ltd does not exist. These extracts +> were written to exercise the stock-analysis skill's IPO-mode behaviour against +> an offer document containing several deliberately planted issues. All figures +> are invented. Do not treat any number here as real. ₹ crore unless stated. + +--- + +## 1. The Offer (Objects of the Issue) + +Total offer size at the upper price band: **₹1,800 crore**, comprising: + +- **Fresh issue: ₹300 crore.** + - Repayment/prepayment of certain borrowings: ₹120 crore + - Funding capital expenditure (new hubs): ₹60 crore + - **General corporate purposes: ₹120 crore** +- **Offer for Sale (OFS): ₹1,500 crore**, comprising: + - Aurora Capital Fund II (private-equity investor): ₹1,050 crore + - Promoter — Mr R. Vaidyanathan and family: ₹450 crore + +Price band: **₹590–₹620 per equity share** (face value ₹5). + +Only ₹300 crore of the ₹1,800 crore offer represents fresh capital entering the +business; the remaining ₹1,500 crore accrues to selling shareholders. + +--- + +## 2. Pre-IPO placement and prior transactions + +In **March 2026** (approximately four months before this filing), the Company +allotted equity shares to a group of investors at **₹210 per share**. The IPO +price band of ₹590–₹620 represents an increase of roughly **2.8x–3.0x** over that +price within four months. + +--- + +## 3. Restated financial information (extract) + +| Metric (₹ cr) | FY24 | FY25 | FY26 | +|---|---:|---:|---:| +| Revenue from operations | 2,050 | 2,760 | 3,540 | +| Restated profit / (loss) for the year | (45) | 12 | 88 | +| Net cash from operating activities | (160) | (95) | 40 | +| **Adjusted EBITDA (as presented by the Company)** | 95 | 210 | 360 | + +The Company presents "Adjusted EBITDA", a non-GAAP measure, which excludes +employee stock-option expense, "one-time" branch-launch and logistics-onboarding +costs, and share-based payments. Such branch-launch and logistics-onboarding +costs have been incurred in each of the last three financial years. + +The restated financial statements reflect **seven restatement adjustments**, +including a correction to the timing of revenue recognition on certain +subscription contracts and the reclassification of "one-time" costs. + +--- + +## 4. Selected Risk Factors (extract) + +- Two of our top three customers accounted for **61% of revenue** in FY26. +- We have reported **negative net cash from operating activities in two of the + last three financial years**. +- There are outstanding criminal proceedings against our Promoter, including a + proceeding under Section 138 of the Negotiable Instruments Act (cheque + dishonour) and a proceeding relating to alleged tax evasion, each pending + before the relevant court. +- A tax authority has raised a demand of **₹85 crore** against the Company, which + we have disputed and which is pending in appeal. +- Our Promoter will continue to hold 46% of the post-issue paid-up capital and + will retain significant control. + +--- + +## 5. Lock-in + +- Promoter's contribution (minimum 20% of post-issue capital): locked in for + **18 months** from the date of allotment. +- Anchor investor shares: 50% locked in for 90 days and 50% for 30 days from the + date of allotment. +- Pre-IPO placement shares (allotted March 2026): locked in for six months from + the date of allotment. diff --git a/finance/skills/stock-analysis/examples/README.md b/finance/skills/stock-analysis/examples/README.md new file mode 100644 index 00000000..2bb69eae --- /dev/null +++ b/finance/skills/stock-analysis/examples/README.md @@ -0,0 +1,23 @@ +# Worked examples — gold-standard reference analyses + +These are **illustrative exemplars**: complete analyses the skill is meant to +produce, written so a new run can see the target quality rather than infer it +from the template alone. Read them alongside `references/12-report-template.md` +(structure) — the template shows the *shape*, these show the *bar*. + +**Every company here is fictional and every figure is invented.** That is +deliberate: it lets the numbers be internally consistent and freely shown +without any risk of presenting fabricated data about a real company as if it +were sourced. In a real analysis the same citations (`[FY26 AR, p.112]`) must +point at real documents, and the non-negotiables — never invent a number, +document-first sourcing, the recency gate — apply in full. **Do not lift any +figure from these files into a real analysis.** + +| File | Mode | What it demonstrates | +|---|---|---| +| `standard-analysis-example.md` | Standard | The full workflow on a (fictional) FMCG franchise: sector playbook and suppressed metrics, DuPont, working-capital and cash-conversion analysis, a document-sourced data-quality note with source tiers, a sector-relative scorecard with the gate disclosure, `valuation.py` output (EV bridge, trailing multiples, reverse-DCF implied growth, scenario table), a genuine bear case, and observable invalidation triggers. Passes `scripts/lint_report.py`. | +| `forensic-analysis-example.md` | Forensic | A forensic read of the `evals/fixtures/synthetic-ar-excerpt.md` extracts (fictional Kesar Agro): the F0–F5 runbook, the accruals and proof-of-cash tests, the CARO and related-party evidence, and a "can these accounts bear weight?" verdict that stops short of valuation on purpose. | + +Both were checked with the bundled gates: the standard example passes +`python scripts/lint_report.py`, and its valuation section is the verbatim output +of `python scripts/valuation.py` on the same inputs. diff --git a/finance/skills/stock-analysis/examples/forensic-analysis-example.md b/finance/skills/stock-analysis/examples/forensic-analysis-example.md new file mode 100644 index 00000000..13593e39 --- /dev/null +++ b/finance/skills/stock-analysis/examples/forensic-analysis-example.md @@ -0,0 +1,84 @@ +# Forensic review — Kesar Agro Industries (NSE: KESARAGRO) + +> **ILLUSTRATIVE EXAMPLE — FICTIONAL COMPANY.** Kesar Agro Industries Ltd does +> not exist. This is a worked exemplar of the skill's Forensic-mode output, run +> against the extracts in `evals/fixtures/synthetic-ar-excerpt.md`. Every figure +> is invented. It illustrates method and tone — including the discipline of +> describing what disclosure shows without asserting fraud — not a real finding. + +**Verdict: D — Structural integrity risk.** +As of 2026-08-02 · Basis: Consolidated · Currency/units: INR crore +Most recent period incorporated: FY26 (ended 31-Mar-2026), audited. Pre-Q1-FY27. + +--- + +## Document base + +**Obtained:** FY26 annual report extracts — five-year highlights, Independent Auditor's Report (consolidated), CARO 2020 annexure, related-party note (38), contingent-liabilities note (39), four-quarter shareholding/pledge pattern, corporate-governance extract [all: Kesar Agro FY26 AR extract, §1–§7]. + +**Not obtained (and what each would test):** full notes to accounts and receivables ageing table (extent of the ₹210 cr >365-day receivable and its provisioning); MCA/ROC filings of Kesar Estates Pvt Ltd (whether the ₹180 cr advance is recoverable); prior-year annual reports in full (silent restatements); concall transcripts (management's account of the default and going-concern); rating rationale (liquidity grade). This is a **filings-extract-only** pass — but note that verdict D here rests on the auditor's own qualified opinion, which is decisive from the documents in hand. + +## Summary + +The accounts cannot be relied upon as presented. The auditor has issued a **qualified opinion** over an unprovided ₹180 cr interest-free advance to a promoter-controlled entity, and separately flags a **material uncertainty over going concern** [§2]. Independently, reported profit rose every year FY22–FY26 while operating cash flow was **negative and worsening** across the same period [§1], and the CARO annexure reports a term-loan default, unpaid statutory dues, evergreening, and — most concretely — that the receivables the company reported to its banks **do not agree with its books** [§3]. Several independent flags converge on the same place: profit has gone into receivables and related-party advances, not cash. The single most load-bearing unresolved item is the ₹180 cr advance, which alone exceeds three years of cumulative reported profit. + +## Triage results + +| # | Test | Result | Reading | +|---|---|---|---| +| 1 | Cash conversion (5y cumulative CFO/PAT) | CFO Σ(FY22–26) = −₹164 cr vs PAT Σ = +₹239 cr → **−0.69** [§1] | Profit is not becoming cash; it is reversing into cash *out*flow. Caps composite at 4.0. | +| 2 | Implied yield on cash vs short rates | Interest income ₹3 cr ÷ avg cash ~₹200 cr = **~1.5%**, vs ~11% paid on borrowings [§1] | Cash earns far below the rate paid to borrow; either restricted/encumbered or not fully there. Cost of carry is value-destructive with no stated reason. | +| 3 | Receivables vs sales | Receivables CAGR **27.9%** vs revenue CAGR **15.9%** (FY22–26); DSO 82 → 122 days [§1] | Sustained divergence; caps composite at 6.0. WC test below rules out the innocent reading. | +| 4 | Capex vs depreciation | Not determinable from the extract | Flagged as a gap; full cash flow / PPE note needed. | +| 5 | Audit opinion | **Qualified**, plus going-concern material uncertainty, plus prior auditor **resigned** mid-term [§2, §3] | Qualified opinion caps at 4.0; resignation without a clean reason caps at 4.5. Both are structural (D) signals. | +| 6 | Related party & pledge | RP advance ₹40→95→**180 cr** interest-free; below-market RP sales; promoter pledge **18%→71%** [§4, §6] | Tunnelling indicators cap at 4.5; pledge >50% caps at 4.0. | + +**Innocent-explanation test (mandatory before flagging #1/#3):** could the cash gap simply be a fast-growing, working-capital-heavy agri business? No. Receivables as a % of sales *rose* from 22.5% (FY22) to 33.5% (FY26) [computed, §1]. A stable ratio on a growing base would be growth; a *rising* ratio means the growth is being funded, not earned. The innocent reading does not survive. + +## Findings + +**F1 — Unprovided related-party advance (₹180 cr).** +- *What the disclosure shows:* an interest-free advance to Kesar Estates Pvt Ltd (promoter-controlled), no repayment schedule, outstanding and growing three years, no provision; the auditor states profit before tax would be ₹180 cr lower if provided [§2, §4]. +- *Severity:* structural integrity risk. +- *Innocent explanation:* a genuine, recoverable operational advance. But recoverability is precisely what the auditor could not evidence, and the balance grows yearly regardless of performance. +- *What would resolve it:* Kesar Estates' MCA financials and the terms/security of the advance. +- *Cluster:* joins the below-market RP sales (§4) and the ₹300 cr guarantee to the same entity (§5) — all pointing at promoter-group leakage. + +**F2 — Profit-to-cash reversal, landing in receivables and RP advances.** +- *What it shows:* PAT +₹239 cr cumulatively (FY22–26) against CFO −₹164 cr; over the same window receivables rose ~₹538 cr and RP advances ~₹140 cr [§1, §4]. +- *Severity:* structural. +- *Innocent explanation:* WC-intensive growth — ruled out by the rising receivables/sales ratio above. +- *What would resolve it:* the receivables ageing table and evidence of post-year-end collection. +- *Cluster:* the CARO bank-returns-vs-books disagreement (F3) points at the *same* receivables line. + +**F3 — CARO: books disagree with what lenders were told; plus default and arrears.** +- *What it shows:* quarterly returns to banks overstated receivables vs the books by ~₹60 cr in three of four quarters; ₹95 cr term-loan default (120 days); ₹22 cr undisputed statutory dues unpaid >6 months; evergreening of related-party loans [§3]. +- *Severity:* structural. An auditor-attested reconciliation failure between the books and the lender statements is among the most concrete red flags in any annual report. +- *Innocent explanation:* a timing/reconciliation error — but management only states it is "in the process of reconciling," and unpaid statutory dues are hard evidence of a cash squeeze (companies pay taxes last). +- *Cluster:* corroborates F2 (the receivables are questionable) and the going-concern note. + +**F4 — Contingent liabilities exceed net worth; governance instability.** +- *What it shows:* contingent liabilities ₹420 cr (incl. a ₹300 cr guarantee for the promoter entity) vs net worth ₹350 cr; three CFOs in four years; mid-term auditor resignation citing information not made available; audit committee met twice; promoter is also Chairman/MD [§5, §7, §3]. +- *Severity:* structural (governance). +- *What would resolve it:* it compounds rather than resolves the above — the guarantee ties the listed company's solvency to the same promoter entity that holds the unprovided advance. + +## Quantified dependency + +On a provisioned basis the group has not been profitable. Cumulative reported PAT for FY24–FY26 is ₹164 cr (48+55+61) [§1]; the **single ₹180 cr unprovided advance, if provided as the auditor implies, more than erases it** [§2]. That is before any provision against the ₹210 cr of >365-day receivables carried at a ₹9 cr allowance [§2], or the ~₹24 cr margin differential on ₹300 cr of related-party sales booked at 2% vs ~10% third-party [computed, §4]. Reported profit does not survive contact with the disclosed adjustments; no valuation should be built on it. + +## Gates raised + +- Qualified audit opinion → **cap 4.0** (checked, confirmed present). +- 5y cumulative CFO/PAT < 0.5 → **cap 4.0** (checked, −0.69). +- Related-party tunnelling indicators → **cap 4.5** (checked, present). +- Promoter pledge > 50% → **cap 4.0** (checked, 71%). +- Going-concern material uncertainty → structural (checked, present). + +Multiple independent gates fire; the verdict is **D**, not a low numeric score, because valuation is moot until integrity is resolved. + +## What was not verified + +Filings-extract-only pass. Not verified: recoverability of the ₹180 cr advance (needs Kesar Estates' accounts); existence/encumbrance of the ₹210 cr cash (needs bank confirmations and the charge registry); the receivables ageing beyond the ₹210 cr >365-day figure; whether prior years were silently restated; management's own account (concall). None of these is needed to reach verdict D — the qualified opinion and going-concern uncertainty are decisive from the documents in hand — but each would sharpen the picture and none should be assumed clean. + +--- +*This is analysis of publicly disclosed information, not an allegation of wrongdoing and not licensed financial advice. Findings describe what the disclosure does and does not explain; they are not conclusions of fraud. (Fictional worked example — company and figures invented.)* diff --git a/finance/skills/stock-analysis/examples/standard-analysis-example.md b/finance/skills/stock-analysis/examples/standard-analysis-example.md new file mode 100644 index 00000000..c9ecf0c2 --- /dev/null +++ b/finance/skills/stock-analysis/examples/standard-analysis-example.md @@ -0,0 +1,230 @@ +# Nirmal Consumer Products (NSE: NIRMAL) — Equity Analysis + +> **ILLUSTRATIVE EXAMPLE — FICTIONAL COMPANY, INVENTED FIGURES.** Nirmal Consumer +> Products Ltd does not exist. This file is a worked exemplar of the skill's +> Standard-mode output; every citation below is to a fictional document. Do not +> reuse any figure here for a real company. + +**Analysis date:** 2026-08-02 +**Basis:** Consolidated · Ind-AS · ₹ crore (1 crore = 10 million) +**Latest reported period:** FY26 (year ended 31-Mar-2026), audited. +**Price reference:** ₹1,150 [NSE close, 2026-07-31] · **Market cap:** ₹23,000 cr · **EV:** ₹22,300 cr + +**Depth mode: Standard.** Sector playbook: FMCG / branded consumer. + +--- + +## RECENCY STATEMENT + +- **Most recent reported period incorporated:** FY26 (ended 31-Mar-2026), results filed 09-May-2026; FY26 concall (12-May-2026) incorporated. +- **Events checked through:** 2026-08-02. Q1 FY27 (Jun-2026) board meeting announced for 05-Aug-2026 — **not yet reported**; this analysis is pre-Q1-FY27. +- **Material events since year-end:** final dividend of ₹6.0/share declared [FY26 AR, p.14]; a new ₹450 cr capacity expansion announced 20-Jun-2026 [exchange filing, 2026-06-20]. No rating action, block deal or governance event found. +- **Invalidation trigger already tripped:** No. + +## DATA QUALITY NOTE + +| Item | Statement | +|---|---| +| **Primary sources (Tier 1)** | FY26 Annual Report (audited); FY22–FY25 Annual Reports; Q4 FY26 results filing (09-May-2026). | +| **Company secondary (Tier 2)** | FY26 earnings-call transcript (12-May-2026); FY26 investor presentation. | +| **Aggregators (Tier 4 — navigation/cross-check only)** | screener.in used only to locate filings and cross-check two figures; never cited as a source. | +| **As-of dates** | Financials to 31-Mar-2026. Price/market cap 31-Jul-2026. Shareholding 30-Jun-2026. | +| **Basis** | Consolidated throughout; standalone immaterial (subsidiaries <3% of revenue). | +| **Currency/units** | ₹ crore unless stated. | +| **Estimated** | `[E]`: maintenance capex split (~60% of gross capex); FY27 EPS in scenarios. All marked inline. | +| **Missing** | Channel-level (IQVIA/AWACS) secondary offtake not disclosed — primary-vs-secondary check could not be run; flagged in §5.2. | + +--- + +## VERDICT AND KEY RISKS + +**Verdict:** An excellent branded-consumer franchise — wide distribution moat, ~32% ROCE, clean cash conversion, net cash — but the price already embeds ~18% FCF growth for a decade [reverse-DCF, valuation.py], which the company has not sustained. Quality high; margin of safety thin. **Confidence: high on business quality, low on the entry price being attractive.** + +**Composite score: 7.1 / 10** (sector-relative, weights in §4) · **Playbook:** FMCG / branded consumer · **Situation flags:** none. + +**Disqualifying gates: checked, none tripped.** Clean audit opinion, no promoter pledge, no related-party leakage, no auditor/CFO churn [FY26 AR, Auditor's Report & Note 34]. The score's drag is valuation, not quality or integrity. + +**The three things that matter most:** +1. **Distribution moat is widening.** Direct reach 1.35 m outlets, up from 0.9 m in FY22 [FY26 investor presentation, slide 9]; this is the durable asset, not any single brand. +2. **Returns are high and cash-backed.** ROCE 32% [computed: EBIT 820 / capital employed 2,550, FY26 AR] with CFO/EBITDA of 88% [computed: CFO 806 / EBITDA 916, FY26 AR] — profit converts to cash. +3. **The price is the risk.** P/E 41x / EV/EBITDA 24x [valuation.py] on a business growing revenue ~12%. + +**Key risks:** +1. **Multiple de-rating.** A re-rating from 41x to 30x P/E is ~−27% with no change in the business. +2. **Volume slowdown.** FY26 volume growth was 7% [FY26 concall]; a slip to low-single-digits with input-cost inflation would compress the ~19% EBITDA margin. +3. **Input-cost / competition.** Palm oil and packaging are ~40% of COGS [FY26 AR, p.96]; a spike, or aggressive private-label entry, pressures gross margin (52% [FY26 AR, p.88]). + +**What would change the verdict:** see §10 — chiefly the price, and whether volume growth holds ≥6%. + +--- + +## 1. The Business + +Nirmal sells branded packaged foods (biscuits, snacks, spreads) to Indian consumers through ~1.35 m directly-served retail outlets [FY26 investor presentation, slide 9]. What the customer buys is a trusted, consistent, affordable brand available everywhere; the moat is **distribution density plus brand recall**, which compounds with scale. + +- **Revenue build:** volume × price/mix. FY26 revenue ₹4,820 cr [FY26 AR, p.88], +12.3% YoY, decomposed as ~7% volume + ~5% price/mix [FY26 concall]. 5-year revenue CAGR 11.7% (FY22 ₹3,100 cr → FY26 ₹4,820 cr) [FY22 & FY26 AR]. +- **Mix:** biscuits 54%, snacks 31%, spreads 15% of revenue [FY26 AR, segment note p.104]; premium/"better-for-you" lines now 22% of sales, up from 14% in FY23 — the margin-mix driver. +- **Cost structure:** gross margin 52.0% [FY26 AR, p.88]; commodity inputs (edible oil, wheat, sugar, packaging) ~40% of COGS [FY26 AR, p.96]; A&P spend 8.1% of sales. +- **Cash-conversion path:** negative-to-neutral working capital — a structural FMCG strength; suppliers and the trade partly finance the business (§5.3). + +--- + +## 2. Sector Classification and Playbook + +**Sub-sector:** Branded packaged foods (FMCG). **Playbook:** `references/sectors/fmcg-consumer.md`. + +**Why:** an annuity-like, brand-and-distribution business; the right lens is volume growth, gross/EBITDA margin, ROCE, working-capital cycle and reinvestment — not the metrics that suit asset-heavy or financial businesses. + +**Metrics used with care / suppressed:** + +| Standard metric | Status | Why | +|---|---|---| +| Net debt / EBITDA | n/a — net cash | Nirmal holds net cash of ₹700 cr [valuation.py EV bridge]; leverage ratios are not the constraint. | +| EV/Sales in isolation | Use with care | 4.6x looks high cross-sector but is normal for a high-margin FMCG; read with EV/EBITDA. | +| P/B | Low information | Brand and distribution value is off-balance-sheet; P/B 9.8x reflects that, not overvaluation per se. | + +--- + +## 3. Situation Classification + +No special situation — analysed as a going-concern operating business. No cyclicality overlay (FMCG demand is inelastic), no recent IPO, no holdco structure. + +--- + +## 4. Scorecard + +Sector-relative (FMCG) and vs Nirmal's own history. Anchor: 6 = peer-typical, 8 = clearly above, 3 = materially below. + +| Category | Score /10 | Weight | Weighted | One-line rationale | +|---|---:|---:|---:|---| +| Business quality & moat | 8 | 18% | 1.44 | Widening distribution reach + premiumising mix; durable. | +| Earnings quality | 8 | 12% | 0.96 | CFO/EBITDA 88%; no exceptionals; clean tax rate. | +| Balance sheet | 8 | 8% | 0.64 | Net cash ₹700 cr; no pledge; low contingent liabilities. | +| Cash flow | 7 | 12% | 0.84 | Strong CFO; FCF held back by growth capex (new plant). | +| Returns on capital | 9 | 15% | 1.35 | ROCE 32%, ROE 24%; high incremental returns. | +| Growth | 7 | 12% | 0.84 | ~12% revenue, 7% volume — good, not spectacular. | +| Management & governance | 7 | 8% | 0.56 | Clean, professional; promoter 48%, no pledge; pay reasonable. | +| Valuation | 3 | 15% | 0.45 | 41x P/E / 24x EV/EBITDA prices in ~18% growth for a decade. | +| **Composite** | | **100%** | **7.1** | Excellent business, demanding price. | + +**Weighting rationale:** FMCG default — moat and returns carry the most weight (an FMCG thesis is a compounding-quality thesis), with valuation held high (15%) because entry price is the main open question here. + +--- + +## 5. Core Analysis by Dimension + +### 5.1 Business Quality and Moat +Evidence *for*: direct reach up 50% in four years (0.9 m → 1.35 m outlets) [FY26 presentation, slide 9]; premium mix 14%→22% of sales [FY23 & FY26 AR]; ROCE sustained ≥27% every year FY22–FY26 [computed from each AR] — high returns *held while competitors tried*, the real moat test. Evidence *against*: category is contestable at the value end; private label is a slow structural threat. Net: a widening, durable moat. + +### 5.2 Earnings Quality + +| Metric | FY26 | Own 3–5y | Read | +|---|---|---|---| +| CFO / EBITDA | 88% [computed 806/916] | 82–90% | Profit is cash. | +| Effective tax rate | 25.1% [FY26 AR, p.92] | 25% band | Normal; no tax-driven flatter. | +| Other income / PBT | 4% [FY26 AR, p.90] | <5% | Operating, not treasury-driven. | +| Exceptionals | none [FY26 AR] | none | No add-back games. | + +Caveat: channel secondary-offtake (IQVIA/AWACS) is not disclosed, so the primary-billing-vs-secondary check could not be run — a genuine gap, flagged in the Data Quality Note. + +### 5.3 Balance Sheet +Net cash ₹700 cr [valuation.py]; total borrowings ₹200 cr against ₹900 cr cash [FY26 AR, p.86]. No promoter pledge [shareholding pattern, Jun-2026]. Contingent liabilities ₹95 cr (~4% of net worth) — immaterial [FY26 AR, Note 39]. A fortress balance sheet; the ₹450 cr new-plant spend is comfortably self-funded. + +### 5.4 Cash Flow +CFO ₹806 cr [FY26 AR, cash flow statement]; gross capex ₹336 cr, of which ~₹135 cr [E] maintenance and the rest the new-plant growth spend → FCF (CFO − capex) ~₹470 cr [E]. Cumulative FCF FY22–FY26 ≈ ₹1,850 cr vs cumulative PAT ₹2,180 cr — ~85% conversion over five years, strong for a company also building capacity. + +### 5.5 Returns on Capital +ROCE 32% [computed: EBIT 820 / (equity 2,350 + debt 200), FY26 AR]; ROE 23.8% [560/2,350]. **DuPont:** net margin 11.6% × asset turnover 1.38x × leverage 1.49x = 23.8% [computed, FY26 AR]. Incremental ROCE on FY22→FY26 capital deployed ≈ 34% [E] — reinvestment is value-accretive, the core of the compounding case. + +### 5.6 Growth +Revenue CAGR 11.7% (5y); EBITDA CAGR 14% (margin expanded 17.2%→19.0% on premium mix) [FY22 & FY26 AR]; EPS ₹18.4 → ₹28.0. Growth is ~60% volume, ~40% price/mix — high quality. Share count flat (no dilution) [FY26 AR]. + +--- + +## 6. Peer Comparison + +**Peer set (illustrative, fictional):** Anand Foods, Prakash Snacks, Vedic Consumer — branded-foods peers of similar scale and channel model. (In a real analysis these would be named listed comparables with sourced figures.) + +Peer medians below are illustrative, FY26 basis [see note; real analysis would cite each peer's FY26 filing]: + +| Metric | Nirmal | Peer median (illus.) | Read | +|---|---|---|---| +| Revenue CAGR 5y | 11.7% | 10% | Slightly ahead. | +| Gross margin | 52% | 48% | Premium mix shows. | +| EBITDA margin | 19% | 17% | Above median. | +| ROCE | 32% | 26% | Above median — efficiency, not just margin. | +| CFO/EBITDA | 88% | 82% | Cleaner cash. | +| P/E | 41x | 44x | In line-to-slightly-cheaper vs a rich peer set. | + +Nirmal sits modestly above the peer set on quality and roughly in line on multiple — a good business at a category-typical (rich) price, not a mispricing. + +--- + +## 7. Valuation + +**Method:** trailing multiples + reverse-DCF (implied-expectations) + scenario table, per `references/06-valuation.md`. The figures below are `scripts/valuation.py` output on the FY26 sourced inputs (price as of 2026-07-31). + +EV bridge and trailing multiples [valuation.py on FY26 AR figures, price 2026-07-31]: + +| Line | Value | | Multiple | Value | +|---|---:|---|---|---:| +| Market cap | ₹23,000 cr | | P/E | 41.1x | +| + Total debt | ₹200 cr | | EV/EBITDA | 24.3x | +| − Cash | ₹900 cr | | EV/EBIT | 27.2x | +| = Enterprise value | ₹22,300 cr | | EV/Sales | 4.6x | +| Net cash | ₹700 cr | | P/B | 9.8x | +| | | | FCF yield | 2.0% | + +Reverse-DCF and forward DCF [valuation.py, as of 2026-07-31]: + +| Output | Assumptions | Value | +|---|---|---:| +| Reverse-DCF implied FCF growth | WACC 11%, 10y, terminal 5% | ~18.3%/yr | +| Forward DCF value/share | 13% 10y, fade 5y, terminal 5%, WACC 11% | ₹861 | +| Terminal share of EV | — | 52% | +| Forward DCF vs price | vs ₹1,150 | −25% | + +**Reverse-DCF read (the testable claim):** at ₹1,150 the market embeds **~18% FCF growth for a decade** [valuation.py]. Nirmal has grown FCF ~14% over five years and revenue ~12% — so the price requires an *acceleration* the record does not evidence. That is the crux of the "quality high, price demanding" verdict. + +**Scenario table** [valuation.py, EPS × exit P/E, as of 2026-07-31; probabilities are judgements]: + +| Scenario | Prob | Assumptions | Value/share | vs ₹1,150 | +|---|---:|---|---:|---:| +| Bear | 30% | volume fades to 3–4%, de-rate to 28x on ₹24 EPS [E] | ₹672 | −42% | +| Base | 50% | ~11% growth holds, 38x on ₹31 EPS [E] | ₹1,178 | +2% | +| Bull | 20% | premiumisation accelerates, 46x on ₹35 EPS [E] | ₹1,610 | +40% | +| **Prob-weighted** | 100% | | **₹1,113** | **−3%** | + +The probability-weighted value sits ~3% below the current price: a wonderful business priced for its own success, with a roughly symmetric-to-slightly-negative one-year skew. + +--- + +## 8. Red Flags and Governance + +**No material red flags identified.** Checked and clear: clean unqualified audit opinion [FY26 AR, Auditor's Report]; no CARO qualifications [FY26 AR, CARO annexure]; no promoter pledge, promoter holding stable at 48% [shareholding pattern, Jun-2026]; related-party transactions immaterial and arm's-length [FY26 AR, Note 34]; promoter remuneration ~2% of PAT; no auditor or CFO change in five years; contingent liabilities ~4% of net worth. + +--- + +## 9. The Bear Case + +Nirmal is a very good business trading at a price that assumes it stays very good *and* gets faster. At 41x earnings and 24x EV/EBITDA, the reverse-DCF says the market is paying today for ~18% FCF growth for ten years — yet the company has compounded revenue at ~12% and FCF at ~14%, with FY26 volume growth of just 7% in a category where the value end is contestable and private label is advancing. FMCG multiples have de-rated before when volume growth stalled; a slip to mid-single-digit volumes with any input-cost inflation would compress the ~19% margin *and* the multiple simultaneously — the two forces that make the bear scenario −42%. Nothing needs to go wrong with the franchise for the *stock* to disappoint; the price has borrowed years of future growth into the present. + +**Strongest counter (kept honest):** the distribution moat is genuinely widening (reach +50% in four years), returns are ~32% and cash-backed, premiumisation is a real and continuing margin lever, and the balance sheet is net cash — so a long runway of low-teens compounding is plausible, and for a patient owner the *business* will likely be worth materially more in a decade even if the *entry multiple* is unrewarding for a year or two. + +--- + +## 10. Thesis-Invalidation Triggers + +| # | Trigger | Where to observe | By when | Action if hit | +|---|---|---|---|---| +| 1 | Volume growth falls below 5% for two consecutive quarters | Quarterly results / concall | By Q3 FY27 | Growth-durability leg weakens — revisit. | +| 2 | Gross margin falls below 49% for two quarters | Quarterly results | FY27 | Input-cost/competition pressure confirmed. | +| 3 | CFO/EBITDA falls below 75% | FY27 annual cash flow | FY27 AR | Earnings-quality leg breaks. | +| 4 | Promoter pledge appears, or holding falls materially | Shareholding pattern | Any quarter | Governance re-review. | +| 5 | Any acquisition paid at >5x EV/Sales outside core categories | Exchange filing / AR | Any time | Capital-allocation discipline in question. | + +--- + +## Disclaimer + +This document is research and analysis for informational purposes only. It is **not** investment advice, not a recommendation to buy, sell or hold any security, and not a personalised financial recommendation. The author is not a licensed or registered investment adviser. **This is a fictional worked example: the company and all figures are invented.** Any real investment decision is the reader's own responsibility and should be made in consultation with a licensed financial adviser. diff --git a/finance/skills/stock-analysis/references/01-data-sourcing.md b/finance/skills/stock-analysis/references/01-data-sourcing.md new file mode 100644 index 00000000..4f011e44 --- /dev/null +++ b/finance/skills/stock-analysis/references/01-data-sourcing.md @@ -0,0 +1,315 @@ +# Data Sourcing and Verification + +Use this when: you are about to pull any number into an analysis, or you are checking a figure someone else supplied. + +Every downstream judgment — margin quality, leverage, valuation, sector positioning — inherits the reliability of the numbers you started with. A wrong unit, a standalone-vs-consolidated mix-up, or a stale price destroys a conclusion more thoroughly than a weak argument does, and it does so invisibly. Sourcing discipline is not bookkeeping hygiene; it is the first analytical step. The governing rule of this skill applies here too: a figure without its sector, its period and its basis of preparation is not yet a fact. + +## Contents + +- [1. Primary vs secondary sources](#1-primary-vs-secondary-sources) +- [2. India: where the data lives](#2-india-where-the-data-lives) +- [3. Global / US: where the data lives](#3-global--us-where-the-data-lives) +- [4. The verification protocol](#4-the-verification-protocol) +- [5. Consolidated vs standalone](#5-consolidated-vs-standalone) +- [6. Units, currency and the 10x error](#6-units-currency-and-the-10x-error) +- [7. Fiscal-year alignment and period labelling](#7-fiscal-year-alignment-and-period-labelling) +- [8. Restatements, reclassifications and discontinued operations](#8-restatements-reclassifications-and-discontinued-operations) +- [9. As-of dates for price, market cap and multiples](#9-as-of-dates-for-price-market-cap-and-multiples) +- [10. Common data-provider errors and ambiguous fields](#10-common-data-provider-errors-and-ambiguous-fields) +- [11. Sector-specific sourcing traps](#11-sector-specific-sourcing-traps) +- [12. When web access is unavailable or data is paywalled](#12-when-web-access-is-unavailable-or-data-is-paywalled) +- [13. Never fabricate](#13-never-fabricate) +- [Checklist](#checklist) + +--- + +## 1. Source hierarchy — documents are the only source of record + +This is a **document-first** skill. Every financial figure in the analysis must trace to a raw company document. Rank sources by how many hands the number has passed through, and note the hard boundary between Tiers 1–3 and Tier 4. + +### Tiers 1–3: Sources of record + +Figures from these sources may be cited in the analysis. + +| Tier | What it is | Use it for | +|---|---|---| +| 1. Primary filing | Annual report, 10-K/10-Q, exchange filing (quarterly results), audited financial statements, prospectus (DRHP/RHP/S-1) | Any figure that carries weight in the conclusion — this is the default source | +| 2. Company-published secondary | Investor presentation, earnings release, concall transcript, IR fact sheet | Segment detail, management commentary, guidance, operating KPIs not in the statements | +| 3. Regulator/third-party primary | SEBI/MCA/ROC records, credit rating rationales, exchange bulk-deal and shareholding data | Ownership, pledges, related-party context, debt structure, covenants | + +### Tier 4: Navigation and cross-check only — NOT a source of record + +| Tier | What it is | Permitted use | +|---|---|---| +| 4. Aggregators | screener.in, Tikr, Yahoo/Google Finance, stockanalysis.com, broker terminals, Wikipedia | (a) Locating the actual documents — e.g. screener.in links to annual reports and concall transcripts. (b) Spotting outliers to investigate in the filing. (c) Optional labelled cross-check *after* a figure is already sourced from a Tier 1–3 document. | + +**Hard rule: an aggregator figure must never appear as a cited source in the report.** If a figure exists only in an aggregator and cannot be traced to any Tier 1–3 document, it is `not sourced` — write it as such. Aggregators normalize thousands of filings with rules that cannot fit every company, and their exception handling is invisible to you. When an aggregator figure and a filing figure disagree, the filing wins — and the disagreement itself is information. + +Aggregator figures *may* appear alongside a document-sourced figure as a labelled cross-check: `"Revenue ₹4,820 cr (FY25 AR p.112; screener.in agrees at ₹4,818 cr)"`. They must never stand alone. + +**One exception: current share price and market cap** are inherently sourced from exchange or finance websites. These must carry an as-of date and time. + +Cite the tier in your notes. `"Revenue INR 4,820 cr (FY25, consolidated, annual report p.112)"` is usable. `"Revenue ~4,800 cr"` is not. `"Revenue 4,800 cr (screener.in)"` is not — it fails the document-first rule. + +--- + +## 2. India: where the data lives + +**Company investor-relations page.** The canonical starting point. Look for: annual reports (usually 5-10 years archived), quarterly results, investor presentations, earnings call transcripts and audio, press releases, and often an "investor contact" address. IR pages are the fastest route to the actual PDF of the annual report; exchange sites host the same document but with worse navigation. + +**Annual report (India-specific structure).** Under the Companies Act 2013, an Indian annual report contains, in order of analytical value: +- Standalone **and** consolidated financial statements with schedules/notes — the notes are where the analysis actually is. +- **Management Discussion & Analysis (MD&A)** — segment commentary, sometimes volume and realization data. +- **CARO report** (Companies Auditor's Report Order) — an underused goldmine. It forces the auditor to comment on fixed-asset verification, inventory discrepancies, loans to related parties, statutory dues in arrears, default in repayment of borrowings, fraud reported, and whether funds raised for one purpose were used for another. Read every CARO qualification. +- **Auditor's report**: check for qualified/adverse/disclaimer opinions, Emphasis of Matter, and Key Audit Matters (KAMs). KAMs tell you which numbers the auditor itself found hardest. +- **Related party transactions note** — sales, purchases, loans, guarantees to promoter-linked entities. +- **Contingent liabilities note** — disputed tax demands, guarantees, litigation. Frequently larger than net worth in infra and telecom. +- **Corporate governance report** and **Business Responsibility & Sustainability Report (BRSR)** for larger listed companies. +- **Secretarial audit report** (Form MR-3). + +**NSE and BSE filings and announcements.** Every listed company files quarterly results, shareholding patterns, board-meeting outcomes, material events under SEBI LODR Regulation 30, analyst-meet intimations, credit-rating changes, resignations of directors/auditors/KMP, and pledge disclosures. Search by company on nseindia.com (Corporate Filings) or bseindia.com (Corporate Announcements). Announcements are timestamped — use the exchange timestamp, not a news article's, when sequencing events. +- **Regulation 30 disclosures** are where acquisitions, order wins, plant shutdowns, fires, regulatory actions and litigation first appear. +- **Auditor resignation** filings and **independent-director resignations with reasons** are high-signal governance events. + +**Shareholding pattern filings (quarterly, both exchanges).** Gives promoter holding, promoter **pledge** (as % of promoter holding and % of total shares — note which one a source quotes), FII/FPI, DII (mutual funds, insurance), public and, for many companies, the list of shareholders holding above 1%. Track the trend, not the level: a promoter stake declining over consecutive quarters, or pledge rising, deserves an explanation you should find in filings rather than infer. + +**Aggregators — navigation and cross-check only.** Sites like screener.in, Tikr, and stockanalysis.com are useful for two things: (a) *finding* the actual documents — screener.in links directly to annual reports and concall transcripts, which is its most valuable feature; and (b) spotting outliers in ratio history or peer sets that you then investigate in the filing. Their computed ratios, standardized financials, TTM columns, and median calculations reflect invisible normalization choices that may not match the company's actual reporting. **Do not extract figures from these sites as your source.** Navigate through them to reach the document, then extract from the document. If you use an aggregator figure as a cross-check alongside a document-sourced number, label it explicitly as such. + +**MCA / ROC (Ministry of Corporate Affairs).** The route to unlisted entities: promoter holding companies, subsidiaries, JV partners, related parties, and the private companies behind a group structure. Filed documents include AOC-4 (financial statements), MGT-7 (annual return), charges registered against assets (useful for spotting secured debt not obvious from the consolidated balance sheet), and director/DIN records for cross-directorship mapping. Many documents are pay-per-download. + +**SEBI.** Regulatory orders and adjudication (enforcement against companies, promoters, intermediaries), takeover/SAST disclosures, insider-trading (PIT) disclosures, buyback and open-offer documents, and the mutual-fund and FPI regulatory framework. A SEBI order naming the promoter is a governance fact of the first order. + +**Credit rating agency rationales — CRISIL, ICRA, CARE, India Ratings, Brickwork.** Free, detailed, and often the single best third-party document on a company's debt. A rationale typically gives: rated instruments and amounts, the agency's own computed leverage and coverage ratios, key rating drivers and sensitivities (explicit numeric thresholds for upgrade/downgrade), liquidity assessment, and the group structure the agency consolidates. Ratings history matters more than the current rating — a sequence of downgrades or a move to "Rating Watch with Negative Implications" precedes trouble more reliably than any screen. Also check for **"Issuer Not Cooperating" (INC)** tags: a company that stopped supplying information to its rating agency is telling you something. + +**Concall transcripts.** Usually on the IR page, on exchange filings, and aggregated by screener.in and transcript services. Read the Q&A, not the prepared remarks — the prepared remarks are the press release read aloud. Note: which analysts cover the company, which questions management deflects, whether guidance given last quarter was met, and specific numbers management volunteers (volumes, realizations, capacity utilization, order book, segment margins) that never appear in the statements. Quote the speaker and the quarter when you use them. + +**DRHP / RHP (for IPOs and recent listings).** The Draft Red Herring Prospectus is the most information-dense document that exists on an Indian company: multi-year restated financials, risk factors written by lawyers who must disclose, litigation schedules (including against promoters and directors), objects of the issue, promoter background, related-party history, KPI disclosures with a management justification, and peer comparison. For a company listed in the last 3-4 years, always read the DRHP even though it is old — it explains the pre-IPO structure the current filings assume you know. + +**Other Indian sources.** RBI (banking sector data, sectoral credit deployment), industry bodies (SIAM for autos, CMIE, ICRA/CRISIL sector reports), IBBI (insolvency filings against the company or its counterparties), GST and customs data vendors (paid), and the company's own regulatory filings with sector regulators (IRDAI, TRAI, CERC, PNGRB). + +--- + +## 3. Global / US: where the data lives + +**SEC EDGAR** is the primary source for US registrants and for foreign companies with US listings. Use full-text search and the company's filing index. + +| Form | What it contains | Analytical use | +|---|---|---| +| 10-K | Annual report: audited statements, MD&A, risk factors, Item 1 business description, segment note, controls | The base document. Item 7 MD&A and the segment note carry most of the signal | +| 10-Q | Quarterly, unaudited, condensed | Trend within the year; note the comparatives are prior-year quarter, not sequential | +| 8-K | Material events: earnings release (Item 2.02), leadership change, acquisition, auditor change (Item 4.01), impairment (Item 2.06), covenant default | Timeline of events; the earnings press release is an 8-K exhibit | +| DEF 14A (proxy) | Executive compensation, incentive metrics, board composition, auditor fees, shareholder proposals, related-party transactions | Tells you what management is actually paid to maximize — often diverges from what they say on calls | +| Form 4 | Insider transactions within 2 business days | Insider buying/selling; distinguish open-market purchases from option exercises and 10b5-1 plan sales | +| SC 13D/13G, 13F | Large holders; institutional quarterly positions | Ownership concentration and activist presence | +| S-1 / F-1 | IPO registration | The global analogue of the DRHP | +| 20-F / 40-F | Foreign private issuers (annual), often IFRS | Non-US companies with US listings; note IFRS-GAAP reconciliation is no longer required | +| 6-K | Foreign private issuer interim reports | Quarterly data for 20-F filers, format varies by home market | +| NT 10-K / NT 10-Q | Late-filing notification | A material red flag; read the stated reason | + +Also: **XBRL "Financial Statement Data Sets"** and the EDGAR company-facts JSON API give machine-readable tagged figures straight from filings — use them when you need many periods, but check the tag actually maps to the line item you think it does (companies use extension tags liberally). + +**Non-US primary sources.** UK: Companies House plus the RNS regulatory news service. EU: national registries plus the issuer's own regulatory news; ESEF-tagged annual reports. Japan: EDINET and TDnet. Canada: SEDAR+. Australia: ASX announcements. Hong Kong: HKEXnews. Each has its own equivalent of "material event" filings — find it before concluding nothing happened. + +**Company IR and annual reports (global).** Under IFRS, the annual report structure differs from the 10-K: strategic report, governance and remuneration report, then statements with notes. Segment reporting under IFRS 8 and ASC 280 both follow the "management approach", meaning segments reflect how the CEO sees the business — which is itself information, and which changes when management changes. + +**Earnings call transcripts.** Company IR sites increasingly post them directly; otherwise use transcript providers. Same rule as India: the Q&A carries the signal. Track guidance given versus guidance delivered across four to eight quarters — this is the cheapest available test of management credibility. + +**Other global.** Central bank and statistical agencies for macro inputs; industry regulators; rating agency reports (Moody's/S&P/Fitch — summaries often free, full reports paywalled); bond prospectuses and covenant packages when leverage matters. + +--- + +## 4. The verification protocol + +Apply this to every figure that could change a conclusion. + +**1. Cite source and period, always.** Format: `value + unit + basis + period + source`. Example: `EBITDA margin 14.2% (FY25, consolidated, computed from annual report P&L, p.104)`. If you cannot state all five, you do not yet have the figure. This is not formatting pedantry — most sourcing errors become visible the moment you try to write the full citation and find one field missing. + +**2. Cross-check headline figures across two independent sources — at least one must be a primary document (Tier 1–3).** Headline = revenue, EBITDA/operating profit, PAT, total debt, equity, operating cash flow, share count, market cap. Independent means the two sources did not derive from each other: an aggregator and a news article that both copied the press release are one source, not two. Two aggregators are also not a valid cross-check — at least one side must be a document. Filing vs rating rationale, or annual report vs quarterly results filing, is a real cross-check. Filing vs aggregator is acceptable as the second source, but the aggregator figure is the cross-check, not the source of record. + +**3. Reconcile any discrepancy before proceeding.** A gap of a few percent is usually a definitional difference (other income in/out of EBITDA, leases, minority interest). A gap above ~10% usually means different basis, different period, or different units. Do not average two numbers you cannot reconcile — find which one is right, or report both with their definitions. + +**4. The primary document always wins.** If the aggregator says one thing and the audited statement says another, use the statement and note the aggregator's error, because that error probably contaminates the aggregator's ratios too. The aggregator figure is never an acceptable substitute for a document-sourced one — it may appear only as a labelled cross-check. + +**5. Recompute rather than accept.** Derived metrics — ROCE, ROE, net debt/EBITDA, working capital days, FCF — should be computed by you from raw line items you have sourced, with your formula stated. Providers differ on almost every one of these (see §10). Recomputing also forces you to see the components, which is where the story is. + +**6. Sanity-check against the real world.** Does implied revenue per store, per tonne, per employee, per subscriber make sense? Does the balance sheet balance? Do the three statements tie (PAT to cash flow opening line, closing cash to balance sheet)? Does the growth rate imply a market share that exceeds the market? An arithmetic check costs seconds and catches transcription errors that reasoning will not. + +**7. Flag single-sourced figures explicitly.** Where a number could not be corroborated, say so in the output: "single source, unverified". A reader can discount a flagged number; they cannot discount one presented with false confidence. + +--- + +## 5. Consolidated vs standalone + +India-specific in emphasis, but the same issue exists globally as parent-only versus group accounts. + +- **Consolidated** includes subsidiaries line-by-line, associates/JVs by equity method, and shows non-controlling (minority) interest separately. **Standalone** is the parent company only, with subsidiary income appearing mostly as dividends and investments held at cost. +- **Default to consolidated** for operating and valuation analysis. It reflects the economic entity that the equity actually owns. +- **Never mix the two** within a ratio. Consolidated EBITDA over standalone debt, or consolidated PAT over a standalone equity base, produces numbers that look plausible and are meaningless. +- **PAT must be after minority interest** ("profit attributable to owners of the parent") when computing EPS, ROE or P/E. Providers get this wrong regularly for holding-company structures. +- **When the gap is large, investigate it.** A parent with much higher standalone margins than consolidated is carrying loss-making subsidiaries. The reverse suggests value sits in subsidiaries — then ask who else owns them. +- Watch for **subsidiary debt without recourse to the parent**, **associates carried at equity whose losses are capped at carrying value**, and **structured entities**. Rating rationales are useful here because agencies state their own consolidation perimeter explicitly. +- For **holding companies and conglomerates**, consolidated statements can obscure more than they reveal; you may need a sum-of-parts using subsidiary-level filings from MCA or the subsidiaries' own listings. +- Older Indian data pre-Ind AS (before FY16-17 phase-in) is not directly comparable to later years — Ind AS changed revenue recognition, leases (Ind AS 116 from FY20), financial-instrument measurement and consolidation of certain entities. Say so when your series crosses the boundary. The same applies globally to ASC 606 (revenue) and ASC 842 / IFRS 16 (leases), which moved operating leases onto the balance sheet and shifted rent expense into depreciation and interest — inflating EBITDA and leverage simultaneously. + +--- + +## 6. Units, currency and the 10x error + +This is the single most common serious error and the easiest to prevent. + +- Indian numbering: **1 lakh = 100,000**; **1 crore = 10,000,000 = 10 million**. So **1 crore = 10 million**, and **100 crore = 1 billion**. The recurring failure is treating a crore as a million, understating by 10x, or treating 1 crore as 0.1 billion correctly but then mishandling the next conversion. +- Indian filings variously present in `₹ crore`, `₹ lakh`, `₹ million`, or `₹ '000`. **Read the column header on every table, every time** — the unit sometimes differs between the P&L and a note in the same document. +- Indian listed companies increasingly report in `₹ crore` in presentations but `₹ million` or `₹ lakh` in statutory statements. Fix the unit at the point of extraction, not later. +- State the currency explicitly (`INR`, `USD`, `EUR`) — `$` is ambiguous across USD/SGD/HKD/AUD/CAD, and `₹` vs other symbols matters in copy-paste. +- For cross-currency comparison, state the **FX rate and its date**. Never compare a market cap converted at today's rate with earnings converted at an average rate without saying so. For multi-year series, decide and state whether you use period-average or period-end rates, and be consistent. +- Per-share figures: check the **face value** (Indian shares are commonly ₹1, ₹2, ₹5 or ₹10 par) and adjust historic per-share series for **splits and bonus issues**. An unadjusted EPS series with a 1:1 bonus in the middle shows a fake 50% collapse. +- ADR/GDR ratios distort per-share comparison between the local line and the US line. +- Percentages: distinguish **basis points** from percent, and **percentage-point change** from **percent change** (margin moving 10% to 11% is +100 bps, or +10% relative — say which). + +Quick conversion table to keep in working memory: + +| Indian unit | Numeric | USD-scale equivalent | +|---|---|---| +| 1 lakh | 1e5 | 0.1 million | +| 1 crore | 1e7 | 10 million | +| 100 crore | 1e9 | 1 billion | +| 1,000 crore | 1e10 | 10 billion | +| 1 lakh crore | 1e12 | 1 trillion | + +(USD-scale column is unit scale only, not an FX conversion.) + +--- + +## 7. Fiscal-year alignment and period labelling + +- **India**: fiscal year runs 1 April to 31 March. "FY25" almost always means the year ended 31 March 2025 — but confirm, because some Indian companies (and most Indian subsidiaries of foreign groups) use December or June year-ends. Quarters: Q1 = Apr-Jun, Q2 = Jul-Sep, Q3 = Oct-Dec, Q4 = Jan-Mar. +- **US/global**: fiscal years vary widely; retailers commonly end in late January/early February, and many companies use 52/53-week years where one year has an extra week (a ~2% distortion to annual growth that management will mention and providers will not). +- Company "FY2025" labels can refer to the year *beginning* or *ending* in 2025 depending on jurisdiction and company convention. When comparing across companies, **convert everything to the calendar period covered** and say so: "year ended Mar-2025" beats "FY25". +- Never compare an Indian FY-ending-March figure with a US calendar-year figure without noting the ~3-month offset, particularly across a macro inflection. +- Indian quarterly results are **limited-review, not audited** (except often Q4, which is derived as full-year audited minus nine months and therefore absorbs all year-end adjustments — Q4 is systematically the noisiest quarter). +- **TTM/LTM figures**: state the exact window ("TTM to Sep-2025"). A TTM built by adding quarters must handle restated prior quarters and any change in consolidation perimeter mid-year. +- Seasonality: compare year-over-year, not sequentially, unless you have established the seasonal pattern from at least three years of the company's own history. + +--- + +## 8. Restatements, reclassifications and discontinued operations + +- When the current annual report's prior-year column differs from what that prior report published, the prior year was **restated or reclassified**. Use the latest restated series for trend analysis and note the restatement; using the original numbers creates phantom growth or decline. +- Distinguish innocuous **reclassification** (moving a cost between lines, new segment definitions) from a **correction of error** or **change in accounting policy**, which are disclosed in the notes and are far more serious. Read the note; it says which. +- **Discontinued operations** are presented separately and prior periods are re-presented. Revenue growth computed across the boundary without adjustment is wrong in both directions. +- **Mergers, demergers, slump sales and scheme-of-arrangement effective dates** (common in India, often with retrospective appointed dates) can make one year non-comparable. The scheme details are in the annual report and in exchange filings. +- **Segment redefinitions** typically arrive with a new CEO or a reorganization. When segments change, either rebuild history from the re-presented comparatives the company gives, or start the series fresh — do not splice. +- **Auditor changes** near a restatement deserve scrutiny; check the 8-K Item 4.01 (US) or the exchange filing and the outgoing auditor's stated reason (India). + +--- + +## 9. As-of dates for price, market cap and multiples + +- Stamp every price-derived figure with a date and preferably a time: `P/E 28.4x (price as of close 18-Jul-2026)`. Multiples decay the moment the price moves; an undated multiple is a claim with no verifiable content. +- **Market cap** = current price × current fully-diluted-relevant share count. Check the share count against the latest filing, not a stale field: buybacks, QIPs, preferential allotments, ESOP exercises, conversion of warrants/convertibles and rights issues all move it, and aggregators lag. +- Distinguish **basic**, **diluted** and **fully diluted** share counts, and say which you used. For companies with large option pools or outstanding convertibles, the difference is material. +- **Enterprise value** = market cap + debt + minority interest + preferred − cash and equivalents (and, depending on convention, − investments in associates, ± lease liabilities). State your formula. EV comparisons are only valid when everyone in the peer set used the same formula, which is why you should compute the whole peer set yourself. +- Match numerator and denominator periods: a current price over a trailing EPS is a trailing multiple; over a consensus estimate it is a forward multiple, and you must state whose estimate and as of when. +- **Free float** matters in India, where promoter holding is often 50-75%. Market cap overstates the investable base, and low-float names have unreliable price signals. +- For price history, note whether the series is **adjusted for splits, bonuses and dividends** — and remember that total-return series and price series diverge substantially over long horizons in high-dividend sectors. + +--- + +## 10. Common data-provider errors and ambiguous fields + +The list below is not about bad vendors; it is about fields that have no single correct definition. Whenever a metric appears here, compute it yourself and state your formula. + +| Field | How it goes wrong | +|---|---| +| EBITDA | Some include other income, some exclude; treatment of exceptional items, ESOP cost and post-IFRS 16/Ind AS 116 lease costs varies. Post-lease-standard EBITDA is not comparable to pre-standard EBITDA | +| Operating profit (India usage) | Often quoted as EBITDA excluding other income; screener.in and broker notes may differ from the company's own presentation | +| Net profit / PAT | Before vs after minority interest; before vs after exceptional items; continuing vs total operations | +| ROE / ROCE | Opening, closing or average capital; capital employed with or without cash, CWIP, goodwill, deferred tax; numerator pre- or post-tax. Ranges of 3-5 percentage points arise from definition alone | +| Total debt | Whether short-term borrowings, current maturities of long-term debt, lease liabilities, acceptances/LC-backed trade financing, and preference shares are included. Indian companies frequently carry large **bill discounting / channel financing** that behaves like debt but sits in payables | +| Net debt | Which "cash" counts — some current investments and mutual-fund holdings are cash-like, some are not; restricted cash and margin money should be excluded | +| Cash flow from operations | Interest paid and taxes may be classified in operating, investing or financing under IFRS/Ind AS at the company's choice; that choice makes OCF non-comparable across peers | +| Free cash flow | OCF − capex, but capex may or may not include intangibles, acquisitions, capitalized R&D, capitalized interest and lease payments | +| Working capital days | Computed on revenue vs COGS, on closing vs average balances, on gross vs net receivables. Days differ by 20%+ across conventions | +| Book value / equity | With or without minority interest, revaluation reserves, treasury shares; Indian "net worth" definitions in loan covenants often exclude intangibles | +| Share count | Point-in-time vs weighted average; basic vs diluted; unadjusted for recent corporate actions | +| Dividend yield | Trailing declared vs paid vs ex-date basis; special dividends included or not; India's dividend taxation changed in FY21, breaking older payout series | +| Growth rates | Base-period restatement not applied; 52/53-week years; acquisitions not separated from organic | +| Sector/industry tag | Aggregator classifications are crude. A "diversified" or "trading" tag can hide the actual business. Always read the business description before accepting a peer set | +| Promoter holding / pledge (India) | Pledge quoted as % of promoter holding in one place and % of total equity in another — a 3x-5x apparent difference | +| Market cap | Stale share count; separate listing lines for different share classes counted or omitted | +| "Employees" | Permanent vs contract vs total headcount; Indian filings often disclose only median remuneration and top-earner counts | + +Two structural cautions: aggregator ratio history is often recomputed on today's definitions and applied backwards inconsistently; and any field that is blank in the filing may appear as zero (not null) in a provider's data, which then propagates into averages. + +--- + +## 11. Sector-specific sourcing traps + +Consistent with the skill's governing principle — the standard ratios are undefined or inverted for several sectors, and so are the standard data sources. + +- **Banks and NBFCs**: revenue, EBITDA, EV and net debt are meaningless. Source instead: net interest income and NIM, gross and net NPA, provision coverage, slippage, credit cost, CASA, cost-to-income, capital adequacy (CET1/CRAR). In India these come from the quarterly results filing plus RBI disclosures (Basel III Pillar 3 disclosures are on the bank's own site) and the annual report's "Notes to accounts" disclosures on asset quality, restructuring and write-offs. +- **Insurers**: use premium growth (new business premium, APE), VNB and VNB margin, embedded value (EV) and its movement analysis, solvency ratio, persistency by cohort (13th/61st month), claims ratio and combined ratio for general insurers. Sources: IRDAI monthly business data, the insurer's EV disclosure and actuarial report. +- **REITs / InvITs**: net income is depreciation-distorted. Use NOI, FFO/AFFO, distribution per unit, occupancy, WALE, loan-to-value, cap rates. Sources: the trust's quarterly distribution statements, valuer reports (Indian REITs publish independent valuations semi-annually), SEBI REIT/InvIT disclosures. +- **Miners, oil and gas**: source reserves and resources from the technical reports that follow a recognized code (JORC, NI 43-101, SEC S-K 1300, SPE-PRMS) — not from the annual report summary. Track reserve life, grade, all-in sustaining cost, and note that reserve estimates are price-dependent and get restated when commodity prices move. +- **Utilities, infrastructure, telecom (India)**: regulated returns, tariff orders and licence conditions come from CERC/SERCs, TRAI, NHAI concession agreements. Contingent liabilities and disputed regulatory dues are often the dominant balance-sheet item. +- **Pharma**: USFDA inspection classifications (EIR, Form 483, warning letters, import alerts) are on the FDA site and are material events; ANDA/DMF filings, Paragraph IV status and patent cliffs come from company disclosures and FDA Orange Book. +- **Early-stage / loss-making / platform businesses**: the operating KPIs (GMV, take rate, contribution margin, cohort retention, CAC payback) exist only in investor presentations and calls, are management-defined, and change definition between quarters. Record the definition alongside the number and re-check it each quarter. + +--- + +## 12. When web access is unavailable or data is paywalled + +You will frequently be asked to analyse with incomplete access. Handle it explicitly rather than by inference. The document-first principle still applies: incomplete access means fewer documents, not a licence to substitute aggregator data. + +**Sequence:** +1. **Establish what you actually have.** Documents the user supplied, figures stated in the conversation, and your own general knowledge of the sector and its economics — which is durable — as distinct from company-specific figures, which are not. +2. **Ask the user for the documents themselves, naming them specifically.** Not "can you give me more data" but "please upload the FY25 annual report PDF, the last two concall transcripts, and the latest quarterly results filing from BSE." Named document requests get answered; vague ones do not. If you know the exact source (`bseindia.com` Corporate Filings, the company's IR page, EDGAR filing index) say where to get it. **Do not ask for or accept pasted screener.in tables or aggregator screenshots as a substitute for the document** — if the user provides aggregator data, accept it but mark every figure as `aggregator-sourced, unverified` and continue requesting the actual documents. +3. **Work from provided documents rigorously.** Extract with page/section citations so the user can audit you. If a supplied document is a screenshot or partial page, note what was cut off. +4. **State gaps explicitly and place them in the output.** Maintain a visible "Data gaps and their effect on this analysis" section: what is missing, why it matters, and which conclusions would change if the missing data went one way or the other. +5. **Downgrade the conclusion, not the honesty.** Say what the analysis can support at the available evidence level: structural and qualitative conclusions may hold firmly even when precise valuation does not. "On the available data, the business model and competitive position support X; the valuation question cannot be answered without the current share count and net debt" is a complete, useful answer. +6. **Never substitute a remembered or plausible number for a missing one.** Model knowledge of specific company financials is stale by construction, is often wrong at the level of precision that matters, and cannot be cited. If you genuinely recall an approximate figure, present it as an unverified recollection with an explicit uncertainty band and an instruction to verify, or omit it. +7. **Do not launder a guess through arithmetic.** Deriving a metric from an assumed input produces a figure that looks sourced and is not. If an input is assumed, label the output as scenario-based and show the assumption on its face. + +**Paywalled specifically:** rating rationales, DRHPs, exchange filings, EDGAR, IRDAI and RBI data and most company IR pages are free — exhaust these before concluding that data is unavailable. What is genuinely paywalled is usually consensus estimates, historical databases, full rating reports and specialist industry data. Say which class of data you are missing, because "no consensus estimate available" and "no financial statements available" are very different constraints. + +--- + +## 13. Never fabricate + +State this as a hard rule with no exception clause: **do not produce a company-specific figure you have not sourced.** + +The reason is asymmetric cost. An analysis with three acknowledged gaps still helps the reader — they know exactly where to look and exactly how much to trust each part. An analysis with one invented figure is worse than no analysis, because the reader cannot tell which figure is invented, so the entire document loses its evidentiary status. Worse, invented precision is self-reinforcing: a fabricated revenue figure produces a fabricated margin, a fabricated multiple and a fabricated conclusion, all internally consistent and all wrong. + +Specific failure modes to avoid: +- Filling a table cell because the table has a column for it. Write `n/a — not disclosed` or `not sourced`. +- Converting a qualitative recollection ("margins are around the mid-teens") into a number in a table. +- Producing a peer-comparison table where some rows are sourced and some are estimated, without marking which. +- Interpolating a missing year in a time series without labelling it as interpolated. +- Quoting a multiple without a price date, which is a fabrication of currency even when the arithmetic was once right. +- Attributing a statement to a concall or filing you did not read. + +Preferred vocabulary in output: `not disclosed`, `not sourced — verify`, `single source, unverified`, `estimated by me from [inputs] — not a company figure`, `as of [date]`. + +--- + +## Checklist + +- [ ] Every figure carries value + unit + basis (consolidated/standalone) + period + source. +- [ ] Headline figures (revenue, EBITDA, PAT, debt, equity, OCF, share count) cross-checked against a second independent source. +- [ ] Primary filing beats aggregator wherever they disagree; discrepancy investigated, not averaged. +- [ ] Consolidated used throughout; no ratio mixes consolidated and standalone; PAT is post-minority-interest. +- [ ] Units confirmed on every table read — crore vs lakh vs million; 1 crore = 10 million. +- [ ] Currency stated; FX rate and its date stated for any cross-currency comparison. +- [ ] Fiscal periods converted to calendar coverage; India FY ends 31 March; 52/53-week years noted. +- [ ] Prior-year figures checked for restatement, reclassification, discontinued operations and scheme effective dates. +- [ ] Price, market cap and all multiples stamped with an as-of date; share count taken from the latest filing. +- [ ] Derived ratios recomputed by me from raw line items, with formulas stated. +- [ ] Per-share history adjusted for splits and bonuses. +- [ ] India: shareholding pattern, promoter pledge trend, CARO qualifications, contingent liabilities, related-party note, latest rating rationale and rating history all reviewed. +- [ ] Global: 10-K MD&A and segment note, latest 8-Ks, DEF 14A compensation metrics and recent Form 4 activity reviewed. +- [ ] Latest concall/earnings-call Q&A read; prior guidance checked against delivery. +- [ ] Sector-appropriate sources used — banks, insurers, REITs, miners do not use the standard ratio set or the standard sources. +- [ ] Arithmetic sanity checks passed: statements tie, balance sheet balances, per-unit economics plausible. +- [ ] Single-sourced and unverified figures explicitly flagged as such. +- [ ] A visible "Data gaps" section exists wherever access was incomplete. +- [ ] Zero fabricated figures. Every cell is sourced, marked `n/a`, or explicitly labelled as my own estimate. diff --git a/finance/skills/stock-analysis/references/02-core-factors.md b/finance/skills/stock-analysis/references/02-core-factors.md new file mode 100644 index 00000000..f81e9963 --- /dev/null +++ b/finance/skills/stock-analysis/references/02-core-factors.md @@ -0,0 +1,423 @@ +# Core factors — business model, moat, industry and growth + +Use this when: you are at Stage 4 and need the universal, non-financial half of the analysis — what the business actually is, whether it can defend its economics, and whether it can reinvest at high returns for long enough to matter. + +Everything the financial statements show you is an *output*. This file covers the *inputs* that determine whether those outputs persist: the monetisation architecture, the moat mechanism and its direction, the structure of the industry, and the length of the reinvestment runway. Get these wrong and the ratio work is arithmetic about a business you have misunderstood. Two disciplines carry over from the governing principle: no factor here has a universal "good" level — read every number against sector peers and the company's own 5–10 year record — and never let one strong factor stand in for the set. + +## Contents + +- [How to work through this file](#how-to-work-through-this-file) +- [Part A — Business model and competitive moat](#part-a--business-model-and-competitive-moat) +- [Part B — Industry, market and competitive dynamics](#part-b--industry-market-and-competitive-dynamics) +- [Part C — Growth prospects and reinvestment runway](#part-c--growth-prospects-and-reinvestment-runway) +- [Verify against something the company did not write](#verify-against-something-the-company-did-not-write) +- [Where this generic frame breaks](#where-this-generic-frame-breaks) +- [Checklist](#checklist) + +## How to work through this file + +Three passes, in order. Each answers one question, and each depends on the one before it. + +1. **What is this business?** (Part A) — how it makes money, from whom, and why that is hard to take away. +2. **What game is it playing?** (Part B) — industry structure sets the ceiling on returns more often than management skill does. +3. **How much longer can it compound?** (Part C) — growth only creates value above the cost of capital, and only while the runway lasts. + +Write down the answers as short factual claims with a source and period attached, not as adjectives. "Top customer = 31% of FY25 revenue, disclosed under Ind AS 108 segment note" is analysis. "Customer concentration is a concern" is not. + +Do not run all forty-odd factors below at equal depth. For most companies three or four decide the outcome. Identify them early, evidence those properly, and use the rest to confirm nothing disqualifying was missed. + +**Source map.** US/global: 10-K Item 1 (Business), Item 1A (Risk Factors), Item 7 (MD&A), the segment footnote (ASC 280), 8-Ks, proxy, investor-day decks, earnings-call transcripts, EDGAR full-text search across competitors and customers. **India:** the annual report's Management Discussion & Analysis (mandatory content under SEBI LODR Schedule V — industry structure, opportunities and threats, segment performance, outlook, risks), the segment note under Ind AS 108, the Directors' Report and its annexures, the Business Responsibility & Sustainability Report, and — often the single richest source — the quarterly earnings **concall transcript**, which listed companies must publish on the website and file with the exchanges. Indian investor presentations carry order books, capacity, volumes and market-share claims that appear nowhere in the audited accounts; use them, and label them unaudited. + +--- + +## Part A — Business model and competitive moat + +### A1. Define the business before judging it + +Map exactly what products or services generate revenue, **who actually pays** (which is often not who uses), and the job being done for that payer. Break revenue *and gross profit* down by segment and by individual product line — profit concentration is almost always more extreme than revenue concentration, and one product frequently produces the overwhelming majority of economic profit while the narrative describes the whole portfolio. + +Test yourself: can you state the business and its profit engine in two plain sentences? If not, you do not yet know enough to assess the moat. Separate the *story* from where money is actually made. + +Judge mission-criticality: a product embedded in the customer's workflow, regulated process, or production line has structurally more durable economics than one that can be deferred a quarter without consequence. + +*Red flags:* refusal to disclose segment-level economics; a "diversified" structure masking one weak core; frequent unexplained pivots; reliance on a single hit product; you cannot articulate what the customer is buying. + +### A2. Monetisation mechanics + +Identify the architecture precisely — unit sale, subscription, usage/consumption, transaction take-rate, licence/royalty, advertising, leasing, freemium conversion, razor-and-blade with high-margin consumables, or marketplace commission. Then ask three things: who sets price, how often it is billed, and whether revenue scales with value delivered or is structurally capped. + +This matters because the architecture, not the industry label, drives margin structure, capital intensity, predictability and cyclicality. Consumption models capture upside but add volatility. Subscriptions add predictability and are evidence of switching costs. Advertising is cyclical and concentration-prone. In razor-and-blade and aftermarket models the real profit pool sits in the consumable — analyse *that* line, not the installed-base sales that look like the business. + +For platforms, quantify the take rate and interrogate its headroom. A rising take rate is frequently how a platform masks stalled volume growth. + +### A3. Revenue quality and recurrence + +Split revenue into contracted/recurring (subscriptions, maintenance, long-term service contracts, consumables) versus transactional, project or one-off. Then check contract length, auto-renewal terms, minimum commitments, remaining performance obligations (RPO) or backlog, and the deferred-revenue trend. Cohort retention tells you whether the installed base expands or leaks. + +Recurring revenue is worth more because it does not have to be re-won each period; it is also the cleanest observable evidence that switching costs exist. Be sceptical of the label: one-time hardware or perpetual-licence sales relabelled as "ARR", or annually re-solicited business described as recurring, is a common dressing-up. + +### A4. Unit economics + +Model one incremental customer or unit end to end: gross margin per unit, fully loaded customer acquisition cost, lifetime value, payback period, contribution margin after all variable costs. Ask whether the economics improve or degrade with scale, and — critically — whether they hold without promotional subsidy. + +A company can grow fast and still be uninvestable if each customer is unprofitable or payback is dangerously long. Sound unit economics are the precondition for self-funded growth; broken ones mean growth destroys value, and faster growth destroys it faster. + +Interrogate the LTV assumption itself. It is built on an assumed churn rate and discount rate, both chosen by the company. + +### A5. The moat sources — name the mechanism + +A moat is not an adjective. Identify which specific mechanism produces the excess return, or conclude there is none. + +**Pricing power.** The clearest external evidence of a moat. Examine the history of price increases against volume response, gross-margin behaviour through cost-inflation periods, whether price is a small and low-salience share of the customer's total cost, and whether pricing is value-based. The recent global inflation episode is a natural experiment: did the company pass input costs through cleanly, or discount to hold volume? + +**Switching costs.** Quantify what it actually costs a customer to leave — money, time, retraining, data migration, integration rework, certification, operational risk. Retention and renewal rates are the empirical test; footprint depth (modules or seats per account) is the leading indicator. + +**Network effects.** Establish whether each additional user increases value for existing users, and of which kind: direct, indirect/two-sided, or data. Then test the two things that break them — multi-homing, and networks that are locally dense but do not compound nationally. + +**Brand.** Test whether the brand changes buying behaviour and commands a price premium, not whether it is well known. Awareness is not a moat. Rising advertising spend merely to hold share is evidence against a brand moat, not for one. + +**Scale and cost advantage.** Establish whether size produces a structural unit-cost advantage — purchasing scale, manufacturing or logistics density, fixed-cost leverage, distribution reach, proprietary process — and verify it shows up in the margin gap versus smaller peers. If the claimed advantage is not visible in the numbers, it is not there. Also consider *efficient scale*: niches profitably served by one or two players where entry would destroy everyone's returns (pipelines, rail, regional utilities, a single-city cement market). + +**Intangibles: IP, patents, licences, regulatory exclusivity.** Inventory patents with revenue-weighted expiry dates, approvals, spectrum, franchises and concessions. Map the cliff explicitly. Legal exclusivity can be monopoly-grade, but it is time-bounded, can be litigated away, and can be legislated away — never model it as permanent. + +### A6. Dependencies that can end the business + +**Customer concentration.** Quantify revenue from the top 1/5/10 customers. In the US this surfaces via the 10-K and ASC 280 disclosure of any customer above 10% of revenue; **in India, Ind AS 108 requires the same entity-wide disclosure of major customers at the 10% threshold** — look for it in the segment note, and if it is absent for a company that is obviously concentrated, treat the silence as information. Assess contract length, tenure, and the risk that a large customer insources or vertically integrates. Include channel concentration: one distributor or one retailer can be the real dependency. + +**Supplier and input dependence.** Identify single- or sole-sourced critical inputs, one contract manufacturer, one foundry, one API supplier, one geography. Assess substitutability, second-source qualification, inventory buffer, and hedging. No demand-side moat survives an input that cannot be obtained. In India, Schedule III requires disclosure of cost of materials consumed, which lets you size input dependency even where suppliers are not named. + +**Geographic mix.** Break revenue *and operating profit* by region. Ask whether the moat travels — many models that dominate a home market fail abroad, which both caps the runway and turns expansion into value destruction. Flag single-country dependence for the bulk of profit or upside, unhedged FX exposure, and repatriation or capital-control risk. + +### A7. Moat synthesis — width, durability, direction + +Now combine. Width is how large the excess return; durability is how many years it persists; **direction is usually the more valuable judgement.** A narrowing wide moat is often a worse investment than a widening narrow one, because the market has already paid for the width. + +Measure how long the company has earned returns above its cost of capital and whether that spread is widening, stable or narrowing. Then name the primary disruption vector explicitly — technological change, business-model disruption, or counter-positioning where the incumbent cannot respond without cannibalising its own economics. If you cannot name a plausible way the moat is attacked, you have not looked hard enough. + +Mechanics of ROIC and the ROIC–WACC spread are in `references/05-returns-and-dupont.md`; use those numbers here as evidence, and do not double-count them as a separate score. + +### Part A metric set + +Ranges are **indicative only**. They shift by market, by sector, by cycle and by period; peer and own-history comparison overrides every band below. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Revenue and gross profit by segment/product** | Each segment or product line as % of total revenue *and* of total gross profit, from the segment note (ASC 280 / Ind AS 108) | No single product >~50% of profit without a credible follow-on; profit concentration usually exceeds revenue concentration | Locates the real profit engine, which is frequently not the one the narrative describes | +| **Recurring revenue mix** | Contracted/subscription/consumable revenue ÷ total revenue | >70% is a genuinely subscription business; 30–70% hybrid; interrogate any "recurring" claim below that | Recurring revenue does not have to be re-won each period and is direct evidence of switching costs | +| **Net revenue retention (NRR/NDR)** | Revenue this period from last period's cohort ÷ that cohort's prior revenue, including expansion, contraction and churn | >120% exceptional, 110–120% strong, 100–110% adequate, <100% the base is leaking | The single best test of lock-in; above 100% the business grows with zero new customers | +| **Gross retention / logo churn** | Cohort revenue retained before any expansion; annual customer churn % | Gross retention >90% for enterprise, >80% SMB; churn trend matters more than level | Strips out the flattering effect of upsell into a shrinking base | +| **LTV/CAC and CAC payback** | Lifetime gross profit per customer ÷ fully loaded acquisition cost; months of contribution margin to repay CAC | LTV/CAC >3x; payback <12 months consumer/SMB, <24 months enterprise | Determines whether growth is self-funding or a subsidy; lengthening payback is an early warning | +| **Contribution margin per unit** | Revenue less *all* variable cost per unit or transaction | Positive and improving with scale | Negative contribution margin means growth accelerates value destruction | +| **Realised price growth vs volume growth** | Split reported revenue growth into price, volume, mix and FX (percentage points) | Both positive is the franchise signature; price-only with falling volume is demand destruction | The cleanest quantitative read on pricing power | +| **Gross margin level and 5–10 yr trend** | Gross profit ÷ revenue, against peers of similar model | Stable or rising through an input-cost shock | Margin held through inflation is pricing power demonstrated, not asserted | +| **Take rate (platforms)** | Net revenue ÷ GMV or gross transaction value | Level is sector-specific; the *trend* and its driver are what matter | A rising take rate frequently masks stalled volume | +| **Customer concentration** | Top-1, top-5, top-10 customers as % of revenue | Top customer <10%; >20% is a single-point-of-failure | Concentrated buyers extract margin and can end revenue abruptly | +| **Single-sourced critical inputs** | Count of critical inputs with no qualified second source; key input as % of COGS | Zero sole-sourced critical inputs, or a qualified alternate | Supply failure is existential and not offset by any demand-side moat | +| **Revenue exposed to patent/licence expiry** | % of revenue from products losing exclusivity within 3–5 years, with dates | Low, and covered by a late-stage pipeline | Cliffs are dateable, foreseeable, and routinely under-modelled | +| **Years of ROIC > WACC, and spread trend** | From `05-returns-and-dupont.md`; plot the spread over 10 years | A long run with a stable or widening spread | Duration and direction of excess returns is the largest driver of intrinsic value | + +--- + +## Part B — Industry, market and competitive dynamics + +Industry structure sets the ceiling on returns more reliably than management quality does. A capable operator in a structurally bad industry usually loses to a mediocre one in a good industry. + +### B1. Market size, and whether the sizing is honest + +Decompose into TAM, SAM (serviceable addressable) and SOM (serviceable obtainable). Establish whether the estimate is bottom-up (units × price × realistic penetration) or a top-down number lifted from a slide. Note who produced it and when — company IR, a sell-side bank, or an independent body. In India, industry sizing usually traces to CRISIL, ICRA, industry associations (SIAM, IPA, CREDAI, IBEF) or a company-commissioned consultant; treat commissioned sizing as marketing until independently checked. + +Then do the step that matters: **back-calculate the market share the company must reach to justify the current price.** This converts a vague "huge market" into a testable claim. Cross-reference the reverse-DCF in `references/06-valuation.md`. + +*Red flags:* TAM revised upward to defend a falling stock; adjacent-market TAM stacking; "we only need 1% of a giant market"; a bottom-up build implying more than 100% of any realistic segment. + +### B2. Growth rate and position on the S-curve + +Locate the industry on the adoption curve — early adopters, mass market, or saturation. Decompose industry growth into volume, price and mix. Separate durable secular demand from pull-forward (pandemic, subsidy, pre-buy ahead of a regulation change) that will normalise. Compare industry growth to nominal GDP: much of what is marketed as a growth market is GDP plus inflation. + +Mistaking a maturing market for a growth market is one of the most expensive errors available, because the multiple and the growth rate de-rate together. + +### B3. Structure, concentration and the rationality of competitors + +Count the players and map the share distribution. Compute CR4/CR8 and, where you have share data, the Herfindahl-Hirschman Index. Establish the trajectory — consolidating or fragmenting. + +Then ask the question that concentration statistics miss: **are the competitors rational?** A single player that does not maximise profit — state-owned, subsidy-funded, PE-backed and buying share to exit, or a subscale player pricing for survival — can compete away the profit pool for everyone in a structurally concentrated industry. This is a live issue in Indian PSU-heavy sectors and in any market where a well-funded entrant is buying share. + +### B4. Rivalry intensity and how share actually moves + +Trace market share over 5–10 years, and establish *how* it moves — through price, product or distribution. Share earned without price concessions is owned; share bought with rebates and promotions is rented. Watch whether R&D and advertising intensity must keep rising just to hold position: that is a moat being consumed to look stable. + +### B5. The five forces, applied concretely + +**Supplier power** — supplier concentration relative to the industry, substitutability, single-sourcing, the threat of a supplier forward-integrating, and the industry's demonstrated ability to pass input costs through and with what lag. + +**Buyer and channel power** — buyer concentration, price sensitivity, backward-integration ability, and the gatekeepers sitting between the company and the end user (mega-retailers, distributors, group purchasing organisations, app stores, marketplaces, hospital chains, e-commerce platforms). A dominant channel quietly becomes the industry's real profit-taker; watch its take rate. + +**Barriers to entry** — enumerate and stress-test each one: minimum efficient scale versus market size, capital intensity, licences, IP, network effects, brand, switching costs, proprietary distribution, learning-curve cost. Judge whether each is widening or eroding. High sustained margins with low barriers are an invitation, not a moat. + +**Substitutes and disruption** — map what else does the same job, and track the *price-performance trajectory* of the alternative rather than its current position. Apply the low-end and new-market disruption lens. Substitution destroys value permanently rather than cyclically, and the financials look fine until the inflection. + +### B6. Cyclicality, and where in the cycle you are standing + +Classify demand drivers as cyclical (GDP, credit, capex, housing, commodity price), seasonal, or secular. Locate the position in the cycle and estimate mid-cycle normalised margins and earnings rather than trusting the current print. + +**The peak-cycle trap:** record margins alongside an optically low P/E is the classic value trap, not a bargain. The inverse error — reading a structural decline as a cyclical dip — destroys just as much capital. Deep cyclicals get the overlay in `references/13-situations.md`. + +### B7. The capital cycle — watch supply, not demand + +Track industry-wide capacity additions against demand growth, allowing for capex lead times. Monitor utilisation, whether capital is flooding in (competitor expansions, IPOs, PE and VC funding, announced greenfield projects) or leaving, and channel inventory. + +Returns are driven more by changes in supply than by demand forecasts. Heavy investment in good times sows the next glut; capital fleeing a hated industry sets up the next up-cycle. Aggregate industry capex ÷ depreciation is the cheapest single supply-side indicator available. This lens is decisive in cement, chemicals, steel, shipping, semiconductors, hotels and airlines. + +### B8. Regulation, policy and political economy + +Map the whole regime — antitrust, price control, tariffs, environmental and emissions rules, data and privacy, licensing, reimbursement, safety — plus pending legislation. Quantify dependence on subsidy, tax incentive or regulatory arbitrage. + +**India-specific:** price control and trade-margin rationalisation (NPPA/DPCO in pharma), tariff and anti-dumping orders, GST rate changes, PLI scheme dependence, sectoral regulators (RBI, IRDAI, TRAI, CERC/SERCs, RERA), and the pattern of retrospective or mid-stream policy change. Sizeable chunks of reported profit in PLI-supported sectors are policy income, not franchise income — say so explicitly. + +**US/global:** FDA and reimbursement, FTC/DOJ antitrust posture, IRA/CHIPS-style incentives, tariff schedules, state-level utility rate cases, EU DMA/DSA obligations. + +### B9. Where the profit pool sits, and which layer the company occupies + +Map profit along the value chain and, more importantly, the direction it is migrating — hardware to software, OEM to platform, network to content, manufacturer to brand owner. Compare ROIC across peers and against WACC. Establish whether the whole industry earns above its cost of capital or only one or two players do. + +Some industries destroy capital regardless of management quality; much of airline and dry-bulk shipping history is the proof. Owning the layer the profit pool is moving *toward* is frequently the entire call. + +### B10. Commoditisation + +Commoditisation is the default state of most products. Test whether differentiation is real: can the industry price above inflation without losing volume, and pass input costs through, and with what lag? Track premium versus private label or generic, and the degree of spec interchangeability. Slow gross-margin compression across an industry is what commoditisation looks like in the accounts, years before anyone calls it that. + +### Part B metric set + +Indicative only — vary by market, cycle and period; peer and own-history comparison overrides them. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Penetration (revenue ÷ TAM)** | Company revenue as % of a credibly built, bottom-up TAM | Low penetration only counts if the TAM is independently sourced | Sets the ceiling; the number most often inflated to justify a multiple | +| **Implied share needed** | Back-solve from the reverse DCF: what share must be reached to justify today's price | Comfortably below the current leader's share | Turns a narrative into a falsifiable claim | +| **Industry CAGR vs nominal GDP** | 3/5/10-yr industry growth ÷ nominal GDP growth | >1.5x GDP is a genuine growth industry | Distinguishes secular tailwind from inflation | +| **CR4 / HHI** | Top-4 combined share; sum of squared shares (US DOJ convention: >2,500 concentrated, 1,500–2,500 moderate, <1,500 unconcentrated) | Concentrated *and* rational is the profitable combination | Structure predicts industry profitability better than any single firm's strategy | +| **Market-share trend** | Basis points gained/lost per year over 5–10 yrs, and the mechanism | Flat-to-rising share *without* price concession | Share bought with discounts is rented and reverses | +| **Industry capacity utilisation** | Output ÷ installed capacity, industry-wide | 80–85% is typically the pricing-power threshold; below ~70% price discipline breaks | The supply-side variable that sets industry pricing | +| **Industry capex ÷ depreciation** | Aggregate peer capex ÷ aggregate depreciation | ~1.0 = replacement; sustained >1.5 across an industry warns of a coming glut | The single best early indicator in the capital cycle | +| **Book-to-bill** | Orders received ÷ revenue billed in the period | >1.0 growing, <1.0 for two-plus quarters is a genuine warning | Forward-looking where backlog exists | +| **Industry ROIC vs WACC** | Median peer ROIC less WACC; also the dispersion across peers | Median above WACC, with the company in the upper quartile | Reveals whether the industry creates value at all, or only its best player does | +| **Current margin vs 10-yr mid-cycle** | Current EBIT margin ÷ 10-year average margin | Near 1.0 for normalisation; well above 1.0 means you are underwriting peak | Prevents the peak-cycle low-P/E trap | +| **Realised price vs input inflation** | Company/industry realised price growth less input-cost inflation | ≥0 through a cost shock | Direct test of commoditisation | +| **Revenue dependent on subsidy or regulated price** | % of revenue or EBIT from subsidy, incentive scheme or a regulated tariff | Known, quantified, and modelled to expiry | Policy income is not franchise income and can end on a date | + +--- + +## Part C — Growth prospects and reinvestment runway + +Growth is not intrinsically good. Growth at returns below the cost of capital destroys value, and the faster it grows the more it destroys. This section establishes three things: was past growth real, is incremental capital earning a return, and how many years of that are left. + +### C1. Decompose historical growth — never accept a CAGR + +Compute 3/5/10-year revenue CAGR, then break it apart: + +- **Organic vs inorganic.** For any acquisitive company this is the whole analysis. Strip acquisitions and ask what the base business did. +- **Organic into volume, price, mix and FX**, in percentage points. +- **By segment and geography**, to see whether growth is broad-based or one product in one region. +- **Sequential (QoQ) as well as YoY**, because inflections show up sequentially first. + +Adjust for revenue-recognition changes (ASC 606 / Ind AS 115), divestitures, and one-off commodity or pandemic spikes that distort the base. Volume-led organic growth is the highest-quality kind; price-only, FX-only or acquisition-fuelled growth is far less repeatable and often conceals a stagnating core. + +For serial acquirers specifically, project what reported growth looks like when M&A pauses — and scrutinise purchase accounting (fair-value step-ups, restructuring reserves created in acquisition accounting then released to earnings, contingent-consideration remeasurement, "one-off" integration costs that recur every single year). Roll-ups can show rising reported EPS while the acquired businesses shrink, because each deal resets the baseline. Detail in `references/07-forensic-red-flags.md`. + +### C2. Earnings growth quality + +Separate EPS growth into revenue growth, margin expansion, share-count reduction, tax-rate change, and below-the-line items. Compare EPS CAGR to net-income CAGR to revenue CAGR — EPS can outgrow net income purely through buybacks. Then verify earnings convert to cash (see `references/03-earnings-quality.md` and `references/04-balance-sheet-and-cashflow.md`), and read the GAAP-to-adjusted bridge for add-backs that are growing, recurring, and real (stock-based compensation above all). + +Growth manufactured by financial engineering is not evidence of a compounding business. + +### C3. Reinvestment rate and incremental return on capital + +This is the most important factor in Part C and the most commonly skipped. + +Reinvestment rate ≈ (net capex + acquisitions + change in net working capital + capitalised R&D or growth opex) ÷ NOPAT. + +ROIIC ≈ Δ NOPAT ÷ Δ invested capital, measured over rolling 3–5 year windows so a single year's lumpiness does not dominate. + +Then compare ROIIC to WACC and to the company's own average ROIC. **ROIC tells you about capital already deployed; ROIIC tells you about the capital being deployed now** — which is what you are actually buying. ROIIC well below reported average ROIC means a good legacy business is subsidising poor new investment, and reported ROIC will fade toward the incremental rate over time. Full mechanics in `references/05-returns-and-dupont.md`. + +### C4. Runway length and the sustainable growth identity + +Anchor on: **sustainable growth ≈ reinvestment rate × ROIC.** A company returning most of its earnings cannot also compound at a high rate; if the guidance implies otherwise, something in the model is wrong. + +Then estimate how many years of high-return reinvestment remain: TAM penetration, remaining white space, store or plant or route density versus a realistic ceiling, and whether the pipeline of projects clearing the hurdle rate is expanding or shrinking. Two companies with identical ROIC differ enormously in value if one has twenty years of runway and the other three. Runway is what justifies — or refutes — a premium multiple. + +A specific tell: high ROIC with cash piling up and buybacks replacing capex usually means the reinvestment opportunity set has closed, whatever the growth narrative says. + +### C5. Backlog, order book and RPO — the forward evidence + +For industrials, capital goods, defence, EPC, construction, semis and subscription software, examine backlog or order book size and growth, coverage (backlog ÷ trailing revenue, expressed in months or years), book-to-bill, RPO and current RPO, de-booking and cancellation rates, and the *margin* embedded in the backlog. + +These are among the few forward-looking, semi-verifiable indicators available. A shrinking backlog warns that reported revenue growth is about to roll over while the income statement still looks strong. + +Interrogate quality: backlog padded with non-binding letters of intent or framework agreements, backlog growing only because delivery times lengthened, or a large low-margin cancellable order presented as firm. **India note:** order-book figures for EPC, capital goods and defence companies come from investor presentations and concalls and are unaudited — check whether the definition (firm orders, L1 orders won but not awarded, framework agreements) changed between periods. + +### C6. Capex intensity and the maintenance/growth split + +Split capex into maintenance and growth. Management sometimes discloses the split; otherwise estimate maintenance as depreciation adjusted for inflation and asset-base growth, and say plainly that it is an estimate. + +Then review announced expansion: new plants, fabs, stores, data centres, mines — greenfield versus brownfield, budgeted cost, capacity added, timeline, ramp curve, expected return and payback. Compare against the previous announcement to catch cost overruns and slippage, which are chronic in Indian infrastructure, cement, metals and specialty-chemicals expansions. + +Growth capex is where value is most often destroyed: mistimed, over-budget, or built at cycle-peak equipment prices into a market that will be oversupplied by the time it commissions. Cross-check against the industry capital cycle in B7 — the moment to be suspicious is when the whole industry is expanding at once. + +### C7. The forward bridge — make growth arithmetic, not narrative + +Take management's stated drivers (new products, secular tailwind, share gain, price, geographic entry) and build an additive bridge from today's revenue to the target, driver by driver, in percentage points. Then check the drivers actually sum to the target, and that each one is independently plausible. + +Separate secular from cyclical demand in that bridge. Extrapolating cyclical peak demand as structural is how peak-cycle multiples get paid. + +### C8. Innovation: pipeline and R&D productivity + +Assess the vitality index — revenue from products launched in the last 3–5 years — alongside R&D as % of revenue *and its productivity* (incremental revenue or gross profit per R&D rupee/dollar). R&D spend is an input; productivity is the output that separates innovators from cash-burning labs. + +Review launch cadence, the hit rate of past launches, the patent and exclusivity timeline, and pipeline depth by stage. A falling vitality index means the company is living off legacy products, which is a growth cliff with a date on it even when current earnings look fine. + +### C9. Adjacency and new-market expansion + +Ask whether there is a demonstrated right to win — a transferable capability, brand or distribution — or whether this is diworsification. The evidence is the track record: did earlier new-market entries reach target economics, or quietly stall and retreat? Compare unit economics and payback in new markets against the mature core. + +A repeatable expansion playbook (a retailer that reliably hits store economics in each new region) is a powerful and durable driver. Serial entry-and-retreat means the runway is narrower than claimed. + +### C10. Price, volume and mix in forward growth + +Determine how much future growth is priced versus volume, and whether price sticks without volume loss. Price-led growth carries close to 100% incremental margin and is highly durable when backed by brand, switching costs or scarcity — and is a warning sign when volumes fall as prices rise. Check contractual escalators, and test whether a "premiumisation" narrative is actually visible in mix data. + +### C11. Guidance credibility + +Build a scorecard of guidance versus actuals across the last 8–12 quarters and of multi-year targets versus delivery. Does management beat, meet, sandbag or miss? How does initial full-year guidance evolve — serial cuts or raises? Were the previous analyst-day roadmap and "catalysts" delivered? + +Their historical accuracy is the best available prior for the current forecast. Serial over-promisers should have their projections discounted heavily regardless of how good the current story sounds. **India note:** formal numeric guidance is less common; the equivalent evidence is concall commentary — capacity commissioning dates, margin guidance, order-inflow expectations — checked against what subsequently happened. Watch for goalposts moving and for KPIs quietly dropped when they turn unfavourable. + +### C12. Capital allocation track record + +Over a decade this is often the largest single driver of per-share value. Assess the full history across organic reinvestment, M&A, buybacks, dividends and debt paydown. + +For M&A: prices paid, goodwill impairment history, synergy realisation, post-deal ROIC. For buybacks: were they executed at low or high valuations? A buyback at a stretched multiple is value destruction dressed as shareholder return. Judge whether capital consistently flows to the highest-return use and whether management can articulate a hurdle rate. + +Governance dimensions of the same question — related-party leakage, promoter-group transactions, empire building — are in `references/08-governance.md`. + +### C13. Deceleration risk and the law of large numbers + +Compute the **absolute** revenue the company must add each year to sustain its growth rate, and judge whether that is plausible given market size and share. High percentage growth becomes arithmetically harder as the base compounds. + +Watch the deceleration signals: sequential growth slowing, leading indicators (bookings, backlog, app downloads, hiring) decelerating ahead of reported revenue, comps getting harder, share nearing a ceiling. Then distinguish a comp-driven air pocket from structural maturation. + +Identifying the inflection from hyper-growth to mature growth is one of the highest-value calls in equity analysis, because multiples de-rate violently and simultaneously with the growth rate. + +Apply the **outside view** here. Before accepting a bottom-up forecast, ask what the base rate is: how often do companies of this size actually sustain 20%+ growth for a decade, how often do turnarounds and roll-ups work, and how fast does excess ROIC historically fade toward the cost of capital? Bottom-up models produce systematic inside-view optimism; base rates are the cheapest correction available. More in `references/17-process-and-epistemics.md`. + +### C14. How the growth is funded + +Establish whether growth is funded by internally generated cash, debt, or equity issuance. Compute the funding gap (reinvestment need less operating cash flow) and how it is plugged. Track share-count growth from issuance and stock-based compensation, convertible and warrant overhang, and leverage rising to fund capex. + +**Per-share growth is what accrues to owners.** A company growing revenue 20% while issuing 15% more shares is barely compounding for you. Growth requiring continual external capital is fragile because it depends on capital markets staying open and cheap. Self-funded growth is the gold standard of a durable runway. + +### Part C metric set + +Indicative only — vary by market, cycle and period; peer and own-history comparison overrides them. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Organic vs inorganic growth split** | Revenue growth excluding acquisitions completed in the last 12 months, vs total | Majority organic; know the number before judging anything else | Acquired growth is bought, not earned, and stops when M&A stops | +| **Volume / price / mix / FX contribution** | Decomposition of organic growth into pp of each | Positive volume contribution in most years | Volume-led growth is the most durable form | +| **ROIIC (incremental ROIC)** | Δ NOPAT ÷ Δ invested capital over rolling 3–5 yr windows | Above WACC with a clear margin; ~15–20%+ marks a genuine compounder in most sectors | Prices what the capital being deployed *now* will earn | +| **Reinvestment rate** | (Net capex + acquisitions + Δ NWC + capitalised growth spend) ÷ NOPAT | High is good *only* when ROIIC is high; high with weak ROIIC is the worst combination | Determines how much of the return compounds internally | +| **Sustainable growth rate** | Reinvestment rate × ROIC | Should roughly reconcile to guided growth | Exposes guidance that is arithmetically impossible | +| **Backlog coverage** | Backlog ÷ trailing 12-month revenue, in months or years | Sector-dependent; the *trend* and de-booking rate carry the signal | Forward visibility, and the first place a slowdown appears | +| **Book-to-bill** | Orders ÷ billings for the period | >1.0; below 1.0 for consecutive quarters is a real warning | Leads reported revenue by two to four quarters | +| **RPO / cRPO growth** | Remaining performance obligations, and the portion due within 12 months | cRPO growth ≥ revenue growth | Detects subscription growth rolling over before revenue does | +| **Capex ÷ depreciation** | Total capex ÷ depreciation and amortisation | ~1.0 maintenance-only; 1.5–2.5 genuine expansion; sustained >2 with flat returns is a warning | Separates real expansion from treadmill spending | +| **Growth vs maintenance capex** | Disclosed split, or estimate maintenance as inflation-adjusted depreciation | Growth capex tied to specific projects with stated returns | Reveals the true free cash flow of the business as it stands | +| **Vitality index** | % of revenue from products launched in the last 3–5 years | 15–30% for consumer and industrial innovators; higher in pharma/tech | Leading indicator of organic growth; falling means living off legacy | +| **R&D productivity** | Incremental gross profit ÷ trailing R&D spend | Rising, or at least stable | R&D spend is an input; only the return on it is evidence | +| **Guidance hit rate** | Beat/meet/miss across trailing 8–12 quarters, plus multi-year targets set vs achieved | Consistent meet-or-modest-beat, no serial in-year cuts | The best available prior on the credibility of the forward case | +| **Share count growth** | Diluted share count CAGR, including SBC and convertibles | ≤0 for mature businesses; <2–3%/yr for growth names | Aggregate growth means nothing if per-share growth is diluted away | +| **SBC as % of revenue** | Stock-based compensation ÷ revenue | Low single digits outside early-stage software | A real cost, routinely adjusted out, and a direct transfer from shareholders | +| **Self-funding test** | FCF after growth capex; funding gap = reinvestment need − OCF | Non-negative, or a credible dated path to it | Growth dependent on open capital markets is fragile by construction | +| **Absolute revenue add required** | Current revenue × target growth rate, in currency | Small relative to the realistic addressable market | The law of large numbers, made concrete | + +--- + +## Verify against something the company did not write + +Everything above can be answered entirely from company-produced documents — which is exactly how a fabricated or deteriorating business passes a desk-based checklist. Add at least one independent cross-check for any thesis you intend to act on. + +- **Alternative data.** Web traffic and app-download trends, app-store and review-site ratings, job postings and headcount (LinkedIn), employee-review sentiment and attrition, card/transaction panels, freight and customs data. **India-specific proxies:** GST and e-way-bill volumes, VAHAN vehicle-registration data for autos, SIAM dispatch numbers, DGCA traffic data for airlines, AWACS/IQVIA secondary sales for pharma, RBI sectoral credit data, port and rail freight statistics. Divergence between reported growth and every external proxy for it is the earliest tell available. +- **Scuttlebutt.** Use the product. Read customer reviews. Talk to customers, distributors, suppliers or ex-employees where feasible. Financial statements are lagging; ground-level observation moves quarters earlier and is one of the few genuine edges available. +- **Proof of existence.** For asset-heavy or geographically remote claims, corroborate that the plants, mines, stores or data centres exist and operate — satellite imagery, environmental clearances and building permits, power draw, shipping and customs records, statutory filings of subsidiaries (MCA/ROC filings in India) reconciled to consolidated claims. +- **Per-employee productivity.** Revenue and gross profit per employee versus peers and over five-plus years. Hard to fabricate, and it quietly validates or refutes claimed scale. A hiring freeze that contradicts a growth story is an independent warning. +- **Bespoke KPI audit.** Catalogue every company-invented metric (ARR, bookings, GMV, MAU, "cash EBITDA", contribution margin ex-marketing, order book) with its exact definition, and check whether the definition changed year over year and whether it reconciles to audited revenue or cash. A shifting denominator keeps a growth narrative alive after the audited numbers have rolled over. +- **Year-over-year redline.** Diff consecutive annual reports and 10-Ks for changes in risk-factor wording, segment definitions, accounting-policy and useful-life assumptions, and — most valuable — disclosures and metrics quietly *dropped*. Management highlights what it adds and never what it removed. Cheap, and high-yield. +- **Vendor and customer financing.** Check whether the company lends to, guarantees, or extends unusually long credit to its own customers or channel to enable purchases (captive finance arms, channel financing, seller notes). Revenue funded by the seller's own credit reads as clean organic growth until the receivables sour. +- **Read the other side.** Find the strongest existing bear case — short-seller reports, sceptical sell-side notes, forum criticism with actual numbers in it — and state what the informed money on the other side sees before deciding it is wrong. + +--- + +## Where this generic frame breaks + +Apply the sector playbook before using any of Part C's growth metrics. In these sectors the generic frame is not merely less useful — it is inverted or undefined. + +- **Banks and lenders** — above-system loan growth is the best leading indicator of the *next* credit cycle's losses, not an achievement. There is no meaningful capex or FCF, so reinvestment rate and capex/depreciation are noise; the reinvestment constraint is regulatory capital (CET1), and sustainable growth = ROA × leverage × retention. The moat is the deposit franchise, not the loan book. See `references/sectors/banks.md` and `nbfc.md`. +- **Insurers** — top-line premium growth can be bought by underpricing risk, and the loss shows up years later. Growth is measured in VNB, APE and new-business margin, not revenue. See `references/sectors/insurance.md`. +- **REITs, InvITs and real estate** — growth is same-store NOI plus acquisitions, and acquisitions only create value if the cap rate exceeds the cost of capital. Use AFFO and NAV, not EPS. See `references/sectors/realestate-reit.md`. +- **Miners, commodity producers, refiners** — there is no pricing power by construction; price is exogenous. The moat is position on the industry cost curve, reserve life and grade. TAM analysis is meaningless; the capital cycle in B7 is the whole game. See `references/sectors/metals-mining.md` and `oil-gas.md`. +- **Regulated utilities** — growth is rate-base growth at an allowed return, so the regulator is the business model. See `references/sectors/utilities-power.md`. +- **Holdcos and conglomerates** — analyse the underlying businesses separately and value sum-of-the-parts; group-level growth and margin are aggregation artefacts. See `references/sectors/holdco-assetmgr.md`. + +--- + +## Checklist + +**Business model and moat** +- [ ] Business and profit engine stated in two plain sentences, with revenue *and gross profit* split by segment/product. +- [ ] Monetisation architecture named; who sets price identified; take rate quantified for platforms. +- [ ] Recurring vs one-off revenue split; NRR, gross retention and churn sourced, not assumed. +- [ ] Unit economics modelled end to end: contribution margin, LTV/CAC, payback — and tested without subsidy. +- [ ] Pricing power evidenced by realised price vs volume and by gross margin through a cost shock. +- [ ] Switching costs quantified in money and time; retention used as the empirical test. +- [ ] Network effects classified (direct/indirect/data) and multi-homing checked. +- [ ] Brand tested for price premium and behaviour change, not awareness. +- [ ] Cost advantage verified in the margin gap versus smaller peers, not asserted. +- [ ] Patents, licences and exclusivity inventoried with revenue-weighted expiry dates. +- [ ] Top-1/5/10 customer concentration pulled from the segment note (ASC 280 / Ind AS 108); channel concentration included. +- [ ] Sole-sourced critical inputs and single-geography supply identified. +- [ ] Revenue and EBIT split by geography; single-country dependence and FX exposure flagged. +- [ ] Moat width, durability **and direction** stated, with the primary disruption vector named. + +**Industry and competitive dynamics** +- [ ] TAM traced to its source and its build method; implied share needed back-solved from the current price. +- [ ] Industry growth decomposed and compared to nominal GDP; pull-forward demand identified. +- [ ] Concentration measured (CR4/HHI) *and* competitor rationality assessed. +- [ ] Market-share trend traced over 5–10 years, with the mechanism of share movement identified. +- [ ] Supplier power, buyer/channel power, entry barriers and substitutes each assessed concretely. +- [ ] Position in the cycle established; mid-cycle normalised margin estimated before any multiple is applied. +- [ ] Industry capacity additions, utilisation and capex/depreciation checked — the supply side, not just demand. +- [ ] Regulatory regime mapped; subsidy- and policy-dependent profit quantified (India: DPCO/NPPA, PLI, tariff orders). +- [ ] Profit-pool location and migration direction identified; peer ROIC dispersion vs WACC compared. +- [ ] Commoditisation tested via realised price vs input inflation and premium vs private label. + +**Growth and reinvestment runway** +- [ ] Revenue growth decomposed: organic vs inorganic, then volume/price/mix/FX, by segment and geography, YoY and QoQ. +- [ ] EPS growth decomposed; buyback, tax and one-off contributions separated; GAAP-to-adjusted bridge read. +- [ ] Reinvestment rate and ROIIC computed over rolling windows and compared to WACC and to average ROIC. +- [ ] Sustainable growth (reinvestment rate × ROIC) reconciled against guided growth. +- [ ] Backlog/order book/RPO, coverage, book-to-bill and de-booking checked; definition changes caught (India: unaudited). +- [ ] Capex split into maintenance and growth; announced projects checked against prior announcements for overrun and slippage. +- [ ] Forward growth bridge built driver by driver in percentage points, and the drivers actually sum to the target. +- [ ] Vitality index and R&D productivity computed; patent cliff dated. +- [ ] Track record of prior adjacency and geographic expansions assessed. +- [ ] Guidance-vs-actual scorecard built over 8–12 quarters (India: concall commitments vs outcomes). +- [ ] Capital allocation history judged: M&A prices and post-deal ROIC, impairments, buyback valuations. +- [ ] Absolute revenue add required to sustain the growth rate computed; leading indicators checked for deceleration. +- [ ] Base rate for the claimed growth durability checked against the reference class, not just the model. +- [ ] Funding gap, share-count growth and self-funding test completed; per-share growth compared to aggregate growth. + +**Independent verification** +- [ ] At least one non-company data source cross-checked against the reported growth curve. +- [ ] Bespoke KPIs catalogued and definition changes checked. +- [ ] Consecutive filings redlined for dropped disclosures. +- [ ] The strongest bear case read and answered on its own terms. diff --git a/finance/skills/stock-analysis/references/03-earnings-quality.md b/finance/skills/stock-analysis/references/03-earnings-quality.md new file mode 100644 index 00000000..2476ac3a --- /dev/null +++ b/finance/skills/stock-analysis/references/03-earnings-quality.md @@ -0,0 +1,383 @@ +# Income Statement Analysis and Earnings Quality + +Use this when: you are at Stage 4 and need to establish whether the reported profit is real, repeatable, and earned by the operating business. + +The income statement is the most-read and least-trusted of the three statements. It is the one management has the most discretion over, the one that drives headlines and multiples, and the one that can be made to say almost anything within the rules. Your job here is not to admire the profit number — it is to take it apart, find out which parts recur, which parts are cash, and which parts are the accounting equivalent of a loan from next year. Everything downstream (returns on capital, valuation, scoring) inherits the errors you fail to catch here. + +## Contents + +- [1. The OPM trap — read this before computing any margin](#1-the-opm-trap--read-this-before-computing-any-margin) +- [2. Revenue growth decomposition](#2-revenue-growth-decomposition) +- [3. The margin ladder](#3-the-margin-ladder) +- [4. Operating leverage and the fixed/variable split](#4-operating-leverage-and-the-fixedvariable-split) +- [5. Below-the-line: the EBIT-to-PAT bridge](#5-below-the-line-the-ebit-to-pat-bridge) +- [6. Other income reliance](#6-other-income-reliance) +- [7. One-offs, exceptionals and the adjusted-earnings gap](#7-one-offs-exceptionals-and-the-adjusted-earnings-gap) +- [8. Tax normalcy and sustainability](#8-tax-normalcy-and-sustainability) +- [9. Accruals versus cash — the single highest-yield test](#9-accruals-versus-cash--the-single-highest-yield-test) +- [10. Revenue recognition aggressiveness](#10-revenue-recognition-aggressiveness) +- [11. Vendor and customer financing — demand bought with your own balance sheet](#11-vendor-and-customer-financing--demand-bought-with-your-own-balance-sheet) +- [12. Per-employee productivity cross-check](#12-per-employee-productivity-cross-check) +- [13. Segment profitability and mix](#13-segment-profitability-and-mix) +- [14. Share-based comp, dilution and per-share quality](#14-share-based-comp-dilution-and-per-share-quality) +- [15. Depreciation adequacy and capitalisation policy](#15-depreciation-adequacy-and-capitalisation-policy) +- [16. Where this file does not apply](#16-where-this-file-does-not-apply) +- [17. Writing the earnings-quality verdict](#17-writing-the-earnings-quality-verdict) +- [Checklist](#checklist) + +--- + +## 1. The OPM trap — read this before computing any margin + +**Margin level is sector-bound and close to meaningless across sectors. Margin trend, and the reason behind the trend, is where the information lives.** + +A distributor at 4% operating margin and a software firm at 30% cannot be ranked against each other. The distributor turns its capital over ten times a year and may earn a 40% return on capital; the software firm may be spending three years of gross profit to acquire each customer and earn less. Margin is one input into return on capital (see `05-returns-and-dupont.md`) — it is never a standalone quality score, and a screen sorted on OPM descending is a list of industries, not a list of good businesses. + +What margin *does* tell you, and only in these forms: + +| Question | What to compare | What it means | +|---|---|---| +| Does this business have pricing power? | Its own gross margin across a full input-cost cycle | Stable/expanding GM through a raw-material spike is the clearest quantitative footprint of a moat | +| Is it winning or losing its position? | Its margin vs the sector median, tracked over 5–10 years | Converging toward peers = advantage eroding; diverging above = advantage compounding | +| Is management running it well? | GM trend vs OPM trend | GM flat but OPM falling is overhead bloat; GM falling but OPM held is cost-cutting masking a demand problem | +| Is the margin structural or cyclical? | Margin vs capacity utilisation, commodity spreads, currency | Peak-cycle margin extrapolated forever is the most common valuation error in cyclicals | + +**Two vocabulary traps that cause real errors:** + +- **India:** what Indian screeners and concalls call "OPM" is almost always **EBITDA margin** — operating profit *before* depreciation, and computed *excluding* other income. What a US analyst calls "operating margin" is **EBIT margin**, after depreciation. Comparing an Indian "OPM %" to a US "operating margin %" without adjusting for depreciation is an apples-to-oranges error of several hundred basis points. Always state which you mean. +- **India:** the Schedule III P&L format has **no gross profit line**. Construct it yourself: revenue from operations minus (cost of materials consumed + purchases of stock-in-trade + changes in inventories of FG/WIP/stock-in-trade). Decide explicitly whether to include power & fuel, freight and direct labour, and apply the same definition to every peer — otherwise the peer comparison is noise. +- **Both markets:** Ind-AS 116 / IFRS 16 moved operating-lease rent out of opex into depreciation and interest, inflating EBITDA margin with no economic change. Retailers, airlines, hotels and QSR are affected most. Never compare a post-adoption EBITDA margin to a pre-adoption one, or an IFRS lessee to a US GAAP operating-lease lessee, without adjusting. See `14-accounting-comparability.md`. + +--- + +## 2. Revenue growth decomposition + +Headline growth is an aggregate of drivers with completely different durability. Decompose it before you value it. + +**Decompose into:** organic volume · price/realisation · product and customer mix · currency translation · acquisitions and divestitures. + +Sources for the bridge: MD&A / Item 7 in the 10-K, the "revenue bridge" slide in the investor deck, constant-currency disclosures, and unit disclosures (tonnes, units, subscribers, room-nights, billable headcount, same-store/like-for-like). In India, the concall Q&A is often the only place volume-versus-realisation is split — management will give it if asked, and the transcript is a primary source. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Revenue CAGR (3/5/10y) | (End/Start)^(1/n) − 1, consolidated | Comfortably above nominal GDP + sector inflation | Below nominal GDP is real-terms shrinkage regardless of the reported "growth" | +| Organic growth % | Reported growth − acquired revenue contribution − FX | Should be the majority of total growth | Isolates the actual franchise from deal-making | +| Volume growth vs realisation growth | Units/tonnes/subs YoY vs revenue-per-unit YoY | Volume positive over a cycle | Price-led growth reverses when input costs fall; volume compounds | +| Same-store / like-for-like | Revenue from outlets/contracts open the full comparable period | Positive and above inflation | Strips out the store-opening treadmill in retail, QSR, hotels | +| Book-to-bill; backlog coverage | New orders ÷ revenue; backlog ÷ trailing revenue (months) | >1.0x; coverage stable or rising | Leading indicator for EPC, capital goods, IT services, defence | +| Constant-currency growth | Reported growth ex-translation | — | FX tailwinds are not performance | + +*Indicative ranges vary by market, cycle and period; the company's own history and the peer median override any absolute band.* + +**Why this matters:** two companies printing 15% growth can be opposite investments. Volume-led growth with stable price is demand. Price-led growth during an inflation spike is a loan from the next deflation. Roll-up growth resets the baseline every year and hides an organic business that may be shrinking — check what happens to the growth rate if M&A pauses, and pair this with the serial-acquirer accounting checks in `07-forensic-red-flags.md`. + +**Red flags:** growth entirely from price while volumes decline; growth that vanishes when acquisitions are stripped out; deceleration masked by serial M&A; revenue growing below inflation for years; growth carried by one large contract or one customer; recurring quarter-end revenue surges. + +**India note:** Q4 standalone/consolidated results are frequently a *balancing figure* — audited full-year minus the three limited-review quarters. Provisions, true-ups and rev-rec adjustments cluster there. Always compare Q4 margin and other income to the 9M run-rate; a Q4 that looks nothing like the rest of the year is telling you where the discretion was exercised. + +--- + +## 3. The margin ladder + +Walk every rung. Each level answers a different question, and the *differences between adjacent rungs* are where the information is. + +| Rung | What it isolates | What can be manipulated at this rung | +|---|---|---| +| **Gross margin** | Pricing power and cost position — the purest moat read | Cost reclassification into SG&A; capitalising production costs; inventory absorption games; channel stuffing | +| **EBITDA margin** | Cash-ish operating profitability before capital intensity | The most gamed metric of all: "adjusted" add-backs, lease accounting, SBC added back | +| **EBIT / operating margin** | True core profitability including the cost of the asset base | Understated depreciation; opex capitalised; "other operating income" of dubious nature parked above the line | +| **PBT margin** | After financing and associates | Interest capitalised into assets; associate income; forex reclassification | +| **PAT margin** | After tax and minorities | Tax holidays, deferred-tax reversals, minority-interest structure | +| **EPS** | After dilution and buybacks | Share-count engineering; SBC excluded from adjusted EPS | + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Gross margin % | Gross profit ÷ revenue (construct manually for Ind-AS filers) | Wholly sector-bound: ~15–25% distribution/EPC, ~25–40% auto components, ~50–70% branded consumer/pharma, ~70–90% software | Level says little; *stability through an input-cost cycle* says a lot | +| GM delta (bps YoY, 5y trend) | Change in GM in basis points | Trend flat-to-up | Multi-year erosion = commoditisation working its way down every line | +| Raw material % of sales | Cost of materials ÷ revenue | — | Sizes the input-cost exposure you are underwriting | +| EBITDA margin % | EBITDA ÷ revenue; state whether pre- or post-IFRS 16 | Sector-bound | Drives multiples and covenants — which is exactly why it is manipulated | +| Adjusted-vs-reported EBITDA gap | (Adj EBITDA − reported) ÷ reported | <5%, and shrinking | A persistent double-digit gap means the "clean" number overstates earning power | +| Add-backs as % of EBITDA | Sum of all adjustments ÷ EBITDA | <10% | Add-backs that appear every year are operating costs | +| EBIT margin % | EBIT ÷ revenue | Sector-bound | The cleanest measure of scalable core profitability | +| SG&A / R&D / employee cost as % of sales | Each line ÷ revenue, 5-year trend | Stable or falling with scale | Reveals whether growth is being bought or earned | + +*Indicative ranges vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**The diagnostic that matters most: compare the GM trend with the OPM trend.** +- GM stable, OPM falling → overhead bloat or negative operating leverage. Ask what SG&A is buying. +- GM falling, OPM stable → costs are being cut to protect the print. Check whether R&D, advertising or maintenance capex is being starved — margin held by mortgaging the future looks identical to margin held by efficiency for about three years. +- Both rising, revenue flat → suspicious. Cost capitalisation and reclassification produce exactly this signature. +- A sudden unexplained GM jump with no mix or input-price explanation is a forensic trigger, not a positive. + +**On EBITDA specifically:** it excludes capex, working capital and the real cost of stock compensation. Treat every add-back as a claim requiring evidence. Restructuring charges in five consecutive years are a cost of doing business. Reconcile adjusted EBITDA back to statutory operating profit *and* to operating cash flow; if adjusted EBITDA grows while cash flow does not, the adjustments are the growth. US filers must publish a Reg G / Item 10(e) reconciliation in the 10-K or 8-K Item 2.02 — read it, do not take the press-release headline. + +--- + +## 4. Operating leverage and the fixed/variable split + +Estimate the fixed/variable cost split and measure how earnings respond to revenue. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Degree of operating leverage | %Δ EBIT ÷ %Δ revenue, over several periods | 1.5–3x for most industrials; >4x is a cyclical warning | Sizes the downside, not just the upside | +| Incremental margin | Δ EBIT ÷ Δ revenue (YoY) | At or above current EBIT margin | Falling incremental margin means new revenue is worth less than old revenue | +| Decremental margin | Same, on a revenue decline | Below the incremental margin | Tells you what a 20% volume drop actually does to EBIT | +| Contribution margin % | (Revenue − variable costs) ÷ revenue | — | Needed to compute breakeven | +| Breakeven revenue | Fixed costs ÷ contribution margin % | Comfortably below trough-cycle revenue | If breakeven is creeping toward current sales, a mild downturn produces losses | +| Capacity utilisation | Volume ÷ rated capacity | — | Margin expansion at rising utilisation is *not* structural improvement | + +**Why it matters:** operating leverage determines earnings volatility and therefore the multiple the business deserves. Margin expansion driven purely by volume flowing over a fixed base will reverse just as fast on the way down. Before crediting management for a 300bps margin gain, decompose it: how much was utilisation, how much was input-cost deflation, how much was price, how much was genuine structural cost-out that survives a downturn. Then stress the EBIT at trough-cycle revenue — that number, not the current one, is what a cyclical should be valued on (`13-situations.md`). + +--- + +## 5. Below-the-line: the EBIT-to-PAT bridge + +Build the bridge explicitly and quantify every step: EBIT → finance costs → interest/other income → share of associates and JVs → exceptional items → tax → non-controlling interests → PAT attributable to owners. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| PBT margin % | PBT ÷ revenue | Sector-bound | Where financing structure shows up | +| PAT margin % | PAT attributable to owners ÷ revenue | Sector-bound | The bottom line equity holders actually own | +| PAT growth vs EBIT growth | 3–5 year CAGR of each | Should track within a few points | Persistent divergence means the profit engine is below the operating line | +| Interest coverage | EBIT ÷ finance cost | >4x general; >6x for cyclicals | Detail in `04-balance-sheet-and-cashflow.md` | +| Minority interest as % of PAT | NCI share ÷ consolidated PAT | — | High NCI means headline consolidated PAT overstates what owners get | +| Associate/JV share as % of PAT | Share of profit of associates ÷ PAT | Small, unless it is the business model | Associate income is non-cash until dividended up | + +**Why it matters:** net margin can rise for years while the operating business decays, on nothing but falling interest rates, a rising associate contribution, or a tax break. That growth is lower quality — management does not control it, it does not compound, and it should not earn the multiple that operating growth earns. + +**Red flags:** net margin rising while operating margin falls; profit growth attributable mainly to deleveraging or a falling tax rate; consolidated PAT flattered by a partly-owned subsidiary (check the "attributable to owners of the parent" line, not the consolidated total); interest capitalised into CWIP suppressing the finance-cost line while a project builds. **India:** always compare standalone and consolidated — where they diverge sharply, the subsidiaries and associates are the story. + +--- + +## 6. Other income reliance + +Disaggregate "other income" into recurring (interest on surplus cash, dividends from investments) and non-core/lumpy (asset-sale gains, treasury and mark-to-market gains, forex, government grants and export incentives, insurance recoveries, provision write-backs). + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Other income as % of PBT | Other income ÷ PBT | <10%; investigate above ~15–20% | Above that, a share of the "profit" is not the business | +| Recurring vs non-recurring split | From the other-income note in the accounts | Majority recurring | Disposal gains do not repeat | +| Treasury income vs core EBIT | Investment income ÷ EBIT | — | A large cash pile earning interest is not operating skill | +| Forex gain/loss as % of PBT | Net FX ÷ PBT | Small and two-directional over time | One-directional FX "gains" every year suggests policy, not luck | + +**Why it matters:** other income overstates sustainable earning power and is the easiest lever for hitting a target. Its collapse is also mechanical: interest income vanishes the moment the cash pile is deployed into capex or an acquisition, so a company valued on a P/E that includes treasury income gets re-rated downward the year it finally invests. + +**India note:** the Schedule III format gives "Other income" its own prominent line, and Indian screeners exclude it from operating profit by design — which is correct. Read the note behind the line; export incentives, PLI grants and forex are often material and are frequently reported as though they were operating. + +--- + +## 7. One-offs, exceptionals and the adjusted-earnings gap + +Catalogue every exceptional, special, restructuring, impairment, litigation-provision, write-off and disposal item for the last **5–7 years** in a single table. The table is the analysis — the pattern across years is what a single-year read cannot show. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Exceptional items as % of PBT | Absolute exceptional ÷ PBT, per year | Genuinely rare | Frequency, not size, is the tell | +| Frequency over 5–7 years | Count of years with an exceptional charge | ≤2 of 7 | Charges in 5 of 7 years are operating costs mislabelled | +| Cumulative restructuring/impairment | Sum over the period vs cumulative reported PAT | Small fraction | Shows how much "profit" was written back off | +| Adjusted vs statutory PAT gap | (Adj PAT − statutory) ÷ statutory | <10% and non-directional | A permanent one-way gap means the adjustments are the earnings | + +**Why it matters:** classification of an item as exceptional is discretionary, and the discretion runs one way. Only charges get excluded from "underlying" profit; one-off *gains* stay in. Normalised earnings built on that asymmetry are systematically overstated, and every multiple computed on them is systematically too low. + +**Red flags:** "non-recurring" charges in most years; asymmetric treatment of gains and losses; a big-bath write-off in the first year of a new CEO (resetting the base so future growth looks better); impairment of goodwill from a recent acquisition (a priced admission of overpayment — see `07-forensic-red-flags.md`); serial restructuring programmes each announced as the last one. + +**India note:** Ind-AS 1 discourages the label "extraordinary items", but Indian filers still present an "Exceptional items" line. Cross-check it against the CARO report, the Key Audit Matters, and the contingent-liabilities note — provisions created and later written back to profit are a classic cookie jar. + +--- + +## 8. Tax normalcy and sustainability + +Compare the effective tax rate to the statutory rate and read the rate reconciliation in the tax footnote. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Effective tax rate | Total tax expense ÷ PBT | Near statutory: India ~25.17% under the 115BAA concessional regime (22% + surcharge + cess); US ~21% federal + state | A rate far below statutory needs a durable, named reason | +| Statutory-to-effective gap | Reconciliation line items | Explained and stable | Unexplained gaps are the warning | +| Cash tax rate | Taxes actually paid (cash flow statement) ÷ PBT | Close to the book rate over 3–5 years | Book profit with negligible cash tax means the profit is not being recognised by the tax authority either | +| Deferred tax movement | Δ net DTA/DTL | Small relative to PAT | A large DTA recognition can single-handedly create a profitable year | +| Remaining life of incentives | From the tax note / MD&A | Known and modelled | Expiry creates a step-down in EPS with no operational change | + +**Why it matters:** an abnormally low tax rate inflates EPS in a way that does not persist. Tax holidays expire on a published date; when they do, PAT drops by the difference with no warning from the operating business. Model the post-expiry EPS before applying a multiple. + +**India-specific:** SEZ/Section 10AA benefits taper and sunset; the old 80-IA infrastructure deductions; MAT/AMT credits being drawn down; whether the company has opted into the 115BAA regime (which forfeits most incentives permanently). **US-specific:** GILTI/FDII, R&D credits, the Section 174 capitalisation rules that have widened the book-versus-cash tax gap for R&D-heavy filers since 2022, valuation allowances on deferred tax assets, and uncertain tax positions (FIN 48) disclosed in the footnote. + +**Red flag:** net profit growth where the largest single contributor is a falling tax rate. Strip it out and re-read the growth rate. + +--- + +## 9. Accruals versus cash — the single highest-yield test + +If you run only one earnings-quality test, run this one. Accrual-heavy earnings reliably revert. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Cash conversion | CFO ÷ net income, averaged over 3–5 years | >0.9x; >1.0x is strong | A single year is noise; a five-year average below 0.8x is a finding | +| FCF conversion | (CFO − capex) ÷ net profit | >0.6x for a maturing business | Profit that never becomes spendable cash is not profit yet | +| OCF ÷ EBITDA | Operating cash flow ÷ EBITDA | >0.7x | Isolates working-capital absorption | +| Sloan accrual ratio | (Net income − CFO) ÷ average total assets | <5%; >10% is a red flag | The classic academic predictor of earnings reversal | +| Balance-sheet accruals | Δ net operating assets ÷ average net operating assets | Low and non-trending | Catches accruals that route through investing, not just working capital | +| Receivables/inventory growth vs revenue growth | Each YoY growth rate | At or below revenue growth | Both growing faster than sales is the standard signature of pulled-forward revenue | + +*Indicative ranges vary by market, cycle and period; a growing company legitimately absorbs working capital — compare to its own history and to peers growing at the same rate.* + +**Why it matters:** the gap between accounting profit and cash generation is the most reliable early-warning signal available from public filings, and it is early — it typically widens for several periods before the reported numbers break. Note that the direction of the test is asymmetric: cash below profit is a warning; cash *above* profit is usually a good sign (negative working capital, deferred revenue growth) but check it is not just underinvestment or a one-time payables stretch. + +Depth on working-capital mechanics and the cash flow statement sits in `04-balance-sheet-and-cashflow.md`; the fraud-detection framing (Beneish-style ratios, channel stuffing) sits in `07-forensic-red-flags.md`. + +--- + +## 10. Revenue recognition aggressiveness + +Read the revenue-recognition accounting policy and the critical-estimates note. You are looking for how much judgement sits between a customer's order and a revenue line. + +**What to examine:** +- **Timing:** point-in-time vs over-time; percentage-of-completion vs milestone (dominant in EPC, infrastructure, defence, and long-cycle IT contracts, and the single most judgement-laden method in common use). +- **Gross vs net (principal vs agent):** whether a marketplace books GMV or commission. Gross-basis reporting can overstate apparent scale by an order of magnitude and makes every margin ratio incomparable to a net-basis peer. +- **Multi-element arrangements:** how a bundle of hardware, licence and support is allocated across performance obligations, and how much revenue is pulled to day one. +- **Bill-and-hold, channel financing, distributor sell-in vs sell-through:** revenue recognised into a channel is not demand. +- **Returns, rebates, discounts and warranty provisioning:** under-provisioning inflates current revenue and margin. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| DSO | (Receivables ÷ revenue) × 365 | Stable vs own history and peers | Rising DSO with rising revenue is the classic pulled-forward-revenue signature | +| Contract assets / unbilled receivables growth | YoY growth vs revenue growth | At or below revenue growth | Revenue recognised ahead of the right to bill is the softest revenue there is | +| Deferred revenue / contract liabilities | YoY trend vs revenue | Growing with revenue for subscription models | Falling deferred revenue while revenue grows = the backlog is being consumed, not replenished | +| Provision for returns/rebates as % of sales | From the provisions note | Stable | A quietly shrinking provision rate is a margin lever, not an improvement | + +**Red flags:** contract assets compounding well ahead of revenue; DSO up several quarters in a row; a rev-rec policy change that happens to lift growth; quarter-end revenue spikes (especially the Indian Q4 balancing quarter); gross-basis presentation adopted without a principal-role justification; revenue growth concentrated in the least-verifiable geography or the newest business line. + +**Standards:** Ind-AS 115 and IFRS 15 and ASC 606 are converged in substance, so the five-step model and the disaggregation disclosures are comparable across markets — use the disaggregation table, it is one of the most useful and least-read disclosures in any filing. + +--- + +## 11. Vendor and customer financing — demand bought with your own balance sheet + +Determine whether the company is funding its own customers' purchases: captive finance arms, seller notes, unusually long or extended credit to distributors, channel financing arrangements, guarantees of customer or dealer debt, buy-back or residual-value commitments, and vendor loans on equipment sales. + +**Where to look:** notes receivable and long-dated/non-current receivables; the related-party and contingent-liability notes; guarantees given; the financing subsidiary's own accounts; and the gap between revenue growth and cash collections. In India, CARO reporting on loans and guarantees, and the Ind-AS 24 related-party note, are the practical route. + +**Why it matters:** revenue funded by the seller's own credit is not demand — it is a loan that has been booked as a sale. It reads as clean organic growth until the receivables sour, and then it reverses violently, taking both the revenue and the balance sheet down at once. This mechanism has repeatedly destroyed telecom-equipment, solar, EV and capital-goods names historically; the pattern is always the same and always visible in the receivable maturities before it is visible in the P&L. + +**What to compute:** customer financing exposure (on- and off-balance-sheet) as a % of annual revenue; the share of revenue growth attributable to financed sales; and the receivable ageing profile. If a material share of growth is vendor-financed, treat that revenue as lower quality and treat the company as partly a lender — which means the sector playbooks for lenders (`sectors/nbfc.md`) have relevant tests even for an industrial. + +--- + +## 12. Per-employee productivity cross-check + +Compute revenue per employee and gross profit per employee versus peers and over 5+ years, alongside headcount growth versus revenue growth. + +**Why it matters:** headcount is one of the few operating inputs that is hard to fabricate and is often disclosed independently of the financials (annual report, LinkedIn-scale disclosures, ESG/BRSR reports, regulatory filings). It provides an external sanity check on claimed scale. Deteriorating revenue per employee while a growth story is being told, or a hiring freeze that contradicts guidance, is an early and independent tell. + +**Read it sector-appropriately.** In IT services, revenue per employee combined with utilisation and offshore mix is a core margin driver, not merely a check. In manufacturing it tracks automation and mix. In software and platforms it should rise steeply with scale — if it does not, the business is not actually scaling. **India note:** employee benefit expense is a separate Schedule III line and headcount is disclosed in the Board's Report and BRSR, so this cross-check is usually computable for NSE/BSE names. + +--- + +## 13. Segment profitability and mix + +Break the consolidated result into reportable segments and geographies: revenue mix, segment EBIT and margin, growth rate, capital employed, and the size of unallocated corporate costs. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Segment revenue mix % | Segment revenue ÷ total | — | Shows where the business actually is | +| Segment EBIT margin and 5y trend | From the segment note | — | The consolidated margin is a weighted average hiding both good and bad | +| % of profit from the top segment | Largest segment EBIT ÷ total segment EBIT | <60% for a diversified claim | Concentration in one segment means you are underwriting one business, not a portfolio | +| Unallocated / corporate cost as % of EBIT | From the reconciliation | Small and stable | Rising unallocated costs is where inconvenient items go | +| Segment ROCE | Segment EBIT ÷ segment capital employed (where disclosed) | — | The only way to see if a segment earns its capital | + +**Why it matters:** consolidated numbers blend divergent economics and disguise cross-subsidy. A profitable core funding a chronic loss-maker destroys value even while consolidated profit grows, and mix shift toward lower-return segments lowers the multiple the whole company deserves even when EPS is rising. Segment disclosure is also where you find whether the growth story and the profit source are the same business — frequently they are not. + +**Red flags:** frequent redefinition of segments (a common way to bury a deteriorating unit); aggregation into a single "others" bucket; segment results presented without capital employed; rising unallocated costs. + +**Conventions:** Ind-AS 108 and ASC 280 both use the management approach, so segments follow internal reporting and are *not* comparable across companies — build the peer comparison at the metric level, not the segment-label level. US filers now disclose significant segment expenses under ASU 2023-07, which materially improves this analysis for 10-K filers. Indian companies disclose segment revenue, results, assets and liabilities quarterly — use the quarterly segment series, it is the highest-frequency view of mix available. + +--- + +## 14. Share-based comp, dilution and per-share quality + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| SBC as % of revenue | SBC expense ÷ revenue | <5%; >10% is severe | A real cost of labour paid in shares | +| SBC as % of operating cash flow | SBC ÷ CFO | <20% | SBC is added back in the cash flow statement — CFO is flattered by exactly this amount | +| Diluted share count growth | YoY change in weighted diluted shares | ≤1–2% p.a. | Steady dilution is a quiet transfer of value away from you | +| Diluted EPS CAGR vs net income CAGR | Both over 5 years | EPS ≥ NI growth | EPS lagging net income means dilution is eating the growth | +| Buyback contribution to EPS growth | EPS growth − net income growth | Should be a minority of EPS growth | Separates operating performance from financial engineering | +| Net buyback vs issuance | Shares retired − shares issued | Genuinely negative | Buybacks that only mop up option issuance are compensation, not capital return | + +**Why it matters:** SBC is a real economic cost that is routinely added back to "adjusted" earnings and EBITDA, and it is added back in the cash flow statement by construction — so a company with heavy SBC shows flattering margins *and* flattering operating cash flow simultaneously. Meanwhile EPS can rise for years on debt-funded buybacks while revenue and EBIT go nowhere. Always decompose EPS growth into operating growth, margin, and share count before crediting management with anything. + +**Conventions:** dilution must be computed on the diluted count under the treasury-stock method, plus any convertible instruments under the if-converted approach (ASU 2020-06 for US filers). **India:** ESOP charges appear within employee benefit expense; the scheme details, outstanding options and exercise prices sit in the Board's Report / ESOP disclosure under the SEBI SBEB Regulations. Indian SBC is generally far smaller than US tech levels — do not import a US benchmark. Also check warrants issued to promoters and preferential allotments, which dilute outside any ESOP scheme. + +--- + +## 15. Depreciation adequacy and capitalisation policy + +Understated depreciation and aggressive capitalisation are the two quietest ways to inflate current profit, because both defer a real cost rather than eliminating it. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| D&A as % of sales | D&A ÷ revenue, 5-year trend | Stable; sector-bound | A falling ratio with a growing asset base needs an explanation | +| D&A ÷ capex | 5-year averages of both | ~0.8–1.2x for a steady-state business | D&A persistently far below capex means depreciation is not reflecting replacement needs | +| Implied depreciation rate | Depreciation ÷ average gross block | Consistent with disclosed useful lives | Falling implied rate = lives lengthened or asset mix shifted | +| Capitalised development/software as % of relevant spend | From the intangibles note and cash flow statement | Low vs peers who expense | If peers expense what this company capitalises, the margins are not comparable | +| Amortisation of acquired intangibles | From the intangibles note | — | Serial acquirers "adjust it out" while continuing to buy the intangibles | + +**Why it matters:** capitalising a cost moves it from this year's P&L to the next several years' depreciation line. Profit rises now, and the business looks more asset-light and more profitable than it is. The comparison that exposes it is against peers: within the same sector, if one company capitalises development costs and product engineering while the others expense them, the margin gap is an accounting choice, not a performance gap. Normalise before you compare (`14-accounting-comparability.md`). + +**Red flags:** useful lives extended in a year when earnings needed help; a change in depreciation method; capitalised development or software rising faster than revenue; capitalised interest large relative to PBT; a low depreciation charge against a large gross block; subscriber-acquisition or contract-acquisition costs capitalised. + +**Conventions:** **India** — Schedule II of the Companies Act 2013 prescribes indicative useful lives; a company using longer lives must disclose technical justification, so a deviation is both visible and meaningful. Also check the componentisation approach and the treatment of CWIP (long-standing CWIP with capitalised interest is a classic profit-deferral and impairment risk). **US/IFRS** — IFRS/Ind-AS requires capitalising development costs meeting the IAS 38 criteria while US GAAP largely expenses R&D (with narrow software exceptions), which is a structural, not discretionary, difference between an IFRS and a US GAAP peer. Adjust for it explicitly rather than treating it as a quality difference. + +--- + +## 16. Where this file does not apply + +The governing principle bites hardest here. For several sectors the standard income-statement ladder is undefined or inverted, and applying it produces confident nonsense: + +- **Banks and NBFCs** — there is no revenue, COGS or gross margin. The equivalents are net interest income, NIM, fee income, cost-to-income, credit cost and provision coverage. Interest expense is a cost of goods, not a financing item. Go to `sectors/banks.md` / `sectors/nbfc.md`. +- **Insurers** — premium is not revenue in the ordinary sense; the profit signal is the combined ratio (general/health) or VNB margin and embedded-value movement (life). `sectors/insurance.md`. +- **REITs / InvITs** — net income is meaningless because depreciation on appreciating property overwhelms it; use FFO/AFFO and NDCF. `sectors/realestate-reit.md`. +- **Miners and commodity producers** — margin is a price artefact. Use cost-curve position (C1/AISC), reserve life and mid-cycle realisations. `sectors/metals-mining.md`. +- **Loss-making growth companies** — the margin ladder still applies but the level is uninformative; work on gross margin, contribution margin after customer-acquisition cost, cohort economics and the path to breakeven. `13-situations.md`. + +--- + +## 17. Writing the earnings-quality verdict + +Do not present this as fifteen paragraphs of findings. Compress to a judgement the reader can act on: + +1. **Quality of the growth** — how much of the last three years' revenue growth was volume, price, mix, FX and M&A, in numbers. +2. **Quality of the margin** — direction over 5–10 years, the reason for the direction, and whether it is structural or cyclical. State the peer median so the level is anchored, and say explicitly that the level alone is not the finding. +3. **Quality of the profit** — how much of PAT is operating, and what the multi-year cash conversion is. +4. **The adjustment gap** — statutory PAT versus the company's own adjusted number, and whether the gap is one-directional. +5. **The three things that would change this verdict** — specific, observable, checkable next quarter. + +Then carry the *normalised* earnings figure forward into valuation, not the reported one, and state every normalisation you made. + +--- + +## Checklist + +- [ ] Stated whether "OPM" here means EBITDA margin (Indian convention) or EBIT margin (US convention). +- [ ] Constructed gross margin manually for Ind-AS filers and used the identical definition for every peer. +- [ ] Decomposed 3-year revenue growth into volume, price/mix, FX and M&A, with a source for each. +- [ ] Compared revenue growth to nominal GDP + sector inflation, and to industry volume growth. +- [ ] Checked same-store/like-for-like and book-to-bill or backlog coverage where the sector has them. +- [ ] Plotted the full margin ladder for 5–10 years; compared the GM trend against the OPM trend and explained any divergence. +- [ ] Checked lease-accounting (IFRS 16 / Ind-AS 116) comparability before comparing EBITDA margins. +- [ ] Listed every add-back to adjusted EBITDA/EPS and tested whether each recurs across 5+ years. +- [ ] Estimated degree of operating leverage and incremental margin; stress-tested EBIT at trough revenue. +- [ ] Built the EBIT→PAT bridge; quantified interest, associates, minorities and tax separately. +- [ ] Split other income into recurring and non-recurring; flagged if it exceeds ~15% of PBT. +- [ ] Tabulated exceptional items for 5–7 years; checked for asymmetric treatment of gains vs losses. +- [ ] Compared ETR to statutory, and cash tax to book tax; noted expiry dates of any tax incentives. +- [ ] Computed 3–5 year average CFO/net income, FCF/PAT and the Sloan accrual ratio. +- [ ] Compared receivables, inventory and contract-asset growth to revenue growth. +- [ ] Read the revenue-recognition policy; checked gross vs net, POC judgement, DSO trend and quarter-end spikes. +- [ ] Checked for vendor/customer financing, guarantees and long-dated receivables funding reported demand. +- [ ] Cross-checked revenue and gross profit per employee against peers and own 5-year history. +- [ ] Analysed segment margins, mix shift, unallocated costs and any segment redefinition. +- [ ] Measured SBC as % of revenue and of CFO; decomposed EPS growth into operating growth vs share count. +- [ ] Tested depreciation adequacy (D&A vs capex, implied rate vs gross block) and capitalisation policy vs peers. +- [ ] Confirmed consolidated vs standalone basis, currency and units on every figure used (India: crore/lakh). +- [ ] Confirmed the sector actually admits these metrics; switched to the sector playbook if it does not. +- [ ] Carried a normalised earnings figure into valuation and disclosed every normalisation made. diff --git a/finance/skills/stock-analysis/references/04-balance-sheet-and-cashflow.md b/finance/skills/stock-analysis/references/04-balance-sheet-and-cashflow.md new file mode 100644 index 00000000..e714b04f --- /dev/null +++ b/finance/skills/stock-analysis/references/04-balance-sheet-and-cashflow.md @@ -0,0 +1,478 @@ +# Balance Sheet Strength, Solvency and Cash Generation + +Use this when: you are at Stage 4 and need to establish whether the company can survive what it owes, and whether the profit you validated upstream turns into cash the owners actually keep. + +The income statement is an opinion assembled from estimates. The balance sheet tells you who has a prior claim on the business and in what order; the cash flow statement tells you whether the profit was ever real. Almost all permanent capital loss in equities traces to one of two failures — debt that could not be refinanced, or earnings that never became cash — and both are visible in these two statements long before the price reacts. Treat this file as one question in two halves: *what does it owe, and what does it generate to pay with?* As everywhere in this skill, no ratio below means anything until you have placed it against the sector norm and the company's own five-to-ten-year record. + +## Contents + +- [0. Sector gate — where this toolkit is undefined or inverted](#0-sector-gate--where-this-toolkit-is-undefined-or-inverted) +- [1. Build the economic debt figure before computing any ratio](#1-build-the-economic-debt-figure-before-computing-any-ratio) +- [2. Prove the cash is real](#2-prove-the-cash-is-real) +- [3. Leverage and capital structure](#3-leverage-and-capital-structure) +- [4. Maturity profile and refinancing risk](#4-maturity-profile-and-refinancing-risk) +- [5. Coverage: can it service what it owes](#5-coverage-can-it-service-what-it-owes) +- [6. Covenants and headroom](#6-covenants-and-headroom) +- [7. Liquidity ratios, facilities and runway](#7-liquidity-ratios-facilities-and-runway) +- [8. Working capital and the cash conversion cycle](#8-working-capital-and-the-cash-conversion-cycle) +- [9. Receivables and inventory quality](#9-receivables-and-inventory-quality) +- [10. Off-balance-sheet, contingent and quasi-debt obligations](#10-off-balance-sheet-contingent-and-quasi-debt-obligations) +- [11. Toxic and structured financing, chronic dilution](#11-toxic-and-structured-financing-chronic-dilution) +- [12. Goodwill, tangible book and asset productivity](#12-goodwill-tangible-book-and-asset-productivity) +- [13. Direction of travel, distress scores and credit-market signals](#13-direction-of-travel-distress-scores-and-credit-market-signals) +- [14. Does profit become cash? Accrual quality](#14-does-profit-become-cash-accrual-quality) +- [15. Free cash flow: define it before you use it](#15-free-cash-flow-define-it-before-you-use-it) +- [16. Maintenance versus growth capex](#16-maintenance-versus-growth-capex) +- [17. SBC and the FCF shareholders actually keep](#17-sbc-and-the-fcf-shareholders-actually-keep) +- [18. Sources and uses: who funded the growth, were the payouts earned](#18-sources-and-uses-who-funded-the-growth-were-the-payouts-earned) +- [19. Classification games and off-statement financing](#19-classification-games-and-off-statement-financing) +- [20. Cash taxes versus book taxes](#20-cash-taxes-versus-book-taxes) +- [21. Full-cycle durability and cash return on capital](#21-full-cycle-durability-and-cash-return-on-capital) +- [22. India versus US: conventions that break comparability](#22-india-versus-us-conventions-that-break-comparability) +- [Checklist](#checklist) + +**Every range printed below is indicative only.** Bands shift with sector, market, rate cycle, accounting regime and period. Net debt/EBITDA of 3x is prudent for a contracted utility and reckless for a mid-cap capital-goods firm with a 200-day cash cycle. Peer comparison and the company's own history override any absolute band here. When you cite a band in output, cite it as a reference point and immediately state what the peer set actually does. + +--- + +## 0. Sector gate — where this toolkit is undefined or inverted + +Run this gate first. For several sectors the standard ratios below are not merely different, they are meaningless, and computing them produces confidently wrong conclusions. + +| Sector | What breaks | Use instead | +|---|---|---| +| Banks (NSE/BSE and US) | Debt is raw material, not risk. Debt/equity of 8–12x is normal. Current ratio, CCC, working capital and FCF are undefined — deposits are funding, loans are assets | CET1 / CRAR, GNPA and NNPA, provision coverage, slippage and credit cost, CASA mix, LCR/NSFR, ALM bucket gaps, restructured book | +| NBFCs / HFCs (India) | Same as banks plus acute asset-liability risk; leverage *is* the business model | Tier-1 and CRAR, ALM mismatch in the ≤1-year bucket, borrowing mix (bank lines vs CP vs NCD vs securitisation), incremental cost of funds, Stage-3 assets, liquidity buffer | +| Insurers | No revenue-driven working capital; float is a liability that funds the asset book | Solvency ratio (IRDAI floor 1.5x), VNB and VNB margin, embedded value, persistency, combined ratio (general), reserve adequacy | +| REITs / InvITs / real-estate developers | High leverage is structural; depreciation is non-economic so EPS and FCF mislead; developer inventory is land and WIP, so DIO in the hundreds or thousands of days is by design | LTV against asset value (SEBI caps REIT/InvIT leverage), FFO and AFFO in place of FCF, WALE, interest cover; for developers net debt vs pre-sales collections and collections vs completion | +| Miners, E&P, heavy capex build-outs | FCF is negative by design during a build; net debt/EBITDA measured at a commodity peak understates leverage by a wide margin | Leverage at a mid-cycle price deck, reserve life and replacement, committed vs discretionary capex, cost-curve position, coverage at trough prices | +| Regulated utilities | High leverage is permitted and priced by the regulator | FFO/net debt, regulated asset base and allowed return, tariff and true-up mechanics, ring-fencing at the opco | +| Airlines, shipping, retail chains | Lease-adjusted debt dominates reported debt; negative working capital is a feature, not a warning | Lease-adjusted net debt/EBITDAR, fixed-charge cover, months of liquidity, fleet/vessel age, off-balance commitments | + +If the company sits in one of these, stop, open the matching file in `references/sectors/`, and use this file only for the parts that survive: cash quality, contingent liabilities, related-party exposure, promoter pledge, distress signals. + +--- + +## 1. Build the economic debt figure before computing any ratio + +Headline "borrowings" understates what the company owes at almost every leveraged company. Compute an **adjusted net debt** first, then feed *that* into every leverage and coverage ratio below. Show the bridge in your output so a reader can disagree with one line rather than with the conclusion. + +Start with gross borrowings (short-term + long-term + current maturities of long-term debt) and add: + +- **Lease liabilities** (Ind-AS 116 / IFRS 16 / ASC 842). On balance sheet for lessees post-adoption, but confirm they are inside your debt figure and that EBITDA is on the same basis. US GAAP operating leases sit on the balance sheet yet keep rent inside operating expense, so an IFRS/Ind-AS retailer shows structurally higher EBITDA than a US GAAP peer with identical economics. See `14-accounting-comparability.md`. +- **Net pension / post-retirement deficit** (projected benefit obligation minus plan assets, plus OPEB). A senior, non-negotiable claim ranking ahead of equity. +- **India — gratuity and leave encashment (Ind-AS 19).** Frequently *unfunded*, or only partly funded through an LIC group policy. Read the employee-benefits note for the defined-benefit obligation, fair value of plan assets, funded status, discount rate (usually pegged to the G-sec curve), and the salary-escalation and attrition assumptions. An unfunded gratuity obligation in a labour-heavy business is real debt with no offsetting asset, and it grows with the wage bill. +- **Reverse factoring / supply-chain finance / channel financing** balances sitting inside trade payables. This is bank debt wearing a payables costume: reclassify it to debt and reverse the corresponding CFO benefit. US filers must disclose supplier-finance programme obligations and a rollforward (ASU 2022-04); IFRS and Ind-AS filers disclose carrying amounts and terms under the IAS 7 / IFRS 7 amendments. If the programme exists and the disclosure is thin, that is itself a finding. +- **Securitised or factored receivables sold with recourse.** Off the balance sheet, still your credit risk. India: "bills discounted with recourse" is normally disclosed under contingent liabilities rather than debt. +- **Financial guarantees given** — to subsidiaries, JVs, associates, and in India critically to promoter-group entities. Probability-weight them, but never at zero: a guarantee to a weaker group company is a call option written against your equity. +- **Written puts over minority interests (NCI puts).** Common in Indian group structures and in partially acquired subsidiaries — the parent has contracted to buy out a minority at a formula price or on a fixed date. It is a dated cash obligation with debt-like seniority, often disclosed only in the financial-instruments note. +- **Preference shares, perpetual and hybrid instruments, compulsorily convertible instruments, PIK and toggle notes.** Classify by economics, not label: anything with mandatory redemption or a cash coupon that cannot be deferred without consequence is debt. PIK and toggle notes flatter coverage while compounding principal. +- **Customer advances and deferred revenue are *not* debt** — they are interest-free funding and a sign of strength — but note them separately so the reader sees why net debt is low. + +Then subtract cash, but only cash genuinely available. Deduct restricted cash, margin money and deposits pledged against letters of credit or guarantees, cash trapped in subsidiaries that cannot upstream it (minority-held or capital-controlled), and cash at consolidated entities the parent cannot reach. **Do not net cash you have not proved (§2).** + +Finally, note **structural subordination**: where does the debt sit? A thin listed holdco servicing debt out of dividends from operating subsidiaries that have their own lenders is far riskier than the consolidated ratio implies. This applies to Indian promoter holdcos and US parent/opco structures alike — see `references/sectors/holdco-assetmgr.md`. + +--- + +## 2. Prove the cash is real + +Every leverage ratio that nets cash is only as good as the cash. This is the highest-severity test in the file, because fake or encumbered cash is the defining feature of the largest accounting frauds of the last three decades — and the standard ratio toolkit quietly assumes the cash line is true. + +Run the **interest-income reconciliation**: implied yield = interest and investment income ÷ average cash and short-term investments. Compare it against prevailing deposit and money-market rates for that currency and period (India: bank FD and liquid-fund yields; US: T-bill and money-market yields). A large cash pile earning implausibly little is cash that is fake, pledged, restricted, parked non-interest-bearing at a related-party bank, or simply not there. + +Then ask the structural questions: + +- **Why does it carry large gross cash and large gross debt at the same time?** There are legitimate answers — regulatory requirements, working-capital seasonality, prefunding a maturity, jurisdictional trapping. There is also one very common illegitimate answer. Make management's explanation explicit and test it against the arithmetic: if the company pays 9% on debt while earning 3% on cash, the negative carry must appear in the P&L and must be justified by something. +- **Where is it held?** Small, obscure, offshore or related-party banks are a flag; so is concentration in a single unrated institution. +- **Is it pledged?** India: check CARO, the margin-money and "deposits with maturity over 12 months" split in the cash note, and charges filed with the MCA/ROC. US: the debt footnote and the restricted-cash reconciliation required under ASU 2016-18. +- **India-specific corroboration.** CARO 2020 requires the auditor to report on short-term funds applied to long-term purposes, loans and advances to related parties, whether the company is a declared wilful defaulter, and diversion of funds. It is the cheapest forensic evidence available on an Indian filer. Also check rating actions — a CRISIL/ICRA/CARE rating moved to "Issuer Not Cooperating" is a serious signal, as is any SEBI-mandated disclosure of default to the exchanges. +- **US-specific corroboration.** Item 9A internal-control conclusions and any disclosed material weakness in treasury or cash; auditor changes and dismissals (8-K Item 4.01); going-concern language under ASC 205-40. + +If the cash cannot be corroborated, run every ratio on **gross** debt as well as net, and lead with the gross figure. State that you did and why. + +--- + +## 3. Leverage and capital structure + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Net debt / EBITDA | Adjusted net debt (§1) ÷ trailing EBITDA; use mid-cycle EBITDA for cyclicals | <2x comfortable; 2–3x manageable; >4–5x stretched outside utilities, REITs and infra | The single most-watched gauge by lenders and rating agencies; it sets refinancing terms | +| Gross debt / EBITDA | Same, without netting cash | Within ~0.5–1x of net for a normally financed firm | Exposes leverage masked by cash that is restricted, trapped or unproven | +| Debt / equity | Adjusted debt ÷ shareholders' funds (India: net worth — watch revaluation reserves) | 0–1x for most non-financials; sector-bound | Shows how much of the asset base creditors funded; the classic Indian screening ratio | +| Debt / total capital | Debt ÷ (debt + equity) | <50% typical for non-financials | Less distorted than D/E when equity is small, negative or buyback-depleted | +| Net debt / (EBITDA − capex) | Uses the cash left after sustaining spend | Materially higher than net debt/EBITDA in capital-heavy names | Capital-intensive firms cannot service debt out of EBITDA they are obliged to reinvest | +| Net debt / FCF (years) | Adjusted net debt ÷ FCF | <4–5 years comfortable for a stable business | Answers "how long to repay out of real cash" without EBITDA's fictions | +| Tangible net worth test | Equity − goodwill − intangibles | Positive | Negative tangible net worth, whether from goodwill or buybacks, can trip net-worth covenants | + +**How to read it.** Leverage magnifies both outcomes: a moderately geared firm survives a downturn, an over-geared one is forced into distressed asset sales, dilutive rescue equity or restructuring exactly when conditions are worst. Two refinements change conclusions more often than the level does. First, compute leverage on **mid-cycle** EBITDA for anything cyclical — leverage measured at a commodity, property or freight-rate peak is a trap. Second, ask *why* leverage moved: debt raised to fund capacity that will earn a return is a different signal from debt raised to fund buybacks, dividends or acquisitions, even at an identical ratio. + +**Red flags:** net debt/EBITDA rising while EBITDA is flat or falling; D/E far above the peer set with no structural reason; leverage that only looks acceptable after netting unproven cash; management quoting leverage on credit-agreement "adjusted EBITDA" rather than reported EBITDA. + +--- + +## 4. Maturity profile and refinancing risk + +A solvent company can still fail if it cannot refinance. This is a *timing* risk independent of profitability, and it is where otherwise healthy businesses die. + +Pull the maturity ladder. **US:** the long-term debt footnote and the credit agreements filed as exhibits — the old contractual-obligations table was dropped from Item 7, so do not look for it there. **India:** the borrowings note, the repayment-terms schedule, and the Ind-AS 107 liquidity-risk maturity table in the financial-instruments note. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Near-term maturity cover | (Cash + undrawn committed facilities + 12m projected FCF) ÷ debt due within 12–24 months | >1.5x | Below 1x the company must access markets to survive, on the market's terms | +| Short-term debt share | (Current borrowings + current maturities) ÷ total debt | <25–30% for a non-financial | Short-dated funding of long-dated assets is the classic liability mismatch | +| Weighted-average maturity | Σ(principal × years to maturity) ÷ total principal | >3–4 years for an investment-grade-type profile | Longer tenor buys time through a closed funding window | +| Maturity-wall test | Largest single-year maturity ÷ annual FCF | <2–3x | Identifies the specific year that decides the equity | +| CP / revolver dependence | Commercial paper + revolver drawings ÷ total debt | Low and stable | CP markets shut fastest and with no warning; rollover is not a right | +| Refinancing gap | Weighted-average existing coupon vs current new-issue yield for that rating and tenor | Small | A wide gap is an interest-cost step-up that today's P&L does not show | + +**Structure matters as much as size.** Split the book by fixed vs floating (and how much floating is hedged), by currency (is FX debt matched by FX revenue or a natural hedge, or would a currency move be a solvency event?), and by secured vs unsecured/subordinated (how much of the asset base is already pledged — if most assets are encumbered there is no collateral left to raise against, and unsecured creditors and equity are structurally subordinated). India: check the charge register, promoter guarantees on company debt, and short-tenor FX exposure via buyer's credit and packing credit. + +**Red flags:** a maturity wall inside 12–24 months exceeding available liquidity; continuous CP rollover funding long-life assets; unhedged floating exposure into a tightening cycle; FX debt at a business with no FX revenue; an average coupon far below current market. + +--- + +## 5. Coverage: can it service what it owes + +Leverage sizes the obligation; coverage tells you whether the business generates enough to carry it. Compute both earnings-based and cash-based coverage — the gap between them is itself the finding. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Interest coverage (TIE) | EBIT ÷ interest expense | >4x comfortable; 2–3x fragile; <1.5x distressed | The standard first screen; below ~2x a modest earnings dip breaches covenants | +| EBITDA / interest | EBITDA ÷ interest expense | >4–6x | Useful for capital-heavy firms, but ignores the capex they are obliged to fund | +| (EBITDA − capex) / interest | Strips sustaining investment before testing coverage | >2x | The honest version for asset-heavy businesses | +| Cash interest coverage | CFO before interest ÷ cash interest paid | >3x | Cash pays interest; accounting EBIT does not | +| Fixed-charge coverage | (EBIT + lease expense) ÷ (interest + lease expense + preference dividends) | >1.5–2x | The only fair measure where leases and preferreds are large — retail, airlines, shipping | +| DSCR | (CFO − capex) ÷ (interest + mandatory principal amortisation) | >1.2–1.5x | What project lenders and Indian banks actually test; India: Schedule III requires DSCR in the ratios note | +| FCF / total debt | FCF ÷ adjusted gross debt | >15–20% is strong | The deleveraging speed the equity story is implicitly relying on | + +**Always stress-test.** Recompute coverage under (a) a 20–30% fall in CFO and (b) the floating book repricing to current market plus the refinancing gap from §4. Coverage that survives only in a peak year is not coverage. Watch for capitalised interest flattering reported interest expense, and for covenants written on an adjusted EBITDA that bears little relation to cash. + +--- + +## 6. Covenants and headroom + +Covenants are the tripwires between distress and default. A company can be paying every bill on time and still lose control of its own restructuring. + +Where to read them. **US:** credit agreements and indentures filed as exhibits on EDGAR; amendments and waivers appear as 8-K Item 1.01, acceleration as Item 2.04. EDGAR full-text search for phrases like "Consolidated Leverage Ratio" or "Fixed Charge Coverage Ratio" inside the filer's exhibits works well. **India:** the borrowings note and terms-and-conditions disclosure, the sanction terms summarised in the annual report, any disclosure of breach or waiver, and the mandatory disclosure of payment default to the exchanges. + +What to compute and watch: + +- **Headroom %** on each maintenance covenant: (limit − current metric) ÷ limit, plus the EBITDA decline that would breach it. Headroom under ~15–20%, or an EBITDA cushion under ~20%, means one weak quarter hands the keys to lenders. +- **Which EBITDA definition the covenant uses.** Credit-agreement EBITDA typically permits add-backs — run-rate synergies, "exceptional" items, pro-forma acquisition contributions — that reported EBITDA does not. Comfortable covenant headroom alongside poor reported cash conversion tells you the covenant is not binding on reality. +- **Springing covenants** that apply only above a revolver-utilisation threshold. They bite precisely when the revolver is being drawn, i.e. in stress. +- **Cross-default and cross-acceleration chains**, change-of-control puts, material-adverse-change clauses, and rating-linked triggers (coupon step-ups, collateral posting). +- **Waiver and amendment history.** Repeated waivers are not a technicality — they are a disclosed loss of negotiating position, and they usually arrive with higher pricing, new security, and restrictions on dividends and capex. +- **Covenant-lite is not safety.** It removes the early warning and defers the reckoning to the maturity wall. + +--- + +## 7. Liquidity ratios, facilities and runway + +Ratios are a screen; **absolute accessible liquidity** decides whether a shock is survived. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Current ratio | Current assets ÷ current liabilities | >1.2–1.5 for industrials; retailers and QSR legitimately run below 1 | First-order near-term payment risk; India: Schedule III requires disclosure with an explanation of any >25% YoY change | +| Quick (acid-test) ratio | (Current assets − inventory − prepaids) ÷ current liabilities | ~1 | Strips the least liquid and most over-stated current asset | +| Cash ratio | (Cash + marketable securities) ÷ current liabilities | 0.2–0.5 typical, sector-bound | The worst-case view; immune to receivable and inventory optimism | +| Total available liquidity | Unrestricted cash + undrawn **committed** facilities | ≥12 months of fixed obligations plus committed capex | Absolute rupees or dollars, not ratios, determine survival | +| Revolver utilisation | Drawn ÷ total facility | Low; a fully drawn revolver means the backstop is spent | Heavy drawing is a late-stage distress signal | +| Cash runway (loss-makers) | Unrestricted cash ÷ average quarterly burn | >18–24 months, or a fully funded plan | Runway dictates the timing and price of the next dilution | +| Defensive interval | Liquid assets ÷ daily operating cash expenses | >90 days | Days of survival assuming zero receipts | + +Check whether facilities are **committed** (a genuine backstop) or **uncommitted / repayable on demand**. India: most working-capital cash-credit and overdraft limits are repayable on demand and reviewed annually — do not count them as committed liquidity, and watch the drawing power fall when the receivable and inventory base securing them deteriorates. Check facility expiry against the maturity ladder: a revolver expiring before the bond it is meant to backstop is not a backstop. + +**Red flags:** current ratio below 1 in a business that does not collect before it pays; liquidity ratios that look adequate only because of slow-moving inventory or doubtful receivables; a large share of "cash" restricted, pledged or trapped; runway under ~12 months with equity markets closed; going-concern emphasis in the audit report. + +--- + +## 8. Working capital and the cash conversion cycle + +Working capital is usually the single largest reason profit and cash diverge, and the cheapest place to detect deterioration early. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| DSO | Trade receivables ÷ revenue × 365, on average balances | Sector-bound: FMCG 10–30d, IT services 60–80d, EPC and infra 120d+ | Rising DSO is the earliest sign of channel stuffing, weakening customers or aggressive recognition | +| DIO | Inventory ÷ COGS × 365 | Sector-bound; developers, distillers and jewellery run in years by design | Inventory built ahead of demand precedes write-downs | +| DPO | Trade payables ÷ COGS × 365 | Stable is good; sharply rising is not | Rising DPO flatters CFO by borrowing from suppliers | +| Cash conversion cycle | DSO + DIO − DPO | Negative is a genuine advantage (retail, marketplaces, subscriptions) | How many days of sales must be funded before cash comes back | +| ΔWorking capital / ΔRevenue | Change in net working capital ÷ change in revenue | <15–20% for a capital-light grower | Tells you whether growth consumes or releases cash | +| Working capital / sales | Net working capital ÷ revenue | Flat or falling | The scaling law of the business model | + +**Method discipline.** Use average balances, not year-end snapshots, and correct for seasonality — a March-year-end Indian manufacturer and a December-year-end US peer are not measured at the same point in their cycle. Put peers on the same revenue basis (gross vs net of indirect taxes) before comparing days. + +**Distinguish a real improvement from a financed one.** A CCC that improves because DPO jumped is supplier financing. A CCC that improves because receivables were factored or securitised is a balance-sheet transaction, not an operating gain. Both reverse, and both strain the counterparty who is funding them. India: Schedule III now mandates **ageing schedules for trade receivables and trade payables** (and for CWIP and intangibles under development) — read them, because a growing over-6-month or over-3-year receivable bucket contradicts a clean-looking headline DSO. + +--- + +## 9. Receivables and inventory quality + +These two assets carry the balance sheet's most optimistic estimates, and they inflate the current and quick ratios while doing it. + +Checks that change conclusions: + +- **Receivables growth vs revenue growth** over 8–12 quarters. Persistent divergence means sales are being recognised faster than they are collected. Cross-reference §14 and `07-forensic-red-flags.md`. +- **Allowance for doubtful accounts ÷ gross receivables, and its trend.** A shrinking allowance into a weakening economy is a quiet earnings source. India: read the Ind-AS 109 expected-credit-loss provision matrix against the ageing buckets. US: the CECL disclosure and the valuation-allowance rollforward. +- **Concentration.** A large receivable from one customer, one government body or a related party is a different asset from a diversified book. In Indian EPC, defence and infrastructure, dues from government and PSU customers are often collectible but with multi-year timing — model the *timing*, not just the loss. +- **Related-party and subsidiary receivables that keep growing and never settle.** A classic tunnelling route; treat a rising, unexplained related-party advance as capital leaving the company. +- **Quarter-end receivable spikes** that reverse in the following quarter — pull-forward of sales into the reporting period. +- **Inventory mix and reserves:** finished goods building faster than sales means sell-through is failing rather than purchasing being early; check the obsolescence-reserve trend and write-down history. For US filers, the LIFO reserve understates carrying value and raises cost of sales relative to FIFO peers — adjust before comparing. +- **Vendor and customer financing.** If the company lends to, guarantees the debt of, or grants unusually long credit to its own customers or distributors to enable purchases, reported growth is partly manufactured credit risk. Track notes receivable, long-dated receivables and customer guarantees against revenue growth. Historically this pattern has ended violently in telecom equipment, solar and EV supply chains — it reads as clean organic growth right up until the receivables sour. + +--- + +## 10. Off-balance-sheet, contingent and quasi-debt obligations + +Everything here is a real economic obligation that can convert into cash and lift true leverage well above the reported figure. Go to the notes; the face of the balance sheet will not tell you. + +| Item | Where to find it | What it does to your numbers | +|---|---|---| +| Reverse factoring / supply-chain finance / channel financing | US: ASU 2022-04 supplier-finance disclosure and rollforward. IFRS/Ind-AS: IAS 7 and IFRS 7 amendments; also the payables note and concall Q&A | Reclassify to debt and reverse the CFO benefit. Debt disguised as trade payables has preceded sudden collapses in construction and supply-chain-finance-dependent names | +| Receivables securitisation, factoring or bill discounting **with recourse** | Financial-instruments note; India — contingent-liabilities note | Gross up receivables and debt; the credit risk never left the company | +| Financial guarantees (subsidiaries, JVs, associates, promoter entities) | Contingent-liabilities note; related-party schedule | Add probability-weighted. A guarantee to a weaker group entity is equity risk written for free | +| Written puts over NCI / minority buyout obligations | Financial-instruments note; shareholder agreements | A dated cash obligation with debt-like seniority, usually invisible in the headline leverage ratio | +| Take-or-pay, purchase and capex commitments | Commitments note | Fixed future outflows; treat as quasi-debt in any downside scenario | +| Pension and OPEB deficit; India — gratuity and leave encashment | Employee-benefits note (Ind-AS 19 / ASC 715) | Add the net deficit to debt; test sensitivity to a 1% discount-rate move and check the expected-return assumption is not flattering the funded status | +| Litigation, tax, environmental and warranty exposures | Contingent liabilities; US Item 3 and the loss-contingency note | India — "contingent liabilities not provided for" is often dominated by **disputed tax demands** (GST, excise, service tax, income tax). Assess litigation stage and the company's historical win rate rather than adding the gross number | +| VIEs, SPEs and structured entities | Consolidation note | Ask what was moved off balance sheet, and why | +| India — promoter share pledge | Quarterly shareholding pattern; encumbrance disclosures | Not a company liability, but a forced-selling overhang and a tunnelling motive. Pledge above ~25–50% of the promoter stake, or rising into a falling price, is a serious governance-plus-liquidity flag — see `07-forensic-red-flags.md` | + +Present the material items as a sensitivity: reported net debt/EBITDA, then the same ratio with quasi-debt included. Where the two tell different stories, that difference *is* your conclusion. + +--- + +## 11. Toxic and structured financing, chronic dilution + +Mostly a small- and micro-cap issue, and it deserves a separate check because it can guarantee a falling share price *regardless of operating performance*. + +Look for: + +- **Variable- or reset-conversion convertibles** ("death-spiral" notes) where the conversion price floats down with the market price. Falling price produces more shares, which produces more selling, which produces a falling price. The instrument is a machine for transferring value away from existing holders. +- **At-the-market (ATM) equity programmes** used continuously to fund operating losses. Quantify the shares issuable under the live shelf at the current price and at a price 50% lower. +- **PIPEs with warrant coverage**, repriceable warrants, and toggle/PIK notes that defer cash cost into principal. +- **India:** preferential allotments and warrants to promoters or related parties priced near the SEBI floor, repeated QIPs whose proceeds fund interest rather than growth, and convertibles issued to group entities. Build the 7–10 year share-count history: chronic dilution while the narrative is "growth" is the tell. + +Compute **potential dilution at a stressed price**, not merely today's diluted count, and restate the thesis per share. A company can triple revenue and still halve the value of your claim. + +--- + +## 12. Goodwill, tangible book and asset productivity + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| (Goodwill + intangibles) / total assets | Balance sheet | Low for organic compounders; high for serial acquirers by construction | Sizes how much of the asset base is a price paid rather than a thing owned | +| Goodwill / equity | Above 100% means negative tangible book | <50% preferred outside roll-ups | A single impairment can erase reported net worth and trip net-worth covenants | +| Tangible book value | Equity − goodwill − intangibles (− revaluation reserves) | Positive | The creditor's view of what actually backs the debt | +| Capex / depreciation | Capex ÷ D&A, 5-year average | ~1.0 sustaining; >1 expanding | Sustained below 1 is harvesting the asset base — borrowing FCF from the future | +| Accumulated depreciation / gross PP&E | Fixed-asset schedule | <60–70% | Asset-age proxy; a near-fully-depreciated base means a replacement cycle is coming | +| Asset turnover and fixed-asset turnover | Revenue ÷ total (or net fixed) assets | Stable or rising vs peers | Links the balance sheet to the earnings that repay creditors; feeds DuPont in `05-returns-and-dupont.md` | + +Read the impairment-test assumptions — terminal growth rate, discount rate, disclosed headroom. Optimistic assumptions defer inevitable write-downs. A serial acquirer carrying unimpaired goodwill over underperforming acquired segments is running a deferred loss. Impairments are non-cash, but they are an admission, and more usefully a dated record of capital-allocation quality. India: watch **CWIP** and "intangible assets under development" sitting unmoved for years in the Schedule III ageing table — a project that never gets commissioned is an impairment waiting to be taken. + +--- + +## 13. Direction of travel, distress scores and credit-market signals + +Trajectory usually matters more than level. Plot five years of adjusted net debt/EBITDA, D/E and interest cover on one view, then *attribute* the change: organic paydown, EBITDA recovery, debt-funded buybacks, debt-funded M&A, working-capital release, or asset sales. Deleveraging by selling the best assets is not deleveraging. + +Corroborate with composites and with markets: + +- **Altman Z-score** (below ~1.8 is the distress zone for manufacturers; use the Z" variant for non-manufacturers and emerging markets; undefined for financials), **Piotroski F-score** (0–9 fundamental momentum), **Beneish M-score** (manipulation likelihood). These are triage that directs attention, never verdicts — say so when you report them. +- **Credit ratings and outlook** — investment grade vs high yield, negative watch, and especially the crossover to junk, which forces index selling. India: CRISIL, ICRA, CARE and India Ratings rationales are detailed, free, and frequently more candid than the annual report. +- **Bond prices vs par, yield-to-maturity vs the sovereign curve, CDS spreads.** Credit markets aggregate professional lenders' real-time judgement and routinely anticipate equity trouble by quarters. When the bonds trade at distressed levels while the equity is priced for growth, one of the two markets is wrong, and it is rarely the bond market. +- **India-specific stress tells:** rating moved to "Issuer Not Cooperating", disclosure of payment default to the exchanges, insolvency petitions filed at the NCLT by operational creditors, auditor or CFO resignation coinciding with a funding squeeze, and a rising promoter pledge into a falling price. + +--- + +## 14. Does profit become cash? Accrual quality + +The highest-yield single test in fundamental analysis. Earnings are an opinion; cash is a fact. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| CFO / net income | Cumulative over 3–5 years, never one year | ~1.0 or above cumulatively | A durable business converts essentially all accounting profit into cash over a cycle | +| CFO / EBITDA | Cash conversion before capex | 70–90%+ for asset-light; structurally lower where working capital is heavy | Isolates working-capital and cash-tax leakage from the capex question | +| Sloan accrual ratio | (Net income − CFO) ÷ average total assets | Low; above ~10% is a flag | High-accrual firms systematically underperform — one of the most robust anomalies in the literature | +| Balance-sheet accruals | Δ(non-cash working capital + net non-current operating assets) ÷ average total assets | Low and stable | Catches accruals that bypass the cash-flow-statement bridge | +| Non-cash add-back share | (D&A + SBC + impairments) ÷ the NI-to-CFO bridge | Understand the mix | A CFO held up entirely by add-backs is not the same as one held up by collections | + +**How to run it.** Bridge net income to CFO line by line for each of the last five years and label every line as (a) genuinely non-cash and recurring, (b) non-cash and one-off, or (c) working capital. Then ask the diagnostic question: is the gap explained by depreciation on a real asset base, or by receivables and inventory? A company reporting record earnings while continually borrowing has already answered it. + +Never conclude from a single year. Working-capital swings, one-off settlements and acquisition timing distort one year and wash out over three to five. + +--- + +## 15. Free cash flow: define it before you use it + +There is no single FCF. State the definition, apply it identically across the peer set, and show the bridge. + +| Variant | Definition | Use it for | +|---|---|---| +| Simple FCF | CFO − capex | The default; comparable across most non-financials | +| Levered FCF (FCFE) | CFO − capex − mandatory debt amortisation (interest already inside CFO under US GAAP) | What is genuinely available to equity after the lenders are served | +| Unlevered FCF (FCFF) | NOPAT + D&A − capex − ΔWC | DCF inputs; independent of capital structure | +| FCF after leases | Subtract lease principal repayments, which IFRS 16 / Ind-AS 116 route to financing | Restoring comparability for retailers, airlines and hotels | +| SBC-adjusted FCF | FCF − stock-based compensation | Tech and growth names (§17) | +| Owner earnings | Net income + D&A − maintenance capex − required working-capital investment | The economic version; requires a maintenance-capex estimate (§16) | + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| FCF margin | FCF ÷ revenue | 5–10% solid for industrials; 20%+ for mature software; near zero or negative is normal mid-build for infra and miners | The clearest single measure of how much of a rupee of sales the owner keeps | +| FCF / net income | Cash conversion of earnings | ~0.8–1.0+ over a cycle | Combines accrual quality and capital intensity into one number | +| FCF / EBITDA | Conversion after capex, cash tax, interest and working capital | >50% for asset-light; structurally lower for asset-heavy | Exposes the gap between the EBITDA management guides on and the cash that arrives | +| FCF yield | FCF ÷ market cap (equity) or ÷ enterprise value (unlevered) | Compare to the risk-free rate and to peers | The bridge into valuation — see `06-valuation.md` | + +Build the **EBITDA-to-FCF bridge** explicitly — cash interest, cash tax, ΔWC, capex, lease principal — each as a percentage of EBITDA. It tells you *where* the cash leaks and whether the leak is structural or fixable. Two firms with identical EBITDA can produce wildly different FCF, and the bridge is the entire explanation. + +**Red flags:** FCF positive only after cutting essential capex; FCF reached with asset sales, tax refunds or insurance proceeds sitting inside the operating section; FCF margin falling while revenue grows (growth that never reaches the owner); positive trailing FCF with negative FCF across the preceding cycle. + +--- + +## 16. Maintenance versus growth capex + +Only growth capex is discretionary. Maintenance capex is a permanent claim on cash, and mislabelling it is the easiest way to inflate normalised FCF and return on capital simultaneously. + +Estimate maintenance capex independently rather than accepting management's split: + +- **D&A-anchored:** take current D&A and adjust upward for inflation since the assets were purchased and for unit growth. Crude, but hard to game. +- **Greenwald method:** compute the historical ratio of gross PP&E to sales, multiply by the current year's *increase* in sales to get growth capex, and treat the remainder of total capex as maintenance. +- **Physical cross-check:** if capex was mostly "growth", capacity or output should have risen. Indian filers routinely disclose installed capacity and utilisation; miners disclose tonnage; utilities disclose MW; telcos disclose sites. Spend that rose without capacity rising was not growth capex. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Capex / revenue | Capex ÷ revenue, 5-year average | 1–3% asset-light; 5–15% manufacturing; 20%+ telecom, utilities, miners | Sets the structural ceiling on FCF margin | +| Capex / D&A | 5-year average | ~1.0 sustaining | Below 1 for several years means the asset base is being harvested | +| Maintenance capex / total capex | From the estimate above | A falling share signals genuine expansion | Determines normalised FCF and owner earnings | +| Incremental capital efficiency | Growth capex ÷ incremental revenue (or incremental EBITDA) | Improving | Tests whether expansion earns its cost of capital before it shows up in ROIC | +| CWIP / gross block (India) | Capital work-in-progress ÷ gross block, read with the ageing schedule | Low and turning over | Large static CWIP is capital deployed but not earning — or an impairment in waiting | + +**Red flags:** capex far below D&A for years while margins hold (deferred maintenance flattering today's FCF at tomorrow's expense); capex spiking with no capacity or revenue response; reclassification of maintenance as growth to promote an "adjusted FCF"; recurring operating costs capitalised as software, development, content or cloud migration — see §19 and `03-earnings-quality.md`. + +--- + +## 17. SBC and the FCF shareholders actually keep + +Stock-based compensation is a genuine economic cost borne by shareholders through dilution, yet it is added back as non-cash and inflates both CFO and FCF. For a growth-tech name it is frequently the difference between an attractive and an unattractive FCF yield. + +Compute and report: SBC ÷ revenue; SBC ÷ CFO; SBC ÷ FCF; **FCF less SBC**; annual diluted share-count growth; and buybacks *net* of issuance. The decisive question is whether repurchases genuinely shrink the share count or merely mop up option and RSU issuance. If the count is flat while the company reports large buybacks, that "capital return" is deferred cash compensation and belongs as a deduction from FCF, not as a shareholder distribution. + +India: ESOP pools are generally smaller outside IT services and recently listed new-age companies, but read the ESOP note, the discount to fair value at grant, and pool refreshes. For recent Indian tech listings, SBC and the associated share-count growth can be large enough to invert the FCF conclusion entirely. + +**Red flags:** SBC a large and rising share of CFO; share count rising despite buybacks; management promoting an adjusted FCF that treats SBC as free; option repricing or accelerated grants after a price fall. + +--- + +## 18. Sources and uses: who funded the growth, were the payouts earned + +Build one cumulative five-year table. Sources: cumulative CFO, debt drawn, equity issued, asset sales. Uses: capex, acquisitions, dividends, buybacks, debt repaid, lease principal. Reconcile to the change in net debt and in share count. This single view answers more questions than any ratio in this file. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Self-funding ratio | Cumulative FCF ÷ cumulative (capex + M&A + distributions) | ≥1.0 | Self-funded growth compounds without dilution or balance-sheet risk | +| FCF payout ratio | (Dividends + gross buybacks) ÷ FCF | <70–80% sustained | Sustained above 100% erodes the balance sheet and ends in a cut | +| Cash dividend cover | FCF ÷ dividends paid | >1.5x | An accounting payout ratio can look safe while the dividend is being borrowed | +| Reinvestment rate | (Capex + M&A + ΔWC) ÷ CFO | Only as high as the return earned justifies | Heavy reinvestment is good only when the incremental return exceeds the cost of capital | +| Net financing flow | Debt drawn − repaid + equity issued − buybacks, over 5 years | Net outflow for a mature franchise | A chronic net *inflow* means the business is capital-markets dependent | +| Share count trend | Diluted shares over 7–10 years | Flat or falling | The per-share claim is the thing you actually own | + +Growth funded repeatedly by new debt or equity is fragile: it depends on open capital markets and reverses violently when they shut. That distinction — self-funded compounder versus capital-markets-dependent story — separates two businesses with identical reported growth rates. India: check whether QIPs and preferential allotments funded expansion or funded interest, who subscribed (public versus promoter and related parties), and at what discount. + +Buyback quality matters too. Repurchases executed at depressed valuations that permanently reduce the count create value; repurchases at peak multiples funded with debt destroy it while flattering EPS. And a high, "safe-looking" dividend yield is usually the market's warning about coverage rather than a gift. + +--- + +## 19. Classification games and off-statement financing + +The section boundaries of the cash-flow statement are a favoured manipulation surface precisely because they attract less scrutiny than the P&L. Moving recurring outflows out of operating, or pulling one-off inflows in, makes cash generation look structurally stronger than it is. + +Check for: + +- **Receivables factoring or securitisation** inflating CFO in the year the programme starts. The step-up is one-time; the run-rate is not. Compare the change in factored balances year over year from the footnote. +- **Reverse factoring** turning a payables outflow into a financing outflow — or worse, staying inside payables and never appearing as debt at all (§10). +- **Capitalised costs** — software development, development-phase R&D (Ind-AS 38 permits capitalisation; US GAAP is stricter), content, cloud implementation — moving cash from operating to investing. Track capitalised spend as a share of total spend, and its trend. +- **Lease classification.** Under IFRS 16 / Ind-AS 116 the lease principal sits in financing, so CFO is structurally higher than under a US GAAP operating lease. Never compare CFO or CFO/EBITDA across the two regimes unadjusted. +- **Interest and dividend classification.** Under Ind-AS/IFRS, interest paid may be presented in operating *or* financing, and dividends received in operating or investing. Most Indian corporates place interest paid in financing, which makes Indian CFO a **pre-interest** number; US GAAP forces interest paid into operating. Comparing an Indian CFO/EBITDA with a US one without normalising flatters the Indian company, sometimes substantially. +- **One-offs dressed as operating cash:** asset-sale proceeds, litigation and insurance settlements, large tax refunds, government incentive receipts. Compute one-offs as a percentage of CFO. +- **Gross versus net capex** presentation, and disposal proceeds netted against capex to flatter FCF. +- **Opaque "other operating" lines** that are large, volatile and unexplained. +- **Year-end window dressing:** payables settled just after year-end, receivables collected just before, inventory shipped to distributors on quarter-end terms. Where quarterly balance-sheet data exists, compare the year-end balance to the average of the four quarter-ends. + +--- + +## 20. Cash taxes versus book taxes + +A low cash tax rate can lift current FCF materially — and most of the drivers expire. + +Compute the **cash tax rate** = cash taxes paid ÷ pre-tax income, and set it against the effective book rate and the statutory rate. Explain every gap: accelerated depreciation, loss carryforwards, tax credits, jurisdiction mix, holidays and incentives. Then estimate the **sustainable** rate once timing differences reverse and carryforwards are exhausted, and use that rate in any forward FCF or DCF. Investors who capitalise an artificially low cash tax rate overpay by construction. + +India specifics: the concessional 22% regime under s.115BAA (and 15% for qualifying new manufacturing under s.115BAB) versus the older rate; MAT credit utilisation and expiry; SEZ and unit-based deductions winding down; area-based incentives. A company still riding MAT credit or an expiring SEZ benefit has a cash-tax step-up coming that no historical ratio will reveal. + +**Red flags:** a large unexplained cash-versus-book gap; FCF flattered by carryforwards about to run out; a growing deferred tax liability that will reverse into cash outflows; guidance that projects today's cash tax rate indefinitely. + +--- + +## 21. Full-cycle durability and cash return on capital + +Two companies with identical trailing FCF can carry entirely different risk. Assess durability before you capitalise anything. + +- Pull CFO and FCF through the **last downturn** for that sector — 2008–09, 2013 (India: taper and current-account stress), 2015–16 (commodities), 2020, plus any industry-specific bust. If the history does not go back that far, say so and treat durability as unproven rather than assuming it. +- Compute **FCF margin volatility** (standard deviation across the cycle) and the trough-to-peak FCF ratio. +- Establish the **recurring share** of cash flow: contracted, subscription or annuity revenue versus transactional and project-based; customer and end-market concentration; commodity linkage. Recurring cash flow deserves a higher multiple because it is more predictable and more self-funding. +- Set a **mid-cycle normalised FCF** and use that in valuation. Capitalising peak-cycle FCF is the most common valuation error in cyclicals, and it is usually compounded by the fact that leverage also looks fine at the peak. + +Then close the loop from cash to value creation: + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| CROIC | FCF ÷ invested capital | Above WACC, consistently | Cash generation creates value only if reinvested above its cost | +| CFROI vs WACC | Inflation-adjusted cash return versus cost of capital | Positive spread | The cash analogue of the ROIC–WACC spread in `05-returns-and-dupont.md` | +| Incremental return on reinvested cash | Δ FCF ÷ cumulative reinvestment, lagged 2–3 years | Above WACC | Averages hide a deteriorating margin on new investment | +| Intrinsic growth rate | Reinvestment rate × cash return on capital | Compare to the growth the market is pricing | The compounding arithmetic a DCF is implicitly asserting | + +**Red flags:** heavy reinvestment at cash returns below the cost of capital (busy value destruction); declining cash returns on rising invested capital; acquisitions absorbing all the FCF with no improvement in returns; leverage and dividends both calibrated to peak-cycle cash generation. + +--- + +## 22. India versus US: conventions that break comparability + +- **Reporting frequency.** Indian listed companies file quarterly *results* but a balance sheet and cash-flow statement only **half-yearly** under SEBI LODR. You cannot compute a quarterly CCC or CFO for an Indian filer the way you can from a 10-Q. State that limitation rather than interpolating silently. +- **Standalone versus consolidated.** Always analyse **consolidated** statements for leverage, cash and contingent liabilities; standalone hides subsidiary debt and guarantees. Where the listed entity is a holdco, examine both and say where the cash sits versus where the debt sits. +- **Units.** ₹1 crore = 10 million; ₹1 lakh = 100,000. Convert once, label every table, and never mix crore and million within one table. +- **Interest inside CFO.** Ind-AS/IFRS optionality versus US GAAP's mandatory operating classification (§19). Normalise before any cross-border CFO comparison. +- **CARO 2020** (India) has no US analogue and is a free forensic read: short-term funds applied to long-term purposes, loans and advances to related parties, wilful-defaulter status, undisclosed income surrendered in tax proceedings, whistle-blower complaints, and the auditor's view on fund diversion. +- **Schedule III ratio and ageing disclosures** (India): current ratio, debt-equity, DSCR, return ratios, inventory and receivable turnover and more must be disclosed with an explanation for any change above 25% year on year — plus ageing schedules for receivables, payables, CWIP and intangibles under development. Read management's own explanation first, then test it. +- **Contingent liabilities** (India) are typically dominated by disputed tax demands and disclosed gross. Do not add them to debt at face value, but do assess litigation stage, precedent and the company's track record. +- **Concall transcripts** (India) are a primary source and frequently the only place working-capital, collection and covenant questions are answered. US equivalents: Item 7 liquidity and capital resources, the earnings call, and EDGAR full-text search across exhibits. +- **Credit information.** India: rating rationales from CRISIL, ICRA, CARE and India Ratings are detailed, free and often more candid than the annual report. US: agency reports are gated, but bond prices, spreads and 8-K covenant events are public. + +--- + +## Checklist + +- [ ] Run the sector gate first — if bank, NBFC, insurer, REIT/InvIT, developer or miner, switch to the sector file before computing any ratio here. +- [ ] Build adjusted net debt: borrowings + leases + pension/gratuity deficit + reverse factoring + recourse securitisation + guarantees + NCI puts + hybrids, less *proven* unrestricted cash. +- [ ] Prove the cash: reconcile interest income to average balances at market rates; explain any large simultaneous gross-cash-and-gross-debt position. +- [ ] Compute leverage on adjusted net debt and on mid-cycle EBITDA; report gross as well as net. +- [ ] Map the maturity ladder against cash + committed undrawn + projected FCF for 24 months; name the maturity-wall year. +- [ ] Split debt by fixed/floating, currency and secured/unsecured; check hedging and how much unencumbered collateral remains. +- [ ] Compute earnings-based and cash-based coverage; stress-test at −25% CFO and at current refinancing rates. +- [ ] Find the covenants; compute headroom %, note the EBITDA definition, springing triggers, cross-defaults and any waiver history. +- [ ] Report absolute available liquidity and months of runway, not just current and quick ratios; verify facilities are committed. +- [ ] Compute DSO, DIO, DPO and CCC on average balances; test whether any improvement came from factoring or stretched payables. +- [ ] Test receivables growth versus revenue, allowance trend, ageing buckets, concentration and related-party receivables; test finished-goods inventory versus sales. +- [ ] Sweep the notes for off-balance-sheet and contingent items; present reported versus quasi-debt-adjusted leverage side by side. +- [ ] Screen for toxic financing and chronic dilution; compute potential dilution at a stressed price. +- [ ] Compute tangible book, goodwill/equity, capex/D&A and asset age; read the impairment assumptions and (India) the CWIP ageing. +- [ ] Plot the five-year leverage trend and attribute it; corroborate with Altman/Piotroski, ratings, bond spreads and India-specific stress tells. +- [ ] Compute cumulative CFO/net income over 3–5 years and the Sloan accrual ratio; bridge net income to CFO line by line. +- [ ] State your FCF definition; compute FCF margin, FCF/NI, FCF/EBITDA and the full EBITDA-to-FCF bridge. +- [ ] Estimate maintenance capex independently; cross-check against disclosed capacity or output growth. +- [ ] Recompute FCF net of SBC; check whether buybacks reduce the share count or only offset issuance. +- [ ] Build the five-year sources-and-uses table; reconcile to change in net debt and share count; test the FCF payout ratio. +- [ ] Check for classification games: factoring, capitalised costs, lease and interest classification, one-offs inside CFO. +- [ ] Compare cash tax to book tax; estimate the sustainable rate and use it forward (India: 115BAA, MAT credit, SEZ expiry). +- [ ] Look at FCF through the last downturn; compute FCF volatility and set a mid-cycle normalised FCF for valuation. +- [ ] Compute CROIC versus WACC and the incremental return on reinvested cash. +- [ ] Normalise India/US conventions (consolidated basis, crore units, interest-in-CFO, half-yearly cash-flow availability) before any cross-market comparison. +- [ ] State every band you cite as indicative, and immediately give the peer-set and own-history figures that override it. diff --git a/finance/skills/stock-analysis/references/05-returns-and-dupont.md b/finance/skills/stock-analysis/references/05-returns-and-dupont.md new file mode 100644 index 00000000..b6d2a5c8 --- /dev/null +++ b/finance/skills/stock-analysis/references/05-returns-and-dupont.md @@ -0,0 +1,480 @@ +# Return on capital, DuPont decomposition and the arithmetic of compounding + +Use this when: you are at Stage 4 with a clean set of financials and need to establish how much the company earns on the money tied up in it, whether that return exceeds its cost of capital, and whether the next rupee invested will earn the same as the last. + +This is the intellectual centre of the skill. Margin tells you what a company keeps out of each rupee or dollar of sales; return on capital tells you what it earns on the money required to make that sale, and only the second one compounds. A business earning 35% on capital funds 10% growth out of a quarter of its profit and hands the rest to owners; a business earning 11% must plough back almost everything to grow at the same rate and returns nothing. That difference — not the margin, not the growth rate — separates a compounding machine from a treadmill, and it is invisible on the income statement. Everything below answers three questions in order: **what is the true return on capital, is it above the cost of capital, and will incremental capital earn the same?** + +## Contents + +- [0. Sector gate — where this arithmetic breaks](#0-sector-gate--where-this-arithmetic-breaks) +- [1. The core argument: why a 20% margin can beat a 30% margin](#1-the-core-argument-why-a-20-margin-can-beat-a-30-margin) +- [2. Which return metric to use, and when](#2-which-return-metric-to-use-and-when) +- [3. Building NOPAT properly](#3-building-nopat-properly) +- [4. Defining invested capital, and the adjustments that decide the answer](#4-defining-invested-capital-and-the-adjustments-that-decide-the-answer) +- [5. ROIC versus WACC: the spread is the whole game](#5-roic-versus-wacc-the-spread-is-the-whole-game) +- [6. DuPont: 3-step and 5-step](#6-dupont-3-step-and-5-step) +- [7. Asset turnover and capital efficiency](#7-asset-turnover-and-capital-efficiency) +- [8. How much of the return is just leverage](#8-how-much-of-the-return-is-just-leverage) +- [9. Return on incremental invested capital (ROIIC)](#9-return-on-incremental-invested-capital-roiic) +- [10. Cash returns: is the ROIC real](#10-cash-returns-is-the-roic-real) +- [11. Tangible versus total capital: the goodwill effect](#11-tangible-versus-total-capital-the-goodwill-effect) +- [12. Consistency and durability across a full cycle](#12-consistency-and-durability-across-a-full-cycle) +- [13. Normalisation: what the mid-cycle return actually is](#13-normalisation-what-the-mid-cycle-return-actually-is) +- [14. Peer and cross-cycle benchmarking](#14-peer-and-cross-cycle-benchmarking) +- [15. Fade rate and the competitive advantage period](#15-fade-rate-and-the-competitive-advantage-period) +- [16. Segment and divisional returns](#16-segment-and-divisional-returns) +- [17. Buybacks, dividends and denominator effects](#17-buybacks-dividends-and-denominator-effects) +- [18. Fourteen ways a reported ROIC lies](#18-fourteen-ways-a-reported-roic-lies) +- [19. India versus US conventions](#19-india-versus-us-conventions) +- [20. What to put in the report](#20-what-to-put-in-the-report) +- [Checklist](#checklist) + +**Every range in this file is indicative only.** Return levels are a function of sector, capital intensity, accounting regime, the rate cycle and the local cost of capital. A 12% ROIC is excellent for a regulated utility, roughly value-neutral for an Indian manufacturer facing a 12–13% WACC, and poor for asset-light software. Peer comparison and the company's own 5–10 year record override every absolute band printed here. If you quote a band, quote it as a starting reference and then state what the actual peer set earns. + +## 0. Sector gate — where this arithmetic breaks + +Run this before computing anything. For several sectors the standard return ratios are not merely less useful — they are undefined, inverted, or measuring the wrong thing. + +| Sector | What breaks | Use instead | +|---|---|---| +| **Banks** | Debt is raw material, not financing. Invested capital, NOPAT, EV and ROIC are meaningless; a bank is *supposed* to run 8–15x assets/equity. | ROA (indicatively 1.0–1.8%) and ROE (12–18%) read **together with** CET1/CAR, plus NIM, cost-to-income, credit cost, RoRWA. `references/sectors/banks.md` | +| **NBFCs / HFCs** | Same. Leverage is the product. DuPont still works, but only in the lender form. | ROA decomposed into NIM + fees − opex − credit cost, × equity multiplier; leverage against the regulatory ceiling. `references/sectors/nbfc.md` | +| **Insurers** | New-business strain depresses reported ROE precisely when the company is writing profitable growth. Invested capital is not meaningful against float. | Life: ROEV, VNB margin, operating variances. General: combined ratio, ROE ex-investment gains. `references/sectors/insurance.md` | +| **REITs / InvITs** | Assets are carried at fair value and the asset *is* the business, so ROIC collapses toward the cap rate by construction. | AFFO yield, NOI yield on cost, cap rate vs cost of debt, LTV. `references/sectors/realestate-reit.md` | +| **Miners, commodity producers, refiners** | ROCE at spot prices is procyclical nonsense — highest at the top, negative at the bottom, and neither is the business. | ROCE on **mid-cycle** realised prices; return per tonne; all-in sustaining cost position. `references/sectors/metals-mining.md` | +| **Regulated utilities, transmission** | The return is *set by a regulator*, not earned competitively. India: CERC/SERC norms fix an allowed RoE on approved equity. US: allowed ROE per rate case. | Allowed vs achieved RoE, regulated asset base growth, regulatory assets/under-recoveries. `references/sectors/utilities-power.md` | +| **Holdcos and conglomerates** | Consolidated ROIC blends unrelated businesses into a number no manager can act on. | Segment returns (§16) and sum-of-the-parts. `references/sectors/holdco-assetmgr.md` | +| **Negative-invested-capital businesses** (exchanges, subscription, ticketing, quick commerce, some platforms) | Customer float and payables fund the business, so invested capital approaches zero or goes negative and ROIC becomes infinite or nonsensically negative. | Say so explicitly — it is a *strength*, not a data error. Use ROE, return on tangible capital with a stated floor, and cash generated per unit of fixed capital. | +| **Loss-making / early-stage** | Negative NOPAT makes every return ratio uninterpretable. | Unit economics, contribution margin, cohort payback, path to first positive ROIC. `references/13-situations.md` | +| **Airlines, shipping, retail chains, hotels** | Lease structures shift capital off the denominator and distort EBIT differently under each regime. | Lease-adjusted invested capital, always. ROIC and EV/EBITDAR on the capitalised base. | + +## 1. The core argument: why a 20% margin can beat a 30% margin + +The identity that governs the entire skill: + +``` +ROE = Net margin × Asset turnover × Equity multiplier + (NI/Sales) (Sales/Assets) (Assets/Equity) + +ROIC ≈ NOPAT margin × Capital turnover + (NOPAT/Sales) (Sales/Invested capital) +``` + +Margin is **one of three terms**. A company earns a superb return on capital with a thin margin if it turns capital over quickly, and a mediocre return with a fat margin if each unit of sales demands enormous fixed assets and working capital. + +**Illustration 1 — same return, opposite margins** (generic and illustrative). + +| | Distributor | Branded manufacturer | +|---|---|---| +| NOPAT margin | 4% | 20% | +| Sales / invested capital | 5.0x | 1.0x | +| **ROIC** | **20%** | **20%** | + +Identical economics. The 4%-margin business is not worse; it is a different machine reaching the same place by turning capital five times instead of once. Ranking these two on margin teaches you nothing. + +**Illustration 2 — the inversion, where the low-margin business is materially better.** + +| | Capital-light distributor | Capital-heavy specialty producer | +|---|---|---| +| EBIT margin | 6% | 25% | +| Sales / invested capital | 4.0x | 0.5x | +| Pre-tax return on capital | 24% | 12.5% | +| After 25% tax | **18%** | **9.4%** | +| WACC (illustrative, India) | 12% | 12% | +| **Verdict** | **+6 pts of spread — compounding** | **−2.6 pts — destroying value while growing** | + +The 6%-margin business earns roughly double the return of the 25%-margin business and is the only one of the two creating value. This is the OPM error stated as arithmetic: **margin is a ratio to sales, and shareholders do not own sales — they own capital.** + +**Illustration 3 — three companies with an identical 18% ROE and three different risk profiles.** + +| | Net margin | Asset turnover | Equity multiplier | ROE | +|---|---|---|---|---| +| Quality operator | 12% | 1.2x | 1.25x | 18% | +| Efficiency operator | 3% | 2.4x | 2.5x | 18% | +| Leveraged asset owner | 9% | 0.5x | 4.0x | 18% | + +The first is self-funding and survives a downturn. The third needs continuous credit access; a 25% fall in operating profit destroys its interest cover and its ROE mean-reverts violently. **Never compare headline ROEs without decomposing them.** + +Two implications to carry through the whole analysis: + +1. **Where the margin sits within its sector matters far more than the margin.** A 20% margin in distribution is an outlier; 30% in enterprise software is unremarkable. Establish the sector distribution first (`references/10-peer-set.md`). +2. **Growth is only valuable above the cost of capital.** Revenue growth funded at sub-WACC returns destroys value while making sales, EBITDA and often EPS look better every year. This is the most common way a "growth story" loses money for its shareholders. + +## 2. Which return metric to use, and when + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **ROE** | Net profit attributable to owners ÷ average shareholders' equity (exclude minority interest from both) | India: >15% good, >20% strong, sustained >25% rare without leverage. US: >15% good. Financials have their own bands | The equity holder's return, but contaminated by leverage, buybacks and one-offs. Never quote it without the DuPont split | +| **ROCE (pre-tax)** | EBIT ÷ capital employed, where capital employed = total assets − current liabilities ≈ net worth + total debt + lease liabilities | India: >15% decent, >20% good, >25% strong. Pre-tax, so **not** comparable to after-tax ROIC | The default Indian convention (screener.in, most sell-side notes). Being pre-tax, it is the cleaner metric for cross-period comparison when tax regimes change | +| **ROIC (after-tax)** | NOPAT ÷ average invested capital (§3, §4) | Judge against WACC, not an absolute band. Broadly: US >12%, India >14–15% clears typical hurdles | The correct economic measure and the only return figure directly comparable to the cost of capital | +| **ROA** | Net income ÷ average total assets | Industrials 5–10%; utilities/telecom 2–5%; banks 1.0–1.8% | Leverage-free view of asset productivity. The ROE−ROA gap *is* the leverage contribution | +| **ROTIC / return on tangible capital** | NOPAT ÷ invested capital excluding goodwill and acquired intangibles | Structurally higher than ROIC; the *gap* is the signal | Shows the operating economics stripped of what was paid to acquire them | +| **ROTE** | Net income ÷ average tangible equity | Banks 12–18% | Standard for financials, where goodwill is not loss-absorbing capital | +| **CROIC / CFROI** | FCF (or CFO − maintenance capex) ÷ invested capital | Within roughly 70–100% of ROIC on a 5-year average | Tests whether accounting returns convert into cash owners can actually have | +| **Return on gross invested capital** | NOPAT ÷ invested capital using **gross** (pre-accumulated-depreciation) fixed assets | Materially lower than net-book ROIC for old asset bases | Replacement-cost sanity check. A fully depreciated plant shows a spectacular net-book return and a poor one on what rebuilding costs | +| **ROIIC** | Δ NOPAT ÷ Δ invested capital over 3- and 5-year windows | Should be ≥ current ROIC and comfortably > WACC | The forward-looking number: does continued reinvestment compound or dilute | +| **Economic profit / EVA** | (ROIC − WACC) × invested capital | Positive and growing in absolute currency | Converts a percentage into money. A firm can raise ROIC by shrinking and still create less value | +| **RoRWA** (financials only) | Net profit ÷ average risk-weighted assets | Indian banks: 1.5–2.5% is strong | Risk-adjusted, and the only honest comparison across lenders with different books | + +Use **at least three**: ROCE or ROIC for the economics, ROE for the equity holder's view, CROIC for the reality check. Where they diverge is where the analysis lives. + +## 3. Building NOPAT properly + +NOPAT is the profit the business would earn with no debt — the numerator that matches a denominator financed by debt *and* equity. + +``` + EBIT (reported) ++ Operating-lease interest IFRS 16 / Ind AS 116 already exclude it from EBIT; + for US GAAP filers add back the imputed interest inside lease cost ++ R&D expensed this year only if you also capitalise R&D in the denominator (§4) +− Amortisation of capitalised R&D ++ Impairments and non-recurring charges; − non-recurring gains ++ Pension service-cost normalisation where the disclosed charge is distorted += Adjusted EBIT (NOPBT) +× (1 − normalised cash tax rate) += NOPAT +``` + +Rules that decide whether the number is usable: + +- **Use a normalised cash tax rate**, not the statutory rate and not one year's effective rate. Take cash taxes paid ÷ pre-tax profit over 3–5 years and sanity-check against statutory. **India:** a company that elected the concessional regime (Section 115BAA, ~25.2% effective including surcharge and cess; ~17.2% for qualifying new manufacturing under 115BAB) is not comparable to its own pre-FY20 history at ~34.9%. **US:** the 2018 cut from 35% to 21% federal breaks a 10-year after-tax series the same way. For cross-cycle work, hold the tax rate constant or use pre-tax ROCE. +- **Do not add back stock-based compensation.** SBC is a real cost that transfers value from existing owners. It also creates no invested capital, which is exactly why heavy-SBC firms show flattered ROIC — note the distortion rather than removing the cost (`references/03-earnings-quality.md`). +- **Match non-operating income to non-operating assets.** Treasury income on surplus cash, rent from non-operating property, and share of profit from associates must either stay with their assets in the denominator or be removed from both sides. Indian companies with large treasury books routinely get this wrong in their own investor decks. +- **Minority interests.** Consolidated EBIT includes 100% of a partly owned subsidiary that owners do not fully own. Either use consolidated NOPAT with capital including minority interest, or strip both. Never mix. + +## 4. Defining invested capital, and the adjustments that decide the answer + +Two routes to the same number. **Compute both and reconcile** — a gap means something is misclassified. + +``` +Operating route: Net working capital (excl. excess cash, excl. debt in current liabilities) + + Net PP&E + CWIP / construction in progress + + Right-of-use (capitalised lease) assets + + Goodwill and acquired intangibles [total-capital version only] + + Capitalised R&D / brand investment [where applicable] + − Non-interest-bearing operating liabilities + = Invested capital + +Financing route: Total debt + lease liabilities + shareholders' equity + minority interest + − Excess cash and non-operating investments + = Invested capital +``` + +| Adjustment | What to do | Why it changes the conclusion | +|---|---|---| +| **Operating leases** | IFRS 16 and Ind AS 116 (mandatory for Indian listed entities from FY2020) already capitalise them. **US GAAP (ASC 842) capitalises the balance sheet but keeps the entire lease cost in operating expense** — so a US filer's EBIT is depressed relative to an IFRS filer's for identical economics. For pre-FY2020 Indian data and pre-2019 US data, capitalise at ~8x annual rent or the PV of disclosed commitments | Retail, QSR, airlines, hotels, logistics and hospital chains look "asset-light" purely through lease accounting; unadjusted ROIC can be double the true figure. It also silently breaks any 10-year ROCE series at the transition year | +| **Goodwill and acquired intangibles** | Compute ROIC both with and without (§11). Not amortised under Ind AS or US GAAP, so goodwill sits in capital permanently until impaired | Excluding goodwill measures operations; including it measures capital allocation. Both are needed | +| **Cumulative impairments and write-offs** | Add back cumulative goodwill impairments, restructuring write-offs and discontinued-operation losses to the denominator | Otherwise the company is *rewarded* for destroying capital: writing off a bad acquisition shrinks the denominator and lifts ROIC permanently | +| **Excess cash** | Subtract cash above an operating requirement (roughly 2–5% of revenue, sector-dependent) and state the assumption | Net-cash Indian IT services and pharma names show ~25% ROE but 40%+ ROIC once idle cash is removed. That gap is the size of the capital-allocation problem and should be reported as such | +| **Non-operating investments** | Remove associates, listed holdings, group-company loans and surplus real estate — and remove the matching income from NOPAT. **India:** Section 186 loans, guarantees and investments to group entities belong here | Endemic in Indian promoter groups. Leaving them in understates the operating business's true return and hides where capital actually went | +| **CWIP / assets under construction** | Report ROCE both including and excluding CWIP | A cement or capital-goods company mid-expansion earns nothing on CWIP but carries it. Excluding it shows the return on *working* assets; including it shows what shareholders are getting today. **India:** Schedule III requires CWIP ageing plus disclosure of projects overdue or over budget — read it before assuming the CWIP will ever earn | +| **R&D and brand spend** | For intangible-driven businesses (software, pharma, branded consumer), capitalise and amortise over an economic life (3–5 yrs software, 5–10 yrs pharma) and add to capital | Expensing all R&D leaves the firm's principal asset out of the denominator. This is the largest single source of overstated ROIC in US technology and pharma | +| **Revaluation reserves (India)** | If PPE is carried at revalued amounts under Ind AS 16, flag it; consider restating to historic cost for peer comparability | Revaluation inflates equity and capital employed, mechanically depressing ROE and ROCE with no economic change | +| **Average vs point-in-time capital** | Use the **average** of opening and closing capital; for ROIIC and acquisition years use **beginning-of-period** capital | Year-end capital after a December acquisition pairs a full year of old NOPAT with a full year of new capital, understating the return; the reverse flatters it | +| **Gross vs net fixed assets** | Cross-check with a gross-invested-capital ROIC | An old, fully depreciated base produces a return no one could earn building the same plant today — including the company when it must replace it | +| **JVs and associates** | Equity-method income sits in the numerator while the investment sits in the denominator: keep both, strip both, or proportionately consolidate | Common in Indian infrastructure, cement and tower structures, where much of the economics sits outside the consolidated operating lines | + +**Apply whatever you choose identically to the peer set and to every year of history, and state the definition in the report.** An ROIC computed on a different basis from its comparison set is worse than no ROIC at all. + +## 5. ROIC versus WACC: the spread is the whole game + +A business creates value only when ROIC > WACC. Below that line growth destroys value: every additional rupee invested returns less than it cost to raise, while revenue, EBITDA and often EPS keep rising. + +``` +Economic profit = (ROIC − WACC) × Invested capital +Value creation = economic profit, sustained and growing, across the competitive advantage period +``` + +**Estimating WACC without false precision.** Derive it from current market data at the time of analysis — never from memory — and present it as a range. + +- **Cost of equity** = risk-free rate + beta × equity risk premium. **India:** current 10-year G-sec yield with an ERP usually taken at 5.5–7%, which has historically put large-cap cost of equity in a low-to-mid-teens range. **US:** current 10-year Treasury with an ERP usually 4.5–5.5%, giving a high-single to low-double-digit cost of equity. These move with the rate cycle — state the inputs and the date. +- **Cost of debt** = the company's actual marginal borrowing rate (interest-rate disclosure or recent issuance), after tax. Not the historical average rate on legacy debt. +- Weight by **market** values of debt and equity, not book. +- **Do not present WACC to two decimals.** Use a range (e.g. "11–13%") and test the conclusion at both ends. If the value-creation verdict flips inside your own WACC range, that *is* the finding — say so. +- **The India/US gap is structural.** A higher risk-free rate means an Indian company needs a materially higher ROIC to create the same economic value as a US peer. A 12% ROIC that clears the bar comfortably in the US can be value-neutral in India. Never compare raw ROIC across markets — compare the spread. + +**Report:** ROIC, WACC range, spread in basis points, economic profit in absolute currency, and how many of the last 7–10 years had a positive spread. + +**Red flags:** ROIC persistently below WACC while capex or M&A accelerates; a positive spread narrowing year after year; management emphasising adjusted EPS or revenue growth while economic profit stagnates; a spread that was positive only during a demand boom. + +## 6. DuPont: 3-step and 5-step + +**3-step** — answers *what kind of business is this?* + +``` +ROE = (Net income / Sales) × (Sales / Total assets) × (Total assets / Equity) + = Net margin × Asset turnover × Equity multiplier +``` + +**5-step** — answers *where is the ROE actually coming from?* + +``` +ROE = (NI/EBT) × (EBT/EBIT) × (EBIT/Sales) × (Sales/Assets) × (Assets/Equity) + = Tax burden × Interest burden × Operating margin × Asset turnover × Leverage +``` + +Worked illustration: 0.75 × 0.85 × 14% × 1.2 × 1.5 = **16.1% ROE**. Now the next year the company reports 18.5%. Rerun the terms: if operating margin and turnover are unchanged and the gain came from the interest burden rising to 0.92 (cheaper refinancing) and leverage to 1.7, the business did not improve at all — the balance sheet and the rate cycle did. That distinction is entirely invisible in the headline number. + +**How to run it.** + +1. Compute all five terms for each of the last 5–10 years, one row per year. +2. Identify which term moved most, in percentage-point contribution to the change in ROE. +3. Classify the ROE as **operations-driven** (margin × turnover) or **financing-driven** (tax burden, interest burden, leverage). +4. Run the same table for 2–3 peers. Firms with the same ROE and different decompositions are not comparable investments. +5. **Financials:** use the lender form — ROE = ROA × equity multiplier, with ROA broken into NIM + fee income − opex − credit cost, each as a % of average assets. + +**What each term tells you.** + +| Term | Rising is good when | Rising is a warning when | +|---|---|---| +| Tax burden (NI/EBT) | A permanent regime change (India: 115BAA election) or a genuine structural mix shift | It reflects one-off credits, MAT credit utilisation, an expiring tax holiday about to reverse, or aggressive positions under dispute | +| Interest burden (EBT/EBIT) | Debt has genuinely been repaid | It reflects refinancing at temporarily low rates, or interest capitalised into CWIP instead of expensed | +| Operating margin | Pricing power, mix, or operating leverage that persists | It comes from an input-cost trough, a one-off, capitalised costs, or under-spend on maintenance and marketing | +| Asset turnover | Genuine utilisation gains | It reflects a shrinking asset base from write-offs, or leasing that moved assets off balance sheet | +| Equity multiplier | Almost never good in isolation | Always. Rising leverage is the cheapest way to manufacture ROE and the fastest way to lose the company | + +**Red flags:** ROE rising while ROIC is flat or falling (the whole gain is financing); declining turnover masked by added leverage; margin expansion later revealed as non-recurring; ROE improving while book value per share stalls. + +## 7. Asset turnover and capital efficiency + +Turnover is the forgotten half of ROIC and usually the half that explains why a low-margin business is excellent. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Total asset turnover** | Sales ÷ average total assets | Distribution/retail 2–4x; manufacturing 0.8–1.5x; utilities/telecom 0.3–0.5x | The efficiency term in DuPont. Judge only against sector | +| **Sales / invested capital** | Sales ÷ average invested capital | Cleaner than asset turnover — excludes idle cash and non-operating assets | The term that multiplies with NOPAT margin to give ROIC | +| **Fixed-asset turnover** | Sales ÷ average net PP&E | Track the trend, not the level | Falling fixed-asset turnover alongside rising capex is the classic signature of building into demand that did not arrive | +| **Working capital turnover** | Sales ÷ average net working capital | Sector-dependent; negative working capital is a feature in retail, QSR and subscription | Usually the largest and most controllable lever on ROIC in Indian manufacturing and trading | +| **Capital intensity** | Capex ÷ sales; total assets ÷ sales | Compare capex/sales with depreciation/sales to separate maintenance from growth | Rising intensity without a margin benefit means returns are heading down regardless of this year's number | +| **Physical productivity** | Revenue per employee, per store, per tonne, per bed, per seat-km, per MW | Sector-specific — take it from the sector playbook | The check that survives accounting choices entirely | + +Cross-check against the cash conversion cycle in `references/04-balance-sheet-and-cashflow.md`: an inventory or receivables build simultaneously flatters reported profit and depresses turnover, so it shows up on both sides of the ROIC identity. + +**Red flags:** asset base growing faster than sales for more than two consecutive years; turnover far below peers with no structural explanation in the business model; turnover improving only because assets were written off or moved into leases. + +## 8. How much of the return is just leverage + +``` +Leverage contribution ≈ ROE − ROA (percentage points) +Financial leverage index = ROE / ROA (>1 means leverage is adding) +``` + +Leverage adds to ROE only while ROIC exceeds the after-tax cost of debt. When that spread inverts — in a downturn, or after refinancing at higher rates — leverage subtracts at the same multiple. The asymmetry is the entire risk. + +- **ROIC minus after-tax cost of debt.** Needs to be wide enough to survive a cyclical decline in ROIC. A company earning 11% ROIC and borrowing at 9% pre-tax has almost no cushion, whatever its ROE says. +- **Stress it against the trough.** Take the worst ROIC year of the last decade (§12), recompute interest cover at today's debt level, and check whether the capital structure survives it. +- **Negative or near-zero tangible equity** makes ROE arithmetically meaningless — it explodes as equity approaches zero from above and inverts below it. Several large US consumer and aerospace names have run negative book equity after years of debt-funded buybacks. For those, drop ROE and use ROIC and ROTIC. +- **India:** promoter share pledging is hidden leverage on the equity itself. High pledging plus high financial leverage compounds in a way no return ratio captures (`references/08-governance.md`). + +**Red flags:** ROE far exceeding ROIC with the gap widening; rising leverage as the sole driver of ROE growth; debt-funded buybacks lifting leverage and ROE together while ROIC is flat. + +## 9. Return on incremental invested capital (ROIIC) + +Average ROIC is history. ROIIC is the forecast. + +``` +ROIIC (3-yr) = (NOPAT_t − NOPAT_t−3) / (Invested capital_t−1 − Invested capital_t−4) +``` + +Lag the denominator by a year — capital takes time to earn. Use rolling 3- and 5-year windows; single-year ROIIC is noise. + +**Worked illustration.** NOPAT rises from 100 to 130 over three years while invested capital rises from 500 to 900. + +- ROIC at the start: 100/500 = **20%** +- ROIC now: 130/900 = **14.4%** — still a respectable-looking headline +- ROIIC: 30/400 = **7.5%** — below an 11–12% WACC + +Every rupee of new capital is destroying value. The legacy business is subsidising the expansion, and the blended ROIC will keep drifting toward 7.5% as new capital dominates the base — while management reports record profits throughout. **This is the highest-value calculation in this file, and almost nobody runs it.** + +**Pair it with the reinvestment rate:** + +``` +Reinvestment rate = (capex + acquisitions + Δ working capital − depreciation) / NOPAT +Intrinsic NOPAT growth ≈ Reinvestment rate × ROIIC +``` + +A firm reinvesting 50% of NOPAT at 20% incremental returns compounds at ~10% with no external funding. A firm reinvesting 90% at 8% compounds at ~7% while consuming all its cash and creating nothing. Use the identity to test management guidance: if the promised growth implies a reinvestment rate above 100% of NOPAT, the plan requires debt or dilution — say so explicitly. + +**Red flags:** incremental returns below both the historical average and WACC; large capex or acquisition programmes with flat NOPAT three years later; ROIIC falling steadily as the firm scales (saturation or diseconomies); management declining to give returns on specific projects when asked on the concall. + +## 10. Cash returns: is the ROIC real + +``` +CROIC = FCF ÷ invested capital (state which capex definition) + or (CFO − maintenance capex) ÷ invested capital +FCF conversion = FCF ÷ NOPAT +``` + +Accounting ROIC can be inflated by revenue recognised ahead of cash, capitalised operating costs, understated depreciation, or a working-capital build that never unwinds. Cash returns are the audit. + +- Compare **5-year average CROIC with 5-year average ROIC**. A persistent gap of more than a few points needs an explanation, and "we are investing for growth" only qualifies if the growth capex is separately identifiable. +- **CFO ÷ net income above 1.0 on a rolling 3–5 year basis** is the baseline; sustained below 0.8 is a serious signal (`references/03-earnings-quality.md`). +- For genuinely growing companies, FCF conversion is legitimately depressed by growth capex and working capital. Separate maintenance from growth capex — depreciation is a crude floor for maintenance — before drawing any conclusion. +- **Accrual ratio** = (NOPAT − FCF) ÷ average invested capital. Rising across several years means an increasing share of the reported return exists only on paper. + +**Red flags:** ROIC persistently and materially above CROIC; conversion deteriorating while reported margins improve; capitalised development costs or capitalised interest growing faster than revenue. + +## 11. Tangible versus total capital: the goodwill effect + +Compute ROIC both ways for any company that has made acquisitions. + +- **Return on tangible invested capital** (goodwill and acquired intangibles excluded) = the economics of the operating business. +- **ROIC on total capital** (goodwill included) = the return on what shareholders actually paid, acquisition premiums and all. + +The gap is a direct measure of capital-allocation quality. A serial acquirer can run a 40% return on tangible capital and a 9% return on total capital: the businesses are good, the prices paid were not. Roll-ups habitually headline the tangible figure. + +Check: goodwill + acquired intangibles as a % of invested capital; the trend in the gap over 5–10 years (widening means premiums rising or acquired performance falling); the history of goodwill impairments, each of which is documentary evidence of overpayment; and whether the company's own "return on capital" disclosure quietly uses the tangible base. + +## 12. Consistency and durability across a full cycle + +One year's ROIC tells you almost nothing. Pull **7–10 years minimum**, spanning at least one genuine downturn, and compute: + +| Statistic | What it tells you | +|---|---| +| Mean and median ROIC | Central tendency — prefer the median where one year is extreme | +| Standard deviation / coefficient of variation | Volatility of returns is the quantitative fingerprint of cyclicality or a fragile competitive position | +| **Minimum (trough) ROIC** | The honest floor of the business and the best single predictor of downside. A company whose worst year is 14% is a different animal from one whose worst year is −3%, whatever their averages | +| Years with ROIC > WACC out of 10 | Value creation is a habit, not an event | +| Peak-to-trough drawdown in ROIC | How much of the return is cyclical rent rather than franchise | +| Trend line through the series | Structural improvement, stability, or slow erosion | + +Durable, high, low-volatility returns are the strongest quantitative evidence that a moat exists. Cross-check against the qualitative moat assessment in `references/02-core-factors.md` — if the narrative claims a widening moat and the ROIC has fallen for six years, the numbers win. + +**Red flags:** returns clearing WACC only at the top of the cycle; one exceptional year carrying the whole average; no history through a real downturn (recent IPO, post-restructuring, or a business model younger than the last recession); each cycle peaking lower than the last — structural decline dressed as cyclicality. + +## 13. Normalisation: what the mid-cycle return actually is + +Reported returns are one point in a cycle plus whatever one-offs landed that year. Capitalise sustainable earning power, not the snapshot. + +1. **Strip non-recurring items** from NOPAT: restructuring, litigation settlements, disposal gains and losses, impairments, insurance recoveries, translation effects, one-off incentives. List them; do not silently delete them. +2. **Normalise tax** to a sustainable cash rate (§3). +3. **Mid-cycle the margin.** For cyclicals use a multi-year average realised price or spread rather than the current one — an average GRM for a refiner, mid-cycle spreads for a steel producer, a through-cycle credit cost for a lender. Applying spot economics to a cyclical produces the classic trap: lowest P/E and highest ROCE precisely at the top. +4. **Quantify the gap** between reported and normalised ROIC and explain it in one line. +5. **Audit the company's own adjustments.** If management excludes a charge every year for five years, it is a recurring cost of doing business. Recompute without their adjustments and compare. + +**Red flags:** returns dependent on a booming end-market or a commodity price; "one-time" items that recur annually; normalised ROIC materially below reported; company-defined adjusted metrics that only ever exclude unfavourable items; a definition of "adjusted" that changed mid-period (`references/07-forensic-red-flags.md`). + +## 14. Peer and cross-cycle benchmarking + +Absolute return levels mean nothing. Benchmark twice, always. + +**Against peers** (build the set with `references/10-peer-set.md`): + +- Use the **same cycle window** and aligned fiscal years for every company. +- **Normalise the accounting before ranking.** Lease presentation (IFRS vs US GAAP), R&D capitalisation policy, revaluation, goodwill history and consolidation scope each move ROIC by several points. Ranking un-normalised figures produces confident nonsense. +- Report the **percentile rank** on ROIC, margin and turnover *separately* — that immediately shows whether the company's advantage is a margin story or a turnover story. +- Watch the **trend in relative rank**, which matters more than the level. A company moving from third quartile to first is a different investment from one drifting the other way at the same absolute ROIC. + +**Against its own history:** spread versus its own 5- and 10-year average ROIC, and the same for margin and turnover independently. A company can beat its peers while decaying against itself — a sector in structural decline, which the peer comparison alone would miss entirely. + +**Red flags:** a peer set containing differently structured or differently regulated businesses; below-peer returns explained away by management narrative; apparent outperformance that vanishes once leverage and accounting policy are equalised. + +## 15. Fade rate and the competitive advantage period + +High returns attract capital, and capital compresses returns. Excess returns fade toward the cost of capital across most industries, and the *rate* of that fade is one of the largest drivers of intrinsic value — usually larger than next year's growth rate, which is where almost all attention goes. + +Assess: + +- **The firm's own persistence.** How many consecutive years has ROIC exceeded WACC, and is the spread widening or narrowing? A long, stable record is real evidence. +- **The industry fade pattern.** Some structures resist fade for decades (network effects, regulated monopolies, entrenched distribution, high-switching-cost software, brands in low-innovation categories). Others fade in three years (commodity manufacturing without a cost advantage, hardware, undifferentiated services). +- **The reinvestment runway.** A 25% ROIC on a capital base that cannot grow is worth far less than a 20% ROIC with a decade of reinvestment ahead. Runway × ROIIC is the compounding engine. +- **What breaks it.** Name the specific entrant, technology, regulation or input shift that would compress the return, and what you would observe first. + +Then make the assumption **explicit** in valuation (`references/06-valuation.md`): state the competitive advantage period you are using and fade ROIC toward WACC beyond it. A DCF holding today's ROIC constant into perpetuity assumes the company defeats competition forever — usually the single largest source of overpayment. + +**Red flags:** implicit assumption of permanently high returns with no identifiable moat; excess returns already fading while the narrative claims the opposite; well-capitalised entrants arriving; industry-wide return compression visible across the whole peer set. + +## 16. Segment and divisional returns + +Consolidated ROIC is an average, and averages hide the actual decision. + +- Compute **ROCE or ROIC per segment**: segment EBIT ÷ segment capital employed (segment assets − segment operating liabilities). **India:** Ind AS 108 disclosure usually includes segment assets *and* liabilities, so segment capital employed is directly computable — use it. **US:** ASC 280 requires segment assets only where regularly reviewed by the chief operating decision maker, so segment capital is often unavailable; fall back on segment margins plus disclosed capex by segment. +- Identify which segments earn **above and below group WACC**, and where **incremental capital** has gone over five years. A high-return core funding chronic losses elsewhere is the commonest form of value destruction in listed conglomerates and is entirely invisible in the consolidated ratio. +- Compare segment capex with segment returns. Capital flowing consistently to the lowest-return segment is a verdict on management (`references/08-governance.md`). +- Segment work is also where **hidden value** appears — a crown-jewel division dragged down in the consolidated number is the basis of a sum-of-the-parts case, a divestiture thesis or a demerger catalyst. + +**Red flags:** heavily aggregated or repeatedly redefined segments; a single segment carrying the entire group's returns; loss-making units retained indefinitely with no credible turnaround plan; segment reporting that changed right after a division started underperforming. + +## 17. Buybacks, dividends and denominator effects + +Capital return is the other half of this domain, and it moves the denominators directly. + +- **Buybacks shrink equity, so ROE rises with zero operating improvement.** Illustration: net income 100 on equity 500 is a 20% ROE. A debt-funded buyback halves equity to 250 and interest cuts net income to 92 — ROE now reads 36.8% while ROIC is unchanged or slightly lower and the balance sheet is materially riskier. **If ROE rises and ROIC does not, the improvement is financial engineering.** +- **Test the price paid.** Buybacks above intrinsic value, or at cyclical peaks, transfer value from continuing holders to sellers. Compare the average buyback price with your own valuation range and with the multiple at the time. +- **Judge payout against reinvestment ROIC, not against a payout norm.** Returning capital is accretive precisely when internal opportunities fall below WACC. A company earning 25% incremental returns should be reinvesting; one earning 6% should be distributing. The comparison is payout ratio versus ROIIC (§9). +- **Track share count and book value per share** alongside ROE. Per-share economic progress is the test that survives every denominator game. +- **India specifics:** buybacks are much less common than in the US and are often tender-offer route — check whether promoters tendered, since that is an exit dressed as capital return. Since October 2024 buyback proceeds are taxed in the shareholder's hands, which has pushed many Indian companies back toward dividends; compare **total shareholder yield** (dividends + net buybacks), never either alone. + +**Red flags:** ROE boosted by buybacks that hollow out or eliminate book equity; debt-funded buybacks raising leverage and ROE together; management guiding on EPS while book value per share stalls; dividends funded by borrowing while ROIC sits below WACC. + +## 18. Fourteen ways a reported ROIC lies + +Run this scan before trusting any return figure, including your own. + +1. **Write-offs shrank the denominator** — cumulative impairments not added back, so past destruction now flatters returns. +2. **Buybacks shrank equity** — ROE up, ROIC flat (§17). +3. **Leases off the denominator** — pre-IFRS 16 / pre-ASC 842 history, or a US GAAP filer compared with an IFRS filer on EBIT-based ROCE. +4. **R&D and brand expensed** — the principal asset is missing from capital entirely. +5. **Idle cash left in** — depresses ROIC and hides a capital-allocation problem; or quietly netted out without disclosure. +6. **CWIP carried with no earnings yet** — depresses returns mid-expansion; excluding it without saying so inflates them. +7. **Fully depreciated asset base** — a superb net-book return that could never be earned on replacement cost. +8. **Associates and JVs mismatched** — income in the numerator, investment out of the denominator, or the reverse. +9. **Minority interests mismatched** — 100% of a subsidiary's profit against a partial ownership claim. +10. **One-off gains in the numerator** — disposals, insurance recoveries, tax credits. +11. **Tax-rate breaks** — India's 115BAA election, the US 2018 cut, expiring holidays. After-tax series are not continuous through these. +12. **Year-end rather than average capital** — especially distorting in an acquisition year. +13. **SBC-heavy models** — a real cost that creates no capital, so ROIC is structurally overstated versus a cash-paying competitor. +14. **Off-balance-sheet structures** — securitised receivables, JV-held assets, project SPVs, supplier finance. Earnings consolidated, capital not. + +Each of these is a reason to state your definition in the report and apply it identically across the peer set. + +## 19. India versus US conventions + +| Topic | India (NSE/BSE, Ind AS) | US / global (10-K, GAAP/IFRS) | +|---|---|---| +| **Default return metric** | **ROCE, pre-tax**: EBIT ÷ (total assets − current liabilities). The screener.in and sell-side convention, and *not* comparable to after-tax ROIC — always say which you quote | **ROIC, after-tax**: NOPAT ÷ invested capital. Many filers now disclose their own version in the 10-K or at investor days — read their definition before using their number | +| **ROE denominator** | "Net worth" per Schedule III: equity share capital + other equity, excluding revaluation surplus where identifiable and excluding minority interest | Total stockholders' equity attributable to the parent | +| **Leases** | Ind AS 116 from FY2020 — on balance sheet, rent split into depreciation and interest, so **EBIT stepped up at transition**. Pre-FY2020 years must be adjusted before any 10-year ROCE comparison | ASC 842 from 2019 — right-of-use asset and liability on balance sheet, but **operating-lease cost remains a single operating expense**, so US EBIT is lower than an IFRS filer's for identical economics | +| **Tax** | Section 115BAA (~25.2% effective) vs the older ~34.9%; 115BAB for new manufacturing; MAT credits; SEZ and area-based holidays that expire | 21% federal statutory since 2018 (from 35%), plus state taxes, GILTI/FDII, and large valuation-allowance swings | +| **Goodwill** | Not amortised under Ind AS 103; impairment-tested. Amalgamations under NCLT-approved schemes can adjust goodwill directly against reserves — read the scheme, because capital can leave the denominator without touching the P&L | Not amortised since 2001; impairment-only for filers | +| **Capital work-in-progress** | Schedule III mandates **CWIP ageing** and disclosure of projects overdue or over budget — a direct read on whether carried capital will ever earn | Construction in progress sits inside the PP&E note, generally with less granularity | +| **Related-party capital** | Section 186 loans/guarantees/investments to group entities; CARO 3(iii) on loans granted and 3(ix) on end-use of borrowings — the standard route by which capital leaves the listed entity's operating base | Related-party disclosure under ASC 850; typically far smaller in scale for large filers | +| **Basis of accounts** | **Consolidated vs standalone matters enormously.** For any group with subsidiaries, standalone ROE is meaningless. State which you used | Consolidated by default | +| **Units** | ₹ crore / lakh — state the unit on every figure | Millions / billions | +| **History sources** | Annual report 5-year highlights, BSE/NSE filings, screener.in (check its ROCE definition), CARO annexure, quarterly segment data | 10-K financial statements and MD&A, EDGAR full-text search, segment note (ASC 280), earnings supplements | +| **Management dialogue** | The **concall is the highest-value source**: whether management guides to ROCE, what hurdle rate they apply to new projects, what returns recent capex actually earned. Indian managements frequently state explicit ROCE targets — hold them to it year over year | Investor days and MD&A; some firms publish an explicit ROIC target and hurdle rate. The proxy (DEF 14A) reveals whether incentive pay is tied to ROIC, which is the real hurdle | +| **Governance overlay** | Promoter holding and pledging, promoter-group related-party flows and holdco discounts determine whether the reported return actually accrues to minority shareholders | Dual-class structures, controlled-company exemptions, VIE structures for China-domiciled ADRs where the listed entity may not own the operating assets at all | + +## 20. What to put in the report + +- A **10-year table**: ROCE/ROIC, ROE, NOPAT margin, capital turnover, CROIC — with the trough year highlighted. +- Your **invested-capital definition** in one sentence, the adjustments made, and their effect in percentage points. +- **ROIC versus a WACC range**, the spread in basis points, and economic profit in absolute currency. +- The **DuPont decomposition** for the company and 2–3 peers, side by side. +- **ROIIC over 3 and 5 years**, beside the historical average ROIC and WACC, with a one-line verdict on whether reinvestment compounds or dilutes. +- **Reported versus normalised** ROIC and what drives the gap. +- The **fade assumption** carried into valuation, stated explicitly. +- **Segment returns** and where incremental capital went, wherever disclosure allows. + +## Checklist + +- [ ] Run the sector gate first — confirm return-on-capital arithmetic is even defined for this business. +- [ ] Build NOPAT on a normalised cash tax rate; do not add back SBC; match non-operating income to non-operating assets. +- [ ] Build invested capital by both the operating and financing routes and reconcile them. +- [ ] Capitalise leases, state the R&D treatment, add back cumulative impairments, strip excess cash and non-operating investments — and note each adjustment's effect. +- [ ] Use average (or beginning-of-period) capital, never year-end, especially in an acquisition year. +- [ ] Compute ROIC including and excluding goodwill; report the gap for any acquirer. +- [ ] Estimate WACC as a range from current market inputs; report ROIC − WACC in bps and economic profit in currency. +- [ ] Never quote ROE without the 3-step DuPont; run the 5-step where tax or interest burden has moved. +- [ ] Split the return into margin and turnover and say which one drives it versus peers. +- [ ] Compute ROIIC over 3 and 5 years against average ROIC and WACC — the forward-looking signal. +- [ ] Cross-check reinvestment rate × ROIIC against management's growth guidance. +- [ ] Compare CROIC with ROIC over five years and explain any persistent gap. +- [ ] Pull 7–10 years; report mean, volatility, **trough** ROIC, and years above WACC. +- [ ] Normalise for one-offs and cycle position; state reported versus normalised. +- [ ] Benchmark twice — against an accounting-normalised peer set and against the company's own 5–10 year record. +- [ ] State the fade assumption / competitive advantage period explicitly and carry it into valuation. +- [ ] Compute segment returns wherever disclosure allows and check where incremental capital is going. +- [ ] Check whether rising ROE is matched by rising ROIC; if not, name the financing action responsible. +- [ ] Run the fourteen-lies scan (§18) before trusting any return figure, including your own. +- [ ] State metric definition, basis (consolidated/standalone), currency, units and period beside every number. diff --git a/finance/skills/stock-analysis/references/06-valuation.md b/finance/skills/stock-analysis/references/06-valuation.md new file mode 100644 index 00000000..61544132 --- /dev/null +++ b/finance/skills/stock-analysis/references/06-valuation.md @@ -0,0 +1,426 @@ +# Valuation and margin of safety + +Use this when: business quality, earnings quality, balance sheet and returns are already established, and you need to decide what the business is worth, what the market is already paying for, and how much room for error the price leaves. + +Valuation is the last stage, never the first screen. A multiple is a compression of everything you have already established — growth, durability, capital intensity, return on incremental capital, accounting honesty — into a single number, and it is unreadable until those are known. The governing principle applies with full force: a P/E of 12 means nothing until you know the sector, the cycle position, and the company's own ten-year band. For banks, insurers, REITs, miners, shipping and holding companies the standard multiples are undefined, inverted, or actively misleading, and **the sector playbook overrides every default in this file**. + +## Contents + +1. [Order of operations](#order-of-operations) +2. [The multiple set](#the-multiple-set) +3. [Where each multiple breaks](#where-each-multiple-breaks) +4. [Building the enterprise value bridge](#building-the-enterprise-value-bridge) +5. [Deriving the discount rate](#deriving-the-discount-rate) +6. [Building the DCF](#building-the-dcf) +7. [Reverse DCF — the central discipline](#reverse-dcf--the-central-discipline) +8. [Earnings yield versus bond yield](#earnings-yield-versus-bond-yield) +9. [Valuation versus its own history](#valuation-versus-its-own-history) +10. [Valuation versus peers](#valuation-versus-peers) +11. [SOTP, private market value and replacement cost](#sotp-private-market-value-and-replacement-cost) +12. [Margin of safety](#margin-of-safety) +13. [Quality trap versus value trap](#quality-trap-versus-value-trap) +14. [Scenarios, expected value and IRR decomposition](#scenarios-expected-value-and-irr-decomposition) +15. [Catalyst, edge and what is already discounted](#catalyst-edge-and-what-is-already-discounted) +16. [Sector overrides](#sector-overrides) +17. [India (Ind-AS/NSE-BSE) vs US/global conventions](#india-ind-asnse-bse-vs-usglobal-conventions) +18. [Errors that ruin this section of the report](#errors-that-ruin-this-section-of-the-report) +19. [Checklist](#checklist) + +--- + +## Order of operations + +Run valuation in this sequence. Out of order, it becomes a rationalisation of the quoted price — the most common failure mode in this entire skill. + +1. **Check the sector playbook first.** If it prescribes a method (P/ABV against ROE for banks, P/EV for life insurers, AFFO yield and cap-rate spread for REITs, mid-cycle EV/EBITDA and P/NAV for miners, EV/EBITDAR for airlines), use it and suppress the generic multiples it declares inapplicable. +2. **Normalise the denominator before touching the numerator.** Strip one-offs, normalise tax, decide whether earnings sit at a cyclical peak or trough, and state whether the figure is reported (Ind-AS/GAAP/IFRS) or adjusted, and why. +3. **Build the EV bridge once**, properly, and reuse it in every enterprise multiple. +4. **Run the reverse DCF before building your own forecast.** Find out what the price already assumes while you are still neutral. Once you have written a forecast you will unconsciously defend it. +5. **Then triangulate:** multiples versus own history, versus peers, a forward DCF with sensitivity, and at least one asset- or transaction-based cross-check. +6. **Convert to a scenario table** with explicit probabilities, a probability-weighted value, and an IRR decomposition. Report a range, never a point. +7. **Apply the margin of safety** against the conservative case, sized to the uncertainty of the estimate — not to how much you like the story. + +--- + +## The multiple set + +Ranges are **indicative only**. They move with market, sector, cycle, interest-rate regime and accounting period, and an Indian multiple is not directly comparable to a US one because the currency, the risk-free rate and the nominal growth rate all differ. **The company's own 5–10 year band and its true peer set override every number in this column.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Trailing P/E** | Price ÷ trailing-12m diluted EPS, after minority interest. | Depends entirely on ROIC and growth; 12–20x is unremarkable for a mature business in either market. | The most quoted and most distorted multiple. Only interpretable next to the normalised version. | +| **Forward P/E** | Price ÷ next-12m consensus or your own EPS. | Should sit below trailing P/E if earnings are growing. | Prices the year ahead, but inherits consensus optimism. Check estimate dispersion and revision direction. | +| **Normalised / mid-cycle P/E** | Price ÷ EPS at mid-cycle margins and a full tax rate, modelled across a complete cycle. | Compare to the company's own normalised history, not an absolute band. | The only P/E that survives a cyclical business. Prevents anchoring to peak or trough earnings. | +| **CAPE / Shiller P/E** | Price ÷ 10-yr average inflation-adjusted EPS. | Use versus its own history and the index's. | Cycle-proof at index level; at single-stock level it penalises genuine structural growth — use for mature cyclicals only. | +| **GAAP-vs-adjusted EPS gap** | (Adjusted EPS − reported EPS) ÷ reported EPS. | <10% and not widening. | A widening gap is an earnings-quality finding dressed up as a valuation input. | +| **Earnings yield (E/P)** | Inverse of P/E; better, FCF ÷ market cap. | Above the local 10-yr sovereign yield by a sensible premium. | Makes the equity directly comparable to bonds and to the company's own cost of debt. | +| **P/B** | Price ÷ book value per share. | Only meaningful with ROE alongside; justified P/B ≈ (ROE − g) ÷ (COE − g). | Anchors financials and asset-heavy businesses. Near-meaningless for asset-light compounders. | +| **P/TBV (P/ABV)** | Price ÷ (equity − goodwill − intangibles); for lenders also net of net NPAs (adjusted book). | With ROTCE/RoE above cost of equity, a premium is earned. | Strips acquisition accounting and, for banks, the reserves the market disbelieves. | +| **EV/EBITDA** | EV (from the bridge) ÷ EBITDA. | 6–12x common for mature industrials; capital intensity drives the band. | Capital-structure and tax neutral; the language of M&A. Blind to capex. | +| **EV/EBIT** | EV ÷ EBIT after real depreciation. | Roughly 10–16x for a decent mature business. | Harder to game than EBITDA because depreciation proxies the cost of keeping the asset base alive. Prefer it for anything capital-intensive. | +| **EV/(EBITDA − capex)** | EV ÷ (EBITDA − total capex), and ÷ (EBITDA − maintenance capex). | Compare against EV/EBITDA; a wide gap is the whole story. | Exposes the business whose EBITDA is consumed by the plant that produced it. | +| **EV/Sales** | EV ÷ revenue. Decompose: EV/Sales ÷ steady-state EBIT margin = implied EV/EBIT. | Only via the implied-margin decomposition. | The fallback when earnings are negative or unrepresentative — and worthless unless you state the margin it implies. | +| **P/S** | Market cap ÷ revenue. | As above; equity-level, so valid only for near-unlevered companies. | Sales are the hardest line to manipulate, so P/S survives trough margins. It does not survive a structurally low-margin business. | +| **PEG** | P/E ÷ expected EPS CAGR (%). | <1 classically cheap; treat 0.8–1.5 as a wide neutral band. | Links price to growth. Ignores growth's capital intensity and durability — always pair with incremental ROIC. | +| **EV/EBIT-to-growth** | EV/EBIT ÷ EBIT CAGR. | Use versus peers, not absolutely. | The capital-structure-neutral version of PEG; avoids PEG's leverage distortion. | +| **FCF yield** | FCF ÷ market cap, FCF = CFO − total capex, with SBC treated as a cost. | 4–8% for a mature business; a genuine high-reinvestment compounder can legitimately show 1–2%. | The truest "what an owner earns" measure and the hardest to manipulate. | +| **FCF/EV** | Unlevered FCF ÷ EV. | Compare directly to WACC. | Removes leverage distortion, making the yield comparable across capital structures. Below WACC, the business is not covering its capital cost. | +| **Owner-earnings yield** | (Net income + D&A − maintenance capex − working-capital needs − SBC) ÷ market cap. | Within a few points of FCF yield across 3–5 years. | Separates reported profit from distributable profit. The gap is the finding. | +| **FCF conversion** | FCF ÷ net income, cumulative over 3–5 years. | 70%+ for a mature business. | A valuation input, because it decides whether the E in P/E is spendable. | +| **Dividend yield** | DPS ÷ price. | Sector- and market-dependent; Indian large caps typically yield less than US peers. | A component of return and a discipline on capital allocation — and a trap when the market is pre-pricing a cut. | +| **Payout ratio** | DPS ÷ EPS, and dividends ÷ FCF. | Below ~70% of FCF for a sustainable dividend. | The FCF version is the one that matters; the EPS version misses the capex. | +| **Total shareholder yield** | Dividend yield + net buyback yield (net of SBC issuance) + net debt-paydown yield. | 4%+ for a mature cash generator. | Captures the whole return of capital, including the buyback that merely offsets dilution and therefore returns nothing. | +| **Multiple percentile vs own history** | Current multiple's percentile / z-score in its own 5–10 yr distribution. | Below the 50th percentile with unchanged fundamentals is the interesting case. | Own history is the cleanest comparable: same model, same accounting, same disclosure. | +| **Implied ERP (yield gap)** | Earnings or FCF yield − local 10-yr sovereign yield. | Judge against that same spread's own history, never against another country's. | Places the multiple inside the prevailing rate regime instead of in a vacuum. | +| **EV per physical unit** | EV ÷ tonne, bed, key, subscriber, MW, sq ft, MHz, dwt. | Versus greenfield replacement cost and recent transactions. | The cross-check that depends on no accounting at all. | +| **Price / intrinsic value** | Price ÷ conservatively estimated fair value. | ≤0.70 for average businesses; ≤0.80 for highly predictable ones. | The margin of safety, stated as a number rather than a feeling. | + +--- + +## Where each multiple breaks + +Every multiple has a situation in which it reliably lies. Establish which one you are in before quoting it. + +| Multiple | Fails when | What it does to you | Use instead | +|---|---|---|---| +| **P/E** | Earnings sit at a cyclical peak, contain one-offs, or are negative. | Prints its lowest reading at the top of a commodity cycle — P/E is *inverted* for cyclicals. A miner or commodity chemical maker at 5x is usually a sell; at 30x, often a buy. | Mid-cycle normalised EPS; P/B against mid-cycle ROE; EV per tonne. | +| **P/E** | Capital structure differs across the peer set. | Leverage flatters EPS and compresses P/E, so the most fragile company screens cheapest. | EV/EBIT. | +| **P/E** | EPS growth is buyback-driven. | Mistakes share-count shrinkage for business growth. | Net income growth and FCF per share, with the buyback price checked against your own value range. | +| **P/B** | The business is asset-light, equity is negative after buybacks, or book carries goodwill from overpriced deals. | Meaningless or undefined; a serial acquirer looks "cheap on book" precisely because it overpaid. | P/TBV with ROTCE; for asset-light names ignore book entirely and use FCF yield. | +| **P/B (financials)** | Asset marks are stale or reserves inadequate. | A bank below book is cheap only if the book is real. The market usually prices a credit event before the auditor recognises it. | P/ABV net of net NPAs, stressed-book scenarios. `sectors/banks.md` | +| **EV/EBITDA** | Capital intensity is high, EV omits leases/pensions/minorities, or "adjusted EBITDA" carries recurring add-backs. | Understates the true purchase price and overstates the cash. SBC and annual "restructuring" added back is the classic. | EV/EBIT, EV/(EBITDA − capex), and a rebuilt EV bridge. | +| **EV/anything (banks, NBFCs, insurers)** | Debt is raw material, not financing. | Enterprise value has no meaning; net debt is not a claim to add back. | P/B, P/ABV, RoE vs COE, P/EV. Suppress every EV multiple. | +| **EV/Sales, P/S** | The implied steady-state margin is never stated. | Any price can be justified by assuming a margin the industry has never achieved. | Always decompose: EV/Sales ÷ target margin = implied EV/EBIT, then ask whether that margin is attainable. | +| **PEG** | Growth is a one-year spike, or the company is a no-growth cash cow. | Rewards a peak-growth year; penalises a genuinely cheap steady compounder. | FCF yield + growth; EV/EBIT-to-growth alongside incremental ROIC. | +| **FCF yield** | The year contains a working-capital release, an asset sale, or deferred capex. | A single year of "free cash" that is really underinvestment or stretched payables. | 3–5 year average FCF; split maintenance from growth capex; check payable days. | +| **Dividend yield** | The yield rose because the price fell. | The classic yield trap; the market pre-prices the cut months before the board announces it. | Payout as % of FCF, coverage, and balance-sheet capacity to sustain it. | +| **P/E on REITs, InvITs** | Depreciation is charged on appreciating property. | Earnings are structurally understated; P/E is nonsense. | AFFO yield, NOI cap-rate spread, NAV. `sectors/realestate-reit.md` | +| **Any multiple straddling FY20 (India) / 2019 (IFRS, US)** | Ind AS 116 / IFRS 16 / ASC 842 capitalised leases; India's s.115BAA cut the tax rate. | EBITDA, EPS and EV all stepped up for non-operating reasons. The 10-year multiple band is broken at that seam. | Restate the pre-transition years before plotting any historical multiple range. | + +--- + +## Building the enterprise value bridge + +Most "cheap on EV/EBITDA" findings are arithmetic errors in EV. Build the bridge explicitly, present it as a table in the report, and reuse the same bridge everywhere. + +``` + Fully diluted market cap ++ Total debt (short-term + long-term + current maturities) ++ Capitalised lease liability ++ Preference shares / CCPS at redemption or conversion value ++ Non-controlling (minority) interest ++ Net underfunded pension / OPEB / gratuity, net of deferred tax ++ Contingent consideration, earn-outs, put options over NCI ++ Other debt-like items +− Surplus cash and equivalents +− Marketable securities and liquid investments +− Market or fair value of non-consolidated stakes (associates, JVs, listed holdings) += Enterprise value +``` + +**Fully diluted share count.** Treasury-stock method for options and RSUs; if-converted for convertibles (either add the converted shares *or* add the bond to debt and interest back to earnings — never both, never neither); warrants; unvested and unexercised ESOP pools from the share-capital note. *India:* compulsorily convertible preference shares and debentures are common in recently listed new-age and PE-funded companies — convert them. *US:* SBC-driven dilution in technology can run 2–4% a year, so a count lifted from the 10-K cover understates the claim on the business. + +**Cash: surplus, not total.** Only cash the business could actually distribute is deductible. Carve out (a) operating cash, roughly 2–5% of sales, (b) cash trapped where repatriation triggers tax, (c) regulatory, margin, escrow and customer-float balances (exchanges, brokers, payment companies — see `sectors/exchanges-payments.md`), (d) cash earmarked for an announced acquisition or declared dividend. *India:* surplus treasury usually sits in "current investments" as liquid mutual funds rather than in "cash and cash equivalents" — read both lines. If you deduct the investments, remove their yield from EBIT as well, or you double-count the treasury. + +**Leases.** Post-IFRS 16 / Ind AS 116 / ASC 842 the liability is on the balance sheet: add it. For pre-transition years, capitalise at the present value of committed rentals, or 8x annual rent as a rough proxy, so the historical EV series is continuous. Retail, QSR, aviation, hospitality and logistics are where omitting this changes the conclusion, not the decimal. + +**Minorities and associates are two halves of one discipline.** If consolidated EBITDA includes 100% of a 60%-owned subsidiary, add the minority interest to EV — ideally at market value or at the multiple you are applying, not at book. Conversely, associates and JVs are equity-accounted, contributing profit but no EBITDA: deduct their value from EV *and* strip the share of associate profit out of your earnings figure. Doing one without the other is the most common silent error in Indian conglomerate and holdco analysis. + +**Pensions and gratuity.** Add the defined-benefit obligation net of plan assets, tax-effected. Material in older US and European industrials; in India the gratuity and leave-encashment provisions are usually smaller but must still be read in the employee-benefits note. A pension deficit approaching the market cap makes the equity a residual claim on an insurance liability, not on the operating business. + +**Other debt-like items to hunt for:** reverse factoring and supply-chain finance hidden in trade payables, receivables securitised with recourse, asset-retirement and mine-closure obligations, litigation and tax provisions with a probable outflow, deferred acquisition consideration, promoter and related-party loans, perpetual instruments (AT1 for banks), and take-or-pay or capacity commitments in the contingent-liabilities note. + +**The pairing rule.** An equity claim belongs in a numerator only with an equity metric; an enterprise claim only with an enterprise metric. P/EBITDA and EV/net-income are meaningless. If minority interest sits in EV, the earnings figure must be pre-minority. + +--- + +## Deriving the discount rate + +Never take a WACC from a screener. Derive it, state every input, and date it — a discount rate is a statement about a specific market on a specific day. + +``` +Ke = Rf + β × ERP + CRP (+ any size / illiquidity premium) +WACC = Ke × E/(D+E) + Kd × (1 − t) × D/(D+E) +``` + +- **Risk-free rate.** Use the long government bond yield *in the currency of the cash flows*, roughly duration-matched. India: the 10-yr G-Sec. US: the 10-yr Treasury. For a sovereign carrying real default risk, subtract the country's default spread from its local bond yield to get a true risk-free rate, then add the country risk premium back explicitly at the equity level — otherwise the same risk is counted twice. +- **Equity risk premium.** Use a consistently sourced mature-market ERP; 4.5–5.5% is the usual working range. Prefer an implied (forward-looking) ERP over a long historical average when rates have moved sharply, and use the *same* ERP for every company in a comparison. +- **Country risk premium.** For emerging markets, CRP ≈ sovereign default spread (from rating or CDS) × the ratio of equity to bond volatility, typically 1.0–1.5x. For India this has historically added roughly 2–3 percentage points. Apply CRP by **revenue exposure, not listing venue**: an Indian-listed IT exporter earning 80% of revenue in the US carries far less India risk than a domestic cement maker listed alongside it. +- **Beta.** Prefer a bottom-up beta — unlever peer betas, average, relever at the target capital structure: `βL = βU × (1 + (1 − t) × D/E)`. Regression betas for Indian mid- and small-caps are dominated by illiquidity and index composition and are close to noise; if you must use one, apply the Blume adjustment (`0.67 × raw + 0.33 × 1.0`) and disclose the window and index. A sub-1.0 beta on a highly operationally leveraged cyclical is a data artefact, not a finding. +- **Cost of debt.** Use the yield to maturity on traded bonds, or build it synthetically: risk-free + a default spread implied by interest coverage or credit rating. Do **not** use the historical average interest cost from the P&L — it reflects debt raised in a different rate regime and understates the marginal cost of new borrowing. Tax-effect at the marginal, not the effective, rate, and only to the extent interest is actually deductible. +- **Weights at market value**, using the target or sustainable capital structure rather than a temporarily distressed or temporarily cash-rich one. +- **Size and illiquidity premia** are contested. Adding 200bps to WACC to express "this is a risky small-cap" is crude and buries the judgement inside a compounding exponent. Prefer conservative cash flows plus a wider margin of safety. + +**The currency-consistency rule.** Discount nominal INR cash flows at a nominal INR rate; nominal USD cash flows at a nominal USD rate; real cash flows at a real rate. Never mix. An INR WACC is structurally several points above a USD WACC purely because of the inflation differential — and therefore an INR terminal growth rate of 4% is *deeply* conservative where a USD 4% would be aggressive. To value a cross-border business, either (a) model in the functional currency and translate the resulting value at spot, or (b) translate the cash flows year by year at forward rates built from the inflation differential, `FX_t = FX_0 × ((1+i_local)/(1+i_foreign))^t`, and discount at the foreign rate. Both are correct; half of each is not. Where the company's revenue and its debt sit in different currencies, that mismatch is a risk to model in the scenarios, not a rate to average. + +**Do not double-count risk.** If the bear scenario already models the asset being expropriated, do not also add a political-risk premium to WACC. Risk belongs either in the cash flows or in the rate — choose one and say which. + +--- + +## Building the DCF + +``` +FCFF = EBIT × (1 − cash tax rate) + D&A − capex − ΔNWC → discount at WACC → EV +FCFE = FCFF − interest × (1 − t) + net borrowing → discount at Ke → equity value +``` + +- **Set the forecast horizon equal to the competitive advantage period**, typically 5–10 years, and only as long as you can name a mechanism that keeps ROIC above WACC. Beyond it, fade incremental ROIC toward the cost of capital. A model in which excess returns never fade has assumed its own conclusion. +- **Terminal value, done properly:** `TV = NOPAT_{n+1} × (1 − g/ROIC_terminal) ÷ (WACC − g)`. The `g/ROIC` term is the reinvestment that growth must be paid for; a terminal value growing at 5% forever with no reinvestment is free money and is wrong. Cap `g` at long-run **nominal** GDP in the same currency. +- **Cross-check the terminal value against an exit multiple** and report the implied exit EV/EBIT. If perpetuity growth implies an exit multiple above today's or above the historical median, the model is smuggling in a re-rating. +- **Report the terminal-value share of present value.** Above 75–80% means the DCF is a terminal-value assertion with a spreadsheet attached. Say so rather than hiding it. +- **Treat SBC as a cash cost** (or model the resulting dilution). Adding it back and calling the result FCF overstates owner returns by exactly the amount transferred to employees. +- **Use mid-year discounting** where cash flows arrive evenly; it typically lifts value 3–5% and is the honest convention. +- **Bridge EV back to equity value** with the same bridge in reverse — EV − debt − leases − minorities − pension deficit + surplus cash + non-consolidated stakes — then divide by the *diluted* count. +- **Sensitivity is not optional.** Produce a two-way table of WACC (±150bps in 50bp steps) against terminal growth (±100bps), and a second on steady-state EBIT margin. Report the spread of outcomes, not the centre cell. If a 50bp WACC change moves value 30%, the DCF is a weak instrument for this company and the multiple and asset cross-checks must carry more weight — say that explicitly. +- **Reconcile to reality.** Compute implied terminal-year revenue, market share, reinvestment rate and ROIC, and check them against history, addressable-market size and base rates. A model that quietly has the company taking 60% of its market has an unstated assumption. + +--- + +## Reverse DCF — the central discipline + +Run this **before** your own forecast. Invert the model: hold the current price fixed and solve for the operating performance required to justify it. + +Solve for and report as a table: + +- **Implied revenue CAGR** over the forecast horizon +- **Implied steady-state EBIT (or FCF) margin** +- **Implied competitive-advantage period** — how many years of above-WACC returns are baked in +- **Implied terminal ROIC** +- **Breakeven growth** — the rate at which the stock returns exactly the cost of capital + +Then decompose the price a second way: `PVGO = market cap − (normalised NOPAT ÷ WACC)`. That splits the price into the value of current operations continued forever and the value of growth not yet delivered. If 70% of the price is PVGO, you are not buying a business, you are buying a forecast — and the report should say exactly that. + +**Judge the implied numbers against base rates, not against the story.** Very few companies of any size sustain 20%+ revenue growth for a decade; excess ROIC typically fades over 5–15 years; 1,000bps of sustained margin expansion is rare outside a genuine platform shift. If the implied expectations already exceed management's own guidance, the market has done the extrapolating for you. Inversely, when a stable, cash-generative business is priced for permanent decline — implied growth below zero, implied ROIC collapsing straight to WACC — that is the cheap case worth investigating, and the reverse DCF is how you *find* it rather than assert it. + +This reframes the exercise from "what is it worth" (unfalsifiable) to "what must be true, and is that likely" (testable). It is also the strongest available defence against anchoring, which is precisely why it comes before your own model rather than after it. + +--- + +## Earnings yield versus bond yield + +Equities compete with bonds for capital, and the multiple that can be justified is a function of the rate regime. + +- Compute the **earnings yield (E/P)** and, better, the **FCF yield**, and set them against the local 10-yr sovereign yield. The difference is the implied equity risk premium for this stock. +- Place that spread in **its own historical distribution**. There is no universal minimum; a 200bp gap can be generous in one market and thin in another. +- **Never compare yield gaps across currencies naively.** India's higher nominal bond yield accompanies higher nominal earnings growth, so an Indian equity showing a narrower yield gap than a US equity is not thereby expensive. Compare each market's gap to its own history. This is the Fed-model critique in miniature: setting a nominal bond yield against a real earnings yield systematically flatters equities when inflation is high, so use the yield gap as a regime check, never as a fair-value model. +- **Cross-check against the company's own credit.** If its investment-grade bonds yield more than its FCF yield, the debt is the better claim on the same cash flows and the equity needs the growth to justify itself. +- **Compare earnings yield to after-tax cost of debt.** This is the arithmetic that decides whether a debt-funded buyback creates value or merely swaps balance-sheet risk for EPS. +- **Note the direction of travel.** A valuation that only works under permanently low rates is a rate bet; label it as one. A multiple set in a 1% rate world does not survive a 5% one, however good the business. + +--- + +## Valuation versus its own history + +Its own past is usually the cleanest comparable a company has: same business model, same accounting, same disclosure culture. + +- Plot **each** multiple — P/E, EV/EBIT, EV/EBITDA, P/S, P/FCF, dividend yield — against its own 5- and 10-year range. Report the **median** (not the mean) and the **current percentile or z-score**. +- Exclude periods where the multiple is undefined or absurd (loss years for P/E, transition years for lease accounting), and say which years you excluded. +- **Then answer the only question that matters: why?** A stock at the top of its band is a buy if the business genuinely re-rated — moat widened, mix shifted to higher-ROIC revenue, capital intensity fell, cyclicality reduced — and a sell if nothing changed but sentiment. Name the structural change or concede there is none. "It has always been expensive" is not an argument; it is the absence of one. +- **Decompose the last 5–10 years of shareholder return** into earnings growth + multiple change + dividend + buyback. If most of the historical return came from multiple expansion, that fuel is not available twice and forward return expectations must fall. +- **Neutralise the market.** Divide the stock's multiple by the index's (Nifty 50 / Sensex / S&P 500) to build a relative multiple series. A stock expensive against its own absolute history but cheap against its relative history is telling you the whole market re-rated, not the company. +- **Watch the accounting seams.** Lease capitalisation (FY20 India, 2019 IFRS/US), India's s.115BAA tax election, GST transition, demergers and large acquisitions all break the series. Restate or annotate; never average across a break. +- **A de-rating is not automatically an opportunity.** Test whether the multiple fell because the moat is eroding — falling incremental ROIC, rising customer churn, a new entrant — in which case the market is right and the low multiple is the new correct one. + +--- + +## Valuation versus peers + +- **Build the peer set on economics, not industry codes.** True comparables share business model, capital intensity, growth profile, customer concentration and end-market. List who is in the set and why, and demonstrate the set was not chosen to flatter the conclusion. +- **Normalise before comparing:** accounting standard (Ind-AS vs IFRS vs US GAAP), R&D capitalisation, lease treatment, SBC treatment, tax regime, consolidated vs standalone basis, and fiscal-year end. +- **Adjust for the drivers of a justified premium** — ROIC, growth, margin stability, leverage, governance. A premium must be *earned*. The disciplined version: regress peer EV/EBIT (or P/B) against ROIC and growth across 10–20 names and read the residual. The outlier versus the fitted line is the finding; the fit itself tells you how much multiple dispersion fundamentals explain at all. +- **Check the sector against itself.** Cheap relative to an expensive sector is not cheap. Plot the peer-group median multiple against its own history before drawing any conclusion from a relative discount. +- **Interrogate the discount.** Most discounts are deserved: weaker returns, worse governance, promoter overhang, lower liquidity, a structurally shrinking end market. State which applies and what would remove it. +- *India:* niche sectors often have two or three listed peers, all similarly mispriced. Use global comparables, but adjust explicitly for the cost-of-capital and nominal-growth differential — an Indian company legitimately trades at a different multiple from a US peer with identical economics because both the discount rate and nominal growth differ. Unlisted transaction multiples, QIP pricing and preferential-allotment prices are additional local evidence of what informed buyers pay. + +--- + +## SOTP, private market value and replacement cost + +Multiples and DCFs both start from the same accounting. These three cross-checks do not — which is why at least one belongs in every deep dive. + +**Sum of the parts.** Value each segment on its own appropriate method — a multiple where a clean peer set exists, a DCF where it does not — then: + +- Capitalise **unallocated corporate costs** as a negative-value stub at the same multiple, rather than ignoring them. +- Deduct **net debt, minorities and pension** at the consolidated level using the bridge above. +- Deduct **tax on disposal** wherever the thesis relies on selling an asset carried at historic cost. +- Apply a **holdco/conglomerate discount** and state whether it is structural (poor capital allocation, no intent to unlock) or temporary (a demerger is announced and dated). In India these discounts are structurally wide — 40–70% is common — and have persisted for decades. Assuming one closes is a thesis, not an adjustment. +- Report the **implied stub**: if market cap minus the value of listed stakes is near zero or negative, the operating business is being given away — genuinely interesting when the stakes are liquid and monetisable, a trap when they are not. +- Hunt for **understated assets**: land and property at historic cost, cross-holdings in listed entities, unconsolidated JVs, brands never capitalised, carry-forward tax losses (check usability — s.79 in India on ownership change, s.382 in the US), and a loss-making incubating unit whose losses mask a profitable core. + +**Private market value.** What would an informed industrial or PE buyer pay for the whole thing? Anchor on precedent transaction EV/EBITDA in the same sector and geography, including a control premium of typically 20–35%. This behaves like a floor only when the asset is genuinely acquirable — check whether it is. A 60%+ promoter holding, a golden share, a sectoral FDI cap or a regulatory-approval requirement can make a company unbuyable, and the PMV then unrealisable. + +**Replacement cost and Tobin's q.** `q = EV ÷ replacement cost of productive assets`. This is the supply-side test and the most useful valuation tool in capacity-driven industries. When q is well below 1, nobody builds new capacity, supply tightens and returns eventually recover; when q is far above 1, new supply is coming and current returns will fade — which is why a commodity producer at a low P/E and a high q is a sell, not a bargain. Use the physical denominators the industry itself uses: EV/tonne (cement, steel), EV/key (hotels), EV/bed (hospitals), EV/MW (power, data centres), EV/subscriber and EV/MHz (telecom), EV/acre or per saleable sq ft (real estate), EV/dwt or broker vessel values (shipping). Compare against current greenfield build cost and recent asset transactions. In deeply distressed situations, run **liquidation value** and net current asset value as the true floor, haircutting receivables and inventory realistically. + +--- + +## Margin of safety + +The margin of safety is risk control, not rhetoric. It exists because the estimate is wrong — the only questions are by how much and in which direction. + +- **Scale the required discount to the uncertainty of the estimate**, not to enthusiasm for the idea. Indicative: 15–25% for a wide-moat, predictable, low-leverage compounder; 30–40% for an average business with a normal cycle; 50%+ for cyclicals, turnarounds, leveraged balance sheets, single-product companies, opaque governance or heavy promoter pledging. Graham's classic ~one-third is a midpoint, not a universal constant. +- **Take the discount off the conservative case, not the base case.** A 30% discount to an optimistic fair value is not a margin of safety; it is an optimistic fair value with a rounding error. +- **Do not stack conservatism.** Conservative cash flows + an inflated WACC + a large price discount is three haircuts compounded, and produces a value so low nothing ever qualifies. Decide where the conservatism lives and state it. +- **Lead with the downside.** Answer "what do I lose if I am wrong" before "what do I make if I am right". Quantify the bear case as a percentage decline and a probability of *permanent* impairment, not as a mood. +- **A margin of safety does not protect against a decaying asset.** Where intrinsic value is itself falling — melting-ice-cube economics, structurally impaired end market — the discount narrows on its own while you hold. Time is a cost there, not an ally. +- **Test against the sector's own floor.** Where the playbook prescribes one (NAV for shipping, replacement cost for cement, adjusted book for banks), measure the margin of safety against that floor as well as against your DCF. +- **Needing the bull case to justify entry is a disqualification**, not a close call. + +--- + +## Quality trap versus value trap + +Separate **business quality** (ROIC−WACC spread, moat durability, reinvestment runway, margin stability — established in `references/05-returns-and-dupont.md`) from **price paid** (the multiple), and place the stock on both axes. + +| | Cheap multiple | Expensive multiple | +|---|---|---| +| **High, durable ROIC** | The rare case. Requires an identifiable reason the market is wrong. | **Quality trap** — a fine business whose return is consumed by multiple compression. | +| **Low ROIC, or ROIC fading to WACC** | **Value trap** — the discount is a fact about the business, not an opportunity. | Avoid outright. | + +The arithmetic underneath: over a long holding period an owner's return converges toward the business's return on capital, not toward the entry multiple. A business compounding capital at 18% delivers something close to 18% to a patient owner even from a full price; a business earning 6% delivers close to 6% however cheaply it was bought, because the cheap multiple is a one-time gain while the low return repeats every year. **Entry price decides the first few years; ROIC decides the rest.** + +So ask explicitly: **does time work for me or against me here?** In a high-ROIC reinvestor, waiting creates value. In a low-return business the only lever is the multiple closing, which requires a catalyst and a clock. Two failure modes follow, and both should be named in the report when present: paying a premium multiple for a business whose *incremental* ROIC is quietly sliding toward WACC (the quality trap — visible in ROIIC long before it shows in average ROIC), and anchoring to a low multiple on a structurally declining business while mistaking cheapness for safety (the value trap). + +--- + +## Scenarios, expected value and IRR decomposition + +Never report a single number. Build the table and let it carry the conclusion. + +| Scenario | Probability | Key assumptions (revenue CAGR, steady-state margin, exit multiple) | Value per share | Return vs price | IRR over holding period | +|---|---|---|---|---|---| +| Bull | e.g. 20% | | | | | +| Base | e.g. 50% | | | | | +| Bear | e.g. 25% | | | | | +| Severe / permanent impairment | e.g. 5% | | | | | + +- **Each scenario must be internally coherent**, not the base case ±10%. If the bull case assumes 20% volume growth, it must also carry the operating leverage *and* the capex and working capital that growth consumes. Flexing one variable at a time understates true dispersion. +- **Probabilities must be stated and sum to 1**, and should be sanity-checked against base rates — how often turnarounds of this type actually work, how often a company of this size sustains this growth. Bottom-up models produce inside-view optimism by construction; the reference class is the correction. +- **Compute the probability-weighted value and the upside/downside ratio.** A working standard is at least 3:1 upside to downside before an idea is interesting. A symmetric 60-up/40-down bet is a fundamentally different proposition from a capped-downside one at the same base case, and only the asymmetry table reveals it. +- **Decompose expected IRR into its sources:** + +``` +Expected annual return ≈ FCF or dividend yield + + growth in earnings / FCF per share + ± change in the multiple (re-rating or de-rating) + ± change in share count + ± FX translation into the holder's base currency +``` + + State each term. If more than half the expected return depends on multiple expansion, the thesis is a re-rating bet and must be labelled as such — re-rating requires other people to change their minds, which the analysis does not control. A return built from FCF yield plus per-share growth with a flat or conservatively contracting multiple is far more robust at the same headline upside. +- **Time is part of the arithmetic.** A 40% gap to fair value is a 35% IRR if it closes in a year and about 7% if it takes five. State the assumed holding period and always express upside in annualised terms. +- **Test against a real alternative.** The hurdle is not zero — it is the expected return on the index or a risk-free instrument over the same horizon, after transaction costs (brokerage, STT and stamp duty in India; spread and impact cost in illiquid small caps) and after tax on the realised gain. A 12% gross expected return netting to 8% against an index expected to do the same is not an opportunity. Present this as analysis of the investment's merits — not as personalised advice, and not as a position size. + +--- + +## Catalyst, edge and what is already discounted + +A valuation gap is a hypothesis about other people's future opinions. Close the loop before concluding. + +- **Why does the mispricing exist, and who is on the other side?** Name the mechanism: a forced seller, index exclusion, a broken-IPO or lock-up overhang, coverage neglect below a market-cap threshold, a temporary earnings dislocation being extrapolated. If there is no answer, the most likely explanation is that the price is right and the model is not. +- **What is the edge?** Informational (rare), analytical (you modelled the fade rate correctly), or behavioural/time-horizon (you can hold through three bad quarters). Behavioural edge is the only durable one for most analysis, and it requires the catalyst timeline to be long, not absent. +- **Enumerate catalysts with expected timing:** earnings inflection, margin recovery, a capex cycle ending and FCF appearing, capital-return initiation, deleveraging past a covenant threshold, demerger or spin-off, management change, index inclusion, a regulatory decision, promoter stake increase or open offer. Distinguish a self-correcting mispricing (FCF accumulates and does the work) from one that requires an event to occur. +- **Know what is already discounted.** Check consensus estimate levels and dispersion, the direction and breadth of recent revisions, and where your forecast sits versus the street. Returns come from surprises against expectations, not from absolute results. Cross-reference with the reverse DCF: consensus estimates and price-implied expectations are frequently different, and the gap between them is itself information. +- **Steel-man the bear case.** Read the best-argued short thesis available and state which parts you accept. A valuation section with no articulated bear case has not been stress-tested, and a pre-mortem — "it is two years later and this is down 50%; what happened?" — usually surfaces the assumption you never examined. + +--- + +## Sector overrides + +**The sector playbook overrides everything above.** Applying a generic P/E across sectors is the valuation equivalent of ranking companies on operating margin. + +| Sector | Default method breaks because | Use instead | +|---|---|---| +| **Banks, NBFCs, HFCs** | Debt is raw material; EV and EV/EBITDA are undefined. | P/B and P/ABV against ROE, justified P/B = (ROE − g)/(COE − g), RoRWA, stressed-book scenarios. `sectors/banks.md`, `sectors/nbfc.md` | +| **Life insurers** | Accounting profit is an artefact of new-business strain. | P/EV, VNB multiple, appraisal value. General insurers: combined ratio with P/B. `sectors/insurance.md` | +| **REITs, InvITs, developers** | Depreciation on appreciating assets destroys the earnings base. | AFFO yield, NOI cap-rate spread, NAV; developers on land-bank NAV plus pre-sales. `sectors/realestate-reit.md` | +| **Miners, steel, oil & gas, commodity chemicals** | P/E is inverted across the cycle — lowest at the peak. | Mid-cycle EV/EBITDA, P/NAV at a stated commodity deck, EV per tonne or boe of reserve, cost-curve position. `sectors/metals-mining.md`, `sectors/oil-gas.md`, `sectors/chemicals-cement.md` | +| **Airlines, hotels** | Leases and operating leverage dominate; earnings swing through zero. | EV/EBITDAR, EV per seat-km or per key, fleet replacement cost. `sectors/aviation-hotels.md` | +| **Shipping** | Asset values move faster than earnings. | P/NAV on broker vessel valuations, EV per dwt, mid-cycle charter rates. `sectors/shipping-logistics.md` | +| **Regulated utilities** | Returns are capped by the regulator. | Multiple of regulated asset base, allowed vs achieved RoE, dividend discount model. `sectors/utilities-power.md` | +| **Holdcos, conglomerates, asset managers** | Consolidated multiples blend unlike businesses. | SOTP with an explicit, justified holdco discount; AUM-based multiples for managers. `sectors/holdco-assetmgr.md` | +| **Loss-making growth / new-age** | There is no E for the P/E. | EV/Sales decomposed to an implied steady-state margin, EV/gross profit, cohort unit economics, reverse DCF on the implied margin. | +| **IT services, SaaS** | The growth-versus-margin trade-off is a choice, not a fact. | EV/FCF, EV/Sales against Rule-of-40, retention-adjusted economics. `sectors/it-saas.md` | +| **Pharma** | Value sits in a pipeline with binary outcomes. | Base-business EV/EBITDA plus probability-adjusted rNPV per asset. `sectors/pharma-healthcare.md` | + +--- + +## India (Ind-AS/NSE-BSE) vs US/global conventions + +**India-specific** + +- **Units.** Market cap and EV in ₹ crore (1 crore = 10 million; 1 lakh = 100,000). State the unit in every table; mixing crore and million is the most common presentation error in India-focused output. +- **Standalone vs consolidated.** Screeners routinely serve standalone P/E and ROCE for companies whose economics are consolidated. Every valuation input must be consolidated — and the EV bridge must then carry the minority interest consolidation creates. +- **Accounting seams that break the multiple history.** Ind AS 116 lease capitalisation (FY20) lifted EBITDA and EV; the s.115BAA election to a ~25.17% effective tax rate (FY20 onward) lifted EPS. Neither is operating. Restate pre-FY20 years before plotting a ten-year multiple band. +- **Surplus treasury sits in "current investments"** (liquid mutual funds), not in cash. Deduct it in the bridge *and* remove its yield from EBIT. +- **CCPS, CCDs, warrants and ESOP pools** in recently listed companies materially change the diluted count. The share-capital and ESOP notes in the annual report are the source; the exchange filing cover page is not. +- **Promoter holding, pledge and open-offer mechanics.** SEBI's takeover code triggers a mandatory open offer past the 25% threshold with a formula-based price floor; delisting runs through reverse book-building. These create observable floors and ceilings in control situations. High promoter holding with a thin free float can sustain a multiple well above fundamentals — and can collapse it when pledged shares are invoked. +- **Holdco discounts are structurally wide and durable** (40–70% is common). Never model one closing without a named, dated catalyst. +- **Buybacks:** since the October 2024 change, buyback proceeds are taxed in shareholders' hands as deemed dividend, materially altering the buyback-versus-dividend calculus for Indian companies. Verify the current-year treatment before comparing shareholder yield across the India/US boundary. +- **Frictions a gross return ignores:** STT on both legs, exchange charges, stamp duty, GST on brokerage, and LTCG on listed equity above an annual exemption with a higher STCG rate. Verify current-year rates — they have changed repeatedly. +- **Concalls and investor presentations** frequently disclose segment EBIT, capacity, utilisation, order book and per-unit realisations absent from the filing, and these are essential for SOTP and EV-per-unit work. Cite the quarter. +- **CARO 2020** disclosures on related-party loans and unrecorded transactions are a direct cross-check on whether the "surplus cash" you deducted in the bridge is genuinely available to shareholders. + +**US/global** + +- **10-K, 10-Q, DEF 14A via EDGAR.** Segment data under ASC 280 for SOTP; the Reg G non-GAAP reconciliation sizes the adjusted-versus-GAAP gap for you. +- **SBC is large and must be treated as a cost.** US technology "adjusted EBITDA" and "adjusted FCF" that add SBC back overstate owner returns directly and materially. +- **Leases under ASC 842 (2019)** create the same series break as Ind AS 116, but US GAAP retains the operating/finance distinction in the P&L, so EBITDA is *not* affected identically to IFRS. Check before comparing EBITDA multiples across the standards boundary. +- **Convertibles with capped calls** need careful dilution treatment; the if-converted count in the 10-K may not reflect the hedge. +- **The 2017 US tax change** creates a discontinuity in historical P/E and EV/EBIT series. +- **Negative book equity** is normal in mature US firms after decades of buybacks; P/B is undefined and should be suppressed rather than printed. +- **A 1% excise on net buybacks** (from 2023) slightly reduces buyback yield. +- **NOL usability** is capped after an ownership change (s.382), so a headline NOL balance is worth less than face value in an SOTP. +- **ADRs** carry withholding tax and depositary fees, and the ADR price embeds an FX view — value the underlying in local currency and translate separately. + +--- + +## Errors that ruin this section of the report + +- **Anchoring:** building the DCF after looking at the price, then tuning WACC or terminal growth until it agrees. Run the reverse DCF first. +- **A broken EV bridge:** leases, minorities, pensions or the option overhang omitted; or gross cash deducted when most of it is operating, trapped or customer float. +- **Mixing claims:** an equity numerator against an enterprise denominator, or consolidated EBITDA against a parent-only EV. +- **Currency mismatch:** discounting INR cash flows at a USD WACC, or calling a 3% terminal growth rate conservative in a 5–6% inflation currency. +- **A single point value** with no sensitivity table and no scenario range. +- **Terminal value carrying 85% of the answer**, unreported. +- **Comparing multiples across the FY20/2019 accounting seam** and calling the step-change a trend. +- **Peer sets chosen to flatter**, or a "discount to peers" in a sector that is itself at a record multiple. +- **Using a low P/E on a peak-cycle commodity earner as evidence of cheapness** — the single most expensive error in this file. +- **Adding back SBC** to reach the FCF that supports the valuation. +- **Assuming a holdco or conglomerate discount closes** with no catalyst and no timeline. +- **Printing a multiple the sector playbook declares undefined** (EV/EBITDA for a bank, P/E for a REIT) with a caveat instead of suppressing it. A caveated number is still a number the reader anchors on. +- **Reporting fair value to two decimals** when the inputs are three judgement calls. Give a range and state what drives its width. +- **Presenting the output as advice.** Give the valuation range, the assumptions, the bear case and the falsifiers; do not issue a buy instruction or a position size. + +--- + +## Checklist + +- [ ] Consult the sector playbook first; use its prescribed method and suppress every multiple it declares undefined or inverted. +- [ ] Normalise earnings for one-offs, cycle position and tax before computing any multiple; state reported vs adjusted and why. +- [ ] Build the full EV bridge — diluted count, debt, leases, preferreds/CCPS, minorities, pension deficit, earn-outs, less *surplus* cash and non-consolidated stakes — and show it as a table. +- [ ] Verify every multiple pairs an equity claim with equity value and an enterprise claim with EV. +- [ ] Derive WACC explicitly: risk-free in the cash-flow currency, ERP, country risk premium by revenue exposure, bottom-up relevered beta, marginal cost of debt, market-value weights. Date it. +- [ ] Apply the currency-consistency rule; never discount local-currency cash flows at a foreign rate. +- [ ] Run the reverse DCF **before** your own forecast; report implied growth, margin, CAP, ROIC, breakeven growth and the PVGO share of price. +- [ ] Test the implied expectations against base rates and against management's own guidance. +- [ ] Build the DCF with an explicit fade toward WACC, a reinvestment-consistent terminal value, and g ≤ nominal GDP in the same currency. +- [ ] Report terminal value as a % of total, plus the implied exit multiple versus today's and the historical median. +- [ ] Produce two-way sensitivity tables on WACC × terminal growth and on steady-state margin; report the range, not the centre cell. +- [ ] Treat SBC as a cost, not an add-back, in every cash-flow measure. +- [ ] Compute FCF yield, owner-earnings yield and total shareholder yield; confirm buybacks are FCF-funded, net of SBC, and executed below your value range. +- [ ] Compare earnings/FCF yield to the local 10-yr sovereign and to the company's own after-tax cost of debt; place the spread in its own history. +- [ ] Plot every multiple against its own 5–10 year median and percentile; explain deviations structurally or concede mean reversion. +- [ ] Decompose historical shareholder return into earnings growth, multiple change and yield. +- [ ] Build a defensible peer set, normalise accounting, regress multiples against ROIC and growth, and interpret the residual rather than the raw discount. +- [ ] Check the peer group's own multiple against its history to rule out whole-sector mispricing. +- [ ] Run at least one non-accounting cross-check: SOTP, private market value with a control premium, or replacement cost / EV per physical unit and Tobin's q. +- [ ] For SOTP, net corporate costs, disposal taxes and a justified holdco discount; report the implied stub. +- [ ] Map the stock on quality (ROIC−WACC) versus price and name it: compounder, cigar-butt, quality trap or value trap. +- [ ] State the margin of safety as a % against the *conservative* case, sized to estimate uncertainty, without stacking conservatism three times. +- [ ] Build a 3–4 scenario table with stated probabilities, coherent per-scenario assumptions, a probability-weighted value and an upside/downside ratio. +- [ ] Decompose expected IRR into yield + growth + re-rating + share count + FX; flag if re-rating is more than half of it. +- [ ] State the assumed holding period, annualise the upside, and net it against transaction costs, taxes and the index alternative. +- [ ] Name the catalyst and its timing, why the mispricing exists, and what is already in consensus estimates. +- [ ] State explicit falsifiers: the price, multiple or operating outcome that would prove the valuation wrong. +- [ ] Label all indicative ranges as indicative; let peer and own-history comparison carry the conclusion. +- [ ] Present a range with assumptions and a bear case — research, not a recommendation and not a position size. diff --git a/finance/skills/stock-analysis/references/07-forensic-red-flags.md b/finance/skills/stock-analysis/references/07-forensic-red-flags.md new file mode 100644 index 00000000..a8006ea0 --- /dev/null +++ b/finance/skills/stock-analysis/references/07-forensic-red-flags.md @@ -0,0 +1,427 @@ +# Forensic Accounting and Red Flags + +Use this when: you are running the Stage 3 kill-criteria screen or the Stage 4 forensic pass, or any time reported profit, growth or asset values look better than the business economics you can observe from outside. + +Forensic work is not about proving fraud. It is about deciding how much weight the reported numbers can carry, because every figure you use downstream — margin, ROCE, EV/EBITDA, FCF yield — is only as good as the accounting policy that produced it, and management chooses that policy. Your job is to locate where discretion was exercised, quantify how much of reported performance depends on it, and say so plainly. The governing rule of this skill applies at full force here: a red flag is meaningless until you know the sector and the company's own history. Rising receivables are normal in EPC and alarming in FMCG; negative operating cash flow is a fraud signal for a distributor and business as usual for a growing lender. + +## Contents + +- [0. How frauds are actually caught](#0-how-frauds-are-actually-caught) +- [1. Cash flow vs earnings: the accruals tests](#1-cash-flow-vs-earnings-the-accruals-tests) +- [2. Proof of cash: does the cash exist and is it yours?](#2-proof-of-cash-does-the-cash-exist-and-is-it-yours) +- [3. Revenue-side manipulation](#3-revenue-side-manipulation) +- [4. Working-capital manipulation and period-end window dressing](#4-working-capital-manipulation-and-period-end-window-dressing) +- [5. Cost capitalisation and expense deferral](#5-cost-capitalisation-and-expense-deferral) +- [6. Acquisition accounting and serial acquirers](#6-acquisition-accounting-and-serial-acquirers) +- [7. Disclosure and metric games](#7-disclosure-and-metric-games) +- [8. Auditor signals](#8-auditor-signals) +- [9. People signals: CFO and audit-committee turnover](#9-people-signals-cfo-and-audit-committee-turnover) +- [10. Structural opacity and off-balance-sheet exposure](#10-structural-opacity-and-off-balance-sheet-exposure) +- [11. Tax anomalies](#11-tax-anomalies) +- [12. India: the mandatory disclosures that do forensic work for you](#12-india-the-mandatory-disclosures-that-do-forensic-work-for-you) +- [13. Independent verification: the part that actually catches frauds](#13-independent-verification-the-part-that-actually-catches-frauds) +- [14. Composite forensic scores and statistical tests](#14-composite-forensic-scores-and-statistical-tests) +- [15. Sector translation: where these tests are undefined or inverted](#15-sector-translation-where-these-tests-are-undefined-or-inverted) +- [16. Calibration: how to report a red flag and what it changes](#16-calibration-how-to-report-a-red-flag-and-what-it-changes) +- [Checklist](#checklist) + +--- + +## 0. How frauds are actually caught + +Internalise this before you start, because it determines how you allocate effort. + +**Every major accounting fraud reconciled internally.** Satyam, Enron, Parmalat, Wirecard, Luckin, NMC Health, Sino-Forest, Carillion — in each case the balance sheet balanced, the cash flow statement tied to the balance sheet, the ratios were computable, and a competent desk analyst working purely from the filings could complete a full checklist without the numbers contradicting each other. Fabricated financials are internally consistent by construction, because whoever fabricated them had to make them tie. + +Two consequences: + +1. **Filings-based forensics detects distortion, not fabrication.** Ratio work reliably catches aggressive accounting — pulled-forward revenue, deferred costs, cookie-jar reserves, over-capitalisation. It is much weaker against a business that does not exist, because there the "distortion" is complete and self-consistent. +2. **The decisive evidence is almost always non-company evidence.** Bank confirmations, customs and shipping records, satellite imagery, registry filings in the operating jurisdiction, employee and customer contact, alternative data. Section 13 is not an optional extra at the end of this file; for any company where the fraud hypothesis is live, it *is* the analysis. + +So run the quantitative tests to **generate hypotheses about which line item is doing the work**, then attack that line item with outside evidence. Never conclude "the accounts reconcile, therefore they are real." + +**Triage order when time is limited.** Cash conversion over five years → interest-income reconciliation on the cash balance → DSO and receivables-vs-sales growth → capex vs depreciation → audit opinion, KAMs and auditor changes → related-party and promoter-pledge disclosure. Those six take under an hour from the filings and catch the overwhelming majority of distortion cases. Everything else in this file is depth applied where those six point. + +--- + +## 1. Cash flow vs earnings: the accruals tests + +Profit is an opinion; cash is closer to a fact. The single highest-yield forensic exercise is to lay reported profit alongside operating cash flow for five or more years and ask where the difference went. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Cash conversion | CFO ÷ net profit, per year **and cumulative over 3–5 years** | Cumulative ≥ 0.8–1.0 for mature businesses; ≥ 1.0 for asset-light | Cash is far harder to fabricate than accrued profit; a persistent gap means profit is sitting in receivables, inventory or capitalised costs | +| Cumulative gap | Σ CFO (5y) − Σ PAT (5y), in absolute currency | Small relative to cumulative PAT | Single-year gaps are noise; a five-year gap is a structural claim about earnings quality | +| Sloan accrual ratio (balance-sheet) | ΔNOA ÷ average NOA, where NOA = (total assets − cash & investments) − (total liabilities − total debt) | Below ~10%; sustained >15–20% is a flag | Growth funded by expanding non-cash assets rather than cash generation predicts weaker future returns and higher restatement risk | +| Sloan accrual ratio (cash-flow) | (PAT − CFO − CFI) ÷ average NOA | As above | Less vulnerable to acquisition and restatement noise than the balance-sheet version | +| FCF conversion | (CFO − capex) ÷ PAT, cumulative 5y | Positive and rising for a mature business | EBITDA and even CFO can be flattered by classification; capex is where deferred costs finally surface | +| EBITDA-to-FCF gap | EBITDA − (CFO − capex), as % of EBITDA, trend | Stable | A widening gap is the signature of costs migrating from the P&L into the investing section | + +*Indicative ranges vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**How to run it.** Build a five-year table: PAT, CFO, capex, FCF, ΔWorking capital, D&A, non-cash items. Then answer explicitly: **if profit did not become cash, which asset did it become?** Receivables, inventory, CWIP, intangibles, loans and advances to related parties, and "other current assets" are the usual destinations, and each points to a different section of this file. + +**Legitimate explanations you must rule out before flagging.** A genuinely fast-growing, working-capital-intensive business (distribution, EPC, capital goods) consumes cash while growing and will show CFO below PAT for years; that is arithmetic, not fraud. Test it by computing working capital as a **percentage of sales**. If that ratio is stable and only the absolute number grows, the cash gap is growth. If working capital as a % of sales is itself climbing, the growth is being bought. + +**Cash-flow-statement integrity check.** Tie the working-capital movements shown in the cash flow statement to the year-on-year changes in the corresponding balance-sheet lines. They will rarely match exactly — acquisitions, disposals, FX translation and reclassifications legitimately break the tie — but the company should be able to explain the bridge, and large unexplained differences are where reclassification games live. If the balance sheet shows receivables up 40% while the cash flow statement shows a small receivables outflow, something was moved: securitised, reclassified to "other assets", or acquired. Find out which. + +**Classification traps — resolve before comparing CFO across companies.** +- Under Ind-AS and IFRS, interest paid may sit in operating **or** financing, and interest and dividends received in operating or investing. Under US GAAP the classification is fixed. Two identical businesses can report materially different CFO. **Re-derive CFO on a common basis** (interest paid in financing, interest received in investing is a clean convention) before any cross-company or cross-regime comparison, and state the convention you used. +- Receivables securitisation or factoring turns what is economically borrowing into an operating inflow. Find the disclosed amount factored and add it back to receivables when computing DSO. +- Supply-chain finance / reverse factoring keeps supplier debt inside trade payables and flatters both CFO and reported leverage. Disclosure is often thin; look in the payables note, the liquidity discussion and rating-agency commentary. This is the Carillion and Abengoa mechanism. +- Purchases of "investments" that are economically operating assets; leases restructured so outflows fall below the CFO line. + +**Quarterly integrity.** Sum the four reported quarters and compare to the audited annual figure for revenue, EBITDA and PAT. **India:** quarterly results are limited-review, not audited, and Q4 is normally a balancing figure — audited full year minus nine months. Provisions, true-ups and rev-rec adjustments therefore cluster in Q4. A Q4 whose margin, other income or tax rate looks nothing like the 9M run-rate is telling you exactly where discretion was exercised. **US:** compare the 10-K to the sum of the 10-Qs and read the fourth-quarter adjustment disclosure. + +--- + +## 2. Proof of cash: does the cash exist and is it yours? + +Fake, pledged or unrepatriable cash is the single most common feature of the largest accounting frauds. Standard analysis nets cash against debt and moves on. Do not. Cash is an asset like any other and requires an existence test. + +**The interest-income reconciliation.** The cheapest high-severity test available. Run it on every company holding a large cash balance. + +1. Average cash and liquid investments = (opening + closing) ÷ 2. Use quarterly averages where available; annual averages are badly distorted by a fundraise or a year-end sweep. +2. Take interest and investment income from the other-income note. Isolate it from FX gains, dividend income from operating subsidiaries, government grants and profit on asset sales. +3. Implied yield = investment income ÷ average cash and investments. +4. Compare to prevailing short-term deposit and money-market rates for that currency and period. India: bank fixed-deposit and liquid-fund rates, which track the repo. US/global: T-bill and money-market rates. + +An implied yield far below the risk-free short rate means one of: the cash is not there; it is pledged or restricted; it sits in non-interest-bearing current accounts; or it sits in a low-rate jurisdiction. Every one of those is something you need to know before treating the balance as net-debt relief. + +**Caveats that produce false positives — resolve them before flagging.** +- **India / Ind-AS:** returns on liquid mutual funds are reported as "net gain on fair value changes" under Ind-AS 109, not as interest income. Counting only "interest income" manufactures a false flag. Sum the entire investment-return block. +- Cash raised late in the period earns almost nothing — check the timing of any issuance or asset sale. +- Operating float in current accounts legitimately earns nothing, but a company should not hold years of surplus that way. +- Interest income is netted against interest expense in some presentations. +- Cash in subsidiaries in low-rate or capital-controlled jurisdictions earns local rates and may not be repatriable. + +**The other cash tests.** + +| Test | What to compute / read | Why it matters | +|---|---|---| +| Gross cash alongside gross debt | Cost of carry = (average debt cost − implied cash yield) × overlapping balance | A company paying 9% to borrow while earning 4% on an equal cash pile destroys value every year for no stated reason. Either the cash is encumbered or absent, or there is an undisclosed constraint. A classic tell; management should have a specific answer | +| Restricted / pledged cash | Balance-sheet split, notes, and the charge registry (India: MCA charges; US: security disclosures in the debt note) | Cash pledged against borrowings is not available to shareholders and must be excluded from net-debt maths | +| Where the cash is banked | Names of banks in the deposits note; jurisdiction | Deposits concentrated in small, obscure, offshore or promoter-linked banks are a severe flag. Large groups bank with large banks | +| Repatriability | Cash held in subsidiaries; tax cost of upstreaming; capital controls | Consolidated cash can be legally unavailable to the listed parent | +| Audit evidence for cash | Is "existence of cash and bank balances" a Key Audit Matter? Did the auditor obtain direct bank confirmations? | If the auditor flagged cash existence as a KAM, so should you | +| Dividend reality | Dividends and buybacks paid ÷ reported PAT, over 5 years | Cash actually leaving the company to shareholders is the hardest confirmation that it existed. A company that reports a decade of profits, never pays out, never deleverages and keeps raising capital is asserting cash it cannot demonstrate | +| **India:** CARO commentary | Funds raised for one purpose applied to another; short-term funds used for long-term purposes; loans and advances to related parties | CARO forces explicit auditor comment on precisely these leakage routes | + +--- + +## 3. Revenue-side manipulation + +Revenue is the number valuation multiples attach to, so manipulation concentrates there. Read the revenue-recognition policy in full (Ind-AS 115 / IFRS 15 / ASC 606) and the critical-estimates note, not the summary. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| DSO | (Receivables ÷ revenue) × 365; five-year trend **and** vs peers | Flat to falling; level is sector-bound | Rising DSO means sales are booked faster than collected — the leading indicator of both channel stuffing and fabricated customers | +| Receivables growth ÷ revenue growth | Both in %, same consolidation basis | ≈ 1.0 | Persistently >1.3–1.5 means growth is being bought with credit, or invented | +| Unbilled revenue / contract assets ÷ revenue | Ind-AS 115 / ASC 606 disaggregation note | Stable; low outside project businesses | Unbilled revenue is a management estimate with no invoice behind it — the softest revenue there is | +| Allowance for expected credit loss ÷ gross receivables | Receivables note | Stable or rising as the book grows and ages | A shrinking allowance against a growing, ageing book is deliberate under-reserving | +| Receivables > 6 months / > 1 year (India) | Schedule III ageing table for trade receivables | Small and stable; disputed balances minimal | Old receivables that are not provided for are tomorrow's write-off, disclosed today | +| "Other receivables" / "other current assets" ÷ current assets | Balance sheet and notes | Small and stable | The standard hiding place for balances that belong nowhere legitimate | +| Deferred revenue growth vs revenue growth | Both in % | Similar for subscription models | Revenue growing while deferred revenue shrinks means the future is being consumed today | +| Revenue and gross profit per employee | ÷ headcount, five-year trend and vs peers | Stable to rising | Hard to fabricate; independently validates or refutes claimed scale | + +*Indicative ranges vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**Mechanisms to look for by name.** +- **Channel stuffing** — shipping to distributors at period end with generous return rights. Tells: quarter-end or Q4 revenue spikes beyond seasonality, DSO jumping in the final quarter, disclosed distributor inventory rising, returns and rebate provisions moving oddly. +- **Bill-and-hold** — revenue on goods not shipped. Requires specific disclosure; if disclosed, treat as material and quantify. +- **Gross vs net (principal vs agent)** — reporting gross merchandise value rather than commission inflates the top line by an order of magnitude without adding a rupee of profit. Critical for marketplaces, travel, energy trading, distribution and payments. Test: revenue ÷ gross profit. A switch from net to gross manufactures "growth" out of nothing and must be restated before any multiple is applied. +- **Percentage-of-completion / input-method revenue** (EPC, infrastructure, defence, capital goods, shipbuilding) — revenue is a function of a cost-to-complete estimate management controls. Watch cost-to-complete revisions, growing unbilled revenue and retention money, claims recognised as receivables, and margin recognised early in contracts. +- **Round-tripping** — sales to entities funded, directly or circularly, by the company or its promoters. Cross-check the related-party note against the customer-concentration disclosure. +- **Vendor / customer financing** — lending to customers, guaranteeing their debt, or accepting long-dated seller notes so they can buy. Track notes receivable, long-dated receivables and off-balance-sheet customer guarantees against revenue growth. It reads as clean organic growth until the credit sours, then reverses violently. Common in telecom equipment, solar, EV, capital goods and anyone selling to weaker counterparties. +- **Policy or estimate change** — any change in recognition timing, standalone-selling-price allocation, or warranty/returns estimate that raises current revenue. Quantify the effect; it is usually disclosed. + +**India-specific cross-checks.** Reconcile reported revenue against GST turnover (GSTR-1/3B summary where the company or a data vendor provides it), e-way bill volumes for goods businesses, and DGFT/customs export data for exporters. A material, persistent gap between accounting revenue and tax-reported turnover with no reconciliation in the notes is a serious flag, because the two numbers are filed with different parties who have opposing incentives. Also compare standalone and consolidated revenue: revenue existing only in unlisted or offshore subsidiaries deserves specific scrutiny. + +--- + +## 4. Working-capital manipulation and period-end window dressing + +The balance sheet is a snapshot on one day, and management knows which day. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| DIO | (Inventory ÷ COGS) × 365 | Flat vs own history; level sector-bound | Rising inventory is either weakening demand or costs parked in the balance sheet | +| Finished goods ÷ total inventory | Inventory note | Stable | Finished goods rising faster than raw materials means product is not selling | +| Inventory provision ÷ gross inventory | Inventory note | Stable or rising with age | Under-reserving inflates gross margin now and forces a write-down later | +| DPO | (Payables ÷ COGS) × 365 | Stable | A DPO spike is the easiest way to manufacture one year of operating cash flow | +| Cash conversion cycle | DSO + DIO − DPO | Stable or improving; compare to peers | The composite; divergence from peers needs a business reason | +| Period-end vs average balances | Quarter-end cash, receivables, payables and borrowings vs intra-period averages | Similar | Large period-end-only movements are window dressing, especially in borrowings and cash | +| Implied average debt | Interest expense ÷ average interest rate, compared to reported year-end debt | Similar | If actual interest implies materially more debt than the year-end balance, the year-end balance is not representative | + +**Specific patterns.** Gross margin expanding while DIO expands (costs absorbed into inventory rather than COGS). Payables stretching in the exact year CFO needed to look good, reversing the next. Receivables factored days before period end to flatter DSO. Borrowings repaid on the last day of the year and redrawn on the first day of the next — the implied-average-debt test above is the leverage analogue of the interest-income test in Section 2, and is worth running on any company with a suspiciously clean year-end balance sheet. + +**India:** CARO requires the auditor to state whether inventory verification was performed and whether discrepancies of 10% or more were found and properly dealt with, and — for working-capital limits above ₹5 crore sanctioned against current assets — whether the quarterly statements filed with the banks **agree with the books of account**. That clause is an auditor-attested reconciliation of reported receivables and inventory against what the company told its lenders. Read it. A disagreement there is one of the most concrete red flags available in any annual report anywhere. + +--- + +## 5. Cost capitalisation and expense deferral + +Capitalising an operating cost inflates profit and EBITDA, moves the outflow from operating to investing, and therefore flatters CFO as well. It is the WorldCom mechanism, and it survives in far milder everyday forms. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Capex ÷ depreciation | Cash capex ÷ D&A, five-year average and trend | ≈ 1.0–1.5 for a steady business; higher only with matching capacity or revenue growth | Sustained capex far above depreciation without volume growth means the spend is not producing output — or is not really capex | +| Implied useful life | Average gross block ÷ annual depreciation | Stable year to year; in line with peers on similar assets | A lengthening implied life raises profit permanently with no cash effect and no announcement | +| Capitalised development / software ÷ revenue | Intangibles note | Low and stable; zero for many businesses | Under IFRS/Ind-AS development costs *may* be capitalised where US GAAP is stricter — the choice itself is a policy signal, and a cross-regime comparability problem | +| CWIP ÷ gross block, plus CWIP ageing (India) | Schedule III mandates CWIP and intangible-under-development ageing (<1y, 1–2y, 2–3y, >3y) and disclosure of projects overdue or over budget | Little CWIP older than two years; projects capitalised on schedule | CWIP that never converts to fixed assets is where impairments hide. The mandatory ageing table makes this directly checkable | +| Change in useful lives / amortisation periods | Accounting-policy note, year over year | No change without a stated operational reason | The cheapest way to raise reported profit | +| Growth in intangibles and "other assets" vs revenue | Balance sheet vs P&L | In line | The residual dumping ground for deferred costs | + +Also check: **capitalised borrowing costs** (raises reported profit and interest coverage simultaneously — recompute coverage using total interest *incurred*, not just interest expensed); capitalised customer-acquisition and contract-fulfilment costs under Ind-AS 115 / ASC 606; capitalised labour; and **capital advances to suppliers**, which in India are a recurring route for funds to leave the company toward related parties without ever appearing as a related-party loan. + +The composite tell for this whole section is **strong EBITDA with weak or negative free cash flow, sustained across years**. If an EBITDA growth story is not visible in FCF after a full capex cycle, the costs did not disappear — they moved. + +--- + +## 6. Acquisition accounting and serial acquirers + +Acquisitions reset the baseline, and purchase accounting hands management a set of one-time, non-cash levers that present as recurring growth. Treat any company doing more than one deal a year as requiring this section, and pair it with the serial-acquirer overlay in `references/13-situations.md`. + +**Separate organic from acquired growth first.** Compute revenue growth excluding acquisitions completed in the last twelve months. If disclosure does not permit it, say so explicitly and treat headline growth as unverified — a serial acquirer that will not disclose organic growth is telling you something. Then ask the decisive question: **what does the growth rate become when M&A pauses?** For many roll-ups the answer is negative, which is precisely why the M&A never pauses. + +**Purchase-accounting levers to inspect in the business-combination note.** +- **Fair-value step-ups** on inventory and fixed assets — the step-up depresses post-acquisition gross margin as inventory sells through, which management then adds back as a "non-cash purchase accounting adjustment", permanently. +- **Restructuring and contingency reserves created on acquisition**, later released to earnings. Classic cookie jar: the charge never touches the P&L going in, but the release boosts it coming out. +- **Purchase-price allocation skewed to goodwill and indefinite-lived intangibles** (not amortised) rather than to finite-lived intangibles (amortised). Raises reported EPS for years with no economic difference. +- **Contingent consideration / earnout remeasurement** through the P&L — a gain when the acquired business underperforms is a perverse, non-economic profit. +- **Bargain purchase gains** — a "profit" from buying cheaply, recognised immediately. Never recurring earnings. +- **Recurring "integration" and "deal" costs** — appearing every single year makes them operating expenses, and adjusted EBITDA that excludes them overstates earning power by exactly that amount. +- **Same-store / like-for-like decay hidden under pro-forma presentation** — check whether the acquired businesses shrink after acquisition. That is the specific signature of a roll-up manufacturing EPS from deal flow rather than operations. + +**Goodwill and intangibles.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Goodwill ÷ total assets | Balance sheet | Modest; interpret against deal history | High goodwill means the balance sheet is mostly prices paid, not assets owned | +| (Goodwill + intangibles) ÷ equity | Balance sheet | Well below 100% | Above 100% means tangible equity is negative, and leverage ratios computed on reported equity become meaningless | +| Tangible book value | Equity − goodwill − intangibles | Positive for most non-software businesses | The capital actually standing behind the debt | +| Impairment-test headroom | Discount rate, terminal growth and disclosed headroom in the impairment note | Assumptions consistent with the company's own cost of capital and realistic growth | An impairment test that passes only on a terminal growth rate above nominal GDP is not passing | + +Market capitalisation persistently below book value with no impairment recorded is a direct disagreement between the market and the balance sheet, and the market is usually right first. An impairment landing immediately after the growth narrative breaks confirms the M&A destroyed value; the analytical failure was not marking it earlier. + +--- + +## 7. Disclosure and metric games + +Here the manipulation is in the definition, not the arithmetic. + +**Non-GAAP / adjusted earnings.** Tally every "exceptional", "one-off", "restructuring" and "impairment" item across five years. Items appearing every year are recurring costs and belong in normalised earnings. Compute the GAAP-to-adjusted gap as a % of reported profit and track whether it widens. Watch for add-backs of ordinary operating costs, of share-based compensation (a real cost paid in dilution — quantify it), and of "growth investments" that are simply opex. Big-bath charges clustered around a CEO or CFO transition and quietly released later are the cookie-jar pattern. US filers must publish a Reg G / Item 10(e) reconciliation — read it rather than the press-release headline. + +**Bespoke KPIs.** Catalogue every company-invented metric — ARR, bookings, backlog, GMV, MAU/DAU, take rate, "cash EBITDA", "contribution margin ex-marketing", "adjusted community EBITDA", store-level unit economics — and write down its exact definition from the filing. Then ask three questions: (a) does it reconcile to an audited number? (b) has the definition changed year over year? (c) is management steering attention to it precisely because the audited numbers rolled over? Bespoke metrics are not inherently illegitimate — for a subscription or platform business they may be the most informative numbers available — but they are unaudited, management-defined and definitionally unstable. **Record the definition alongside the number every time you use one**, and never build a valuation on a metric whose definition moved during the period you are measuring. + +**Metric-definition drift and disclosure deletion — the year-over-year redline.** Diff consecutive annual reports / 10-Ks, and where relevant the proxy or DRHP, for changes in: risk-factor wording, accounting-policy and critical-estimate language, segment definitions, useful lives and capitalisation policy, KPI definitions, MD&A tone, and customer or product concentration disclosures. **The highest-signal finding is always a deletion.** Management announces what it adds and never mentions what it removed. A volume disclosure that vanishes the year volumes fell, a KPI that stops being reported, a named large customer that disappears from the concentration note, a segment merged into "others" — each is information the company chose to stop giving you, and the reason is rarely favourable. Segment redefinition is the commonest form: it resets comparability exactly when comparability would have been damaging. **Tooling:** EDGAR full-text search and the filing-comparison view for US issuers; for India, the equivalent artefacts to diff are the MD&A, segment note, related-party note (watch entity-list changes), contingent-liabilities note, CARO clauses, and the concall — including which questions management stopped answering and which analysts stopped covering the name. + +--- + +## 8. Auditor signals + +The auditor is the last independent check on the numbers, and auditor-related events are among the strongest empirical predictors of restatement and fraud. + +| Signal | Where to find it (Global / India) | Why it matters | +|---|---|---| +| Opinion type: unqualified / qualified / adverse / disclaimer | Auditor's report | Anything other than unqualified is a first-order finding, never a footnote | +| Going-concern emphasis | Auditor's report; Emphasis of Matter | The auditor doubts the entity survives twelve months | +| Key / Critical Audit Matters (KAMs / CAMs) | Auditor's report | The auditor is naming the numbers that were hardest to audit. Start your forensic work there — it is a free prioritisation | +| Auditor resignation or dismissal | US: 8-K Item 4.01. India: exchange filing under SEBI LODR Reg 30, with the resignation letter and reasons | Mid-cycle resignation is among the highest-severity signals available. Read the stated reason *and* the company's version of it | +| Downgrade in auditor quality | Compare firm size and network to group complexity | A large multi-jurisdiction group audited by a small firm is a structural problem regardless of that firm's competence | +| Component-auditor coverage | "Other Matters" paragraph of the consolidated audit report | Compute the % of consolidated revenue, assets and profit **not** audited by the principal auditor, plus anything unaudited or "certified by management". This is a direct measure of how much of the accounts nobody independent examined | +| Audit fee vs complexity | Auditor remuneration note / proxy | An implausibly low fee for a large multi-entity group means the work was not done | +| Non-audit fees ÷ total fees | DEF 14A / auditor remuneration note | High non-audit fees compromise independence | +| Internal-control opinion | US: SOX 404 material weakness. India: separate auditor opinion on internal financial controls under s.143(3)(i) | An adverse IFC/404 opinion says the systems producing the numbers are not reliable — every ratio downstream inherits that | +| Late filings | US: NT 10-K/10-Q. India: delayed results and exchange penalties | Companies file late when there is an unresolved disagreement | +| Restatement and regulatory history | US: Big-R restatement via 8-K Item 4.02 vs little-r revisions; SEC comment letters (UPLOAD/CORRESP on EDGAR); enforcement. India: SEBI orders, NFRA orders against the company or its auditors, SFIO and MCA inspections | A prior restatement is among the strongest predictors of the next one | +| **India:** CARO clauses | CARO 2020 report | Direct attestation on fixed-asset and title-deed verification, inventory verification, benami proceedings, loans and guarantees to related parties (including whether fresh loans were granted to settle overdue ones — an evergreening test), statutory dues in arrears, default in repayment to lenders and wilful-defaulter status, end-use of term loans and IPO/preferential-issue proceeds, cash losses in the current and preceding year, whistleblower complaints, fraud reported under s.143(12), and issues raised by the outgoing auditor. Read every clause, not the summary | + +Also search for specific, substantiated short-seller reports and read the primary document rather than coverage of it. A short report is an adversarial argument with a financial interest behind it: treat every claim as a hypothesis to verify, note which claims the company answered *specifically* and which it answered only with adjectives, and attribute rather than adopt. + +--- + +## 9. People signals: CFO and audit-committee turnover + +Accounting is produced by a small number of identifiable people. When those people leave, it matters — serial finance-leadership churn is among the most reliable pre-restatement tells, and it is observable years before the numbers are. + +Track over 5+ years: CFO, controller / chief accounting officer, treasurer, chief internal auditor, audit-committee chair, and (India) company secretary and independent directors. Flag: + +- Serial CFO turnover — three finance chiefs in five years is a finding in itself. +- Departures clustered near reporting dates, audit sign-off, or a restatement. +- "Personal reasons" or "to pursue other opportunities" with no successor named, and a long gap before a permanent appointment. +- The audit-committee chair resigning, or independent directors resigning citing governance, disagreement, or inability to obtain information. **India:** SEBI requires disclosure of independent-director resignation letters — read the letter, not the press release. +- Departure of the head of internal audit, or internal audit reporting to the CEO rather than to the audit committee. +- **US:** cross-reference Form 4 insider sales against the departure timeline and against the peak of the growth narrative. + +Then correlate: did anything disclosed in the following four quarters explain the departure? People closest to the numbers tend to leave before the numbers become public. Detail on board composition and promoter behaviour sits in `references/08-governance.md`; this section is only the accounting-integrity slice. + +--- + +## 10. Structural opacity and off-balance-sheet exposure + +Complexity is sometimes historical accident and sometimes deliberate. Assume nothing; map it. + +- **Count and map the group.** Subsidiaries, step-down subsidiaries, associates, JVs, SPEs/VIEs and their jurisdictions. India: the AOC-1 statement of subsidiaries in the annual report, plus MCA/ROC records. Global: Exhibit 21 of the 10-K. Dozens of entities in Mauritius, Singapore, UAE, Cyprus or the Caribbean behind a simple domestic operating business is a structure that needs explaining. +- **Consolidated vs standalone (India).** Compare revenue, profit, debt and related-party balances on both bases. Profit concentrated at standalone with losses in subsidiaries, or debt in subsidiaries while cash sits at the parent, changes the entire risk picture. Never mix bases within one ratio. +- **Equity-method income without cash.** Equity-accounted income ÷ net profit, compared to dividends actually received from those entities. Profit you cannot receive is not profit you own. +- **Guarantees, letters of comfort, commitments and contingent liabilities ÷ equity.** In Indian infrastructure, telecom and real estate these routinely exceed net worth. Read the note in full: disputed tax demands and cross-guarantees to group entities live there. +- **Charges and security.** India: the MCA charge registry shows secured borrowings and pledged assets, including at unlisted group entities the consolidated statements may not reveal. +- **Leases and quasi-debt.** Post Ind-AS 116 / ASC 842 most leases are on balance sheet; check for arrangements structured to stay off it, and for sale-and-leaseback gains recognised in profit. +- **Related-party transactions and tunnelling.** Related-party revenue ÷ total revenue; related-party receivables and loans ÷ total assets; guarantees to related entities ÷ equity; intercompany balances ÷ equity. Look for asset transfers at non-arm's-length prices, management or brand-royalty fees paid to promoter entities, and circular flows that manufacture revenue. India: material RPTs need audit-committee approval and, above the LODR threshold, majority-of-minority approval — check how those votes went and whether transactions were sized just under thresholds. +- **Promoter pledging (India).** Pledged shares as % of promoter holding and % of total equity, plus the trend. Rising pledge is a promoter-liquidity signal that transmits directly into governance behaviour. +- **VIE / contractual-control structures.** For China and some EM ADRs, determine whether the listed entity legally owns the operating assets and profits or holds only contractual claims through offshore shells. Assess enforceability under local law, where cash, licences and IP legally reside, the mechanics and legality of upstreaming cash to foreign holders, and PCAOB inspection access / delisting risk. A genuinely profitable operating company can leave foreign minority holders with nothing — a structural trap invisible to earnings-quality analysis. +- **Frequent restructurings** that reset comparability, and segment reporting too aggregated to see what the business does. Cross-check that segment revenues and profits sum to the consolidated totals and that "unallocated" is not where the losses live. + +--- + +## 11. Tax anomalies + +Tax is a useful independent check because a second party — the tax authority — has an opposing interest in the numbers. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Effective tax rate | Tax expense ÷ pre-tax profit | Near the statutory rate, or fully reconciled to it in the tax note | A persistent unexplained gap suggests book profit that does not exist for tax purposes | +| Cash tax rate | Cash taxes paid (cash flow statement) ÷ pre-tax profit | Near the ETR on a 5-year average | Book profit that never generates a cash tax payment is a strong earnings-quality flag | +| Book-tax gap | Pre-tax book profit vs taxable income implied by the tax reconciliation | Small and explained | Widening gaps precede restatements | +| Deferred tax assets and valuation allowance | Tax note, year over year | Stable | Releasing a valuation allowance manufactures an EPS beat with no operating cause | +| Uncertain tax positions | FIN 48 reserve (US); disputed demands in contingent liabilities (India) | Stable | Aggressive structures create future liability and restatement risk | + +Read the tax-rate reconciliation table every year: it names the specific items bridging statutory to effective rate, and a large "others" line is itself a disclosure failure. **India:** check the concessional-regime election (s.115BAA), MAT credit utilisation, and tax holidays (SEZ or unit-based) with known expiry dates. A low ETR with a scheduled expiry is a dated earnings cliff, not a moat — never carry it forward indefinitely in a DCF. + +--- + +## 12. India: the mandatory disclosures that do forensic work for you + +Indian filings are unusually generous to a forensic analyst, because Schedule III (Division II, as amended) and CARO 2020 force explicit disclosure of exactly the things a distressed or manipulating company would prefer to omit. Read these before doing any ratio work on an Indian issuer; each one is a direct answer to a question you would otherwise have to infer. + +| Disclosure | What it tells you | +|---|---| +| Ageing tables: trade receivables, trade payables, CWIP, intangibles under development | Converts "receivables rose" into "how old, how disputed, how overdue" — the difference between a working-capital story and a write-off queue | +| Loans and advances to promoters, directors, KMPs and related parties that are repayable on demand or without stated terms | The tunnelling route, quantified and named | +| Borrowings on security of current assets: whether quarterly returns filed with banks agree with the books | Auditor-attested reconciliation of your receivables and inventory to what the lenders were told | +| Wilful-defaulter declaration; default in repayment of borrowings | Credit distress that has already been adjudicated by someone else | +| Relationship with struck-off companies | Transactions and balances with entities that legally no longer exist — a shell-company tell | +| Title deeds of immovable property not held in the company's name | Assets on the balance sheet that the company may not own | +| Revaluation of PP&E and intangibles; whether by a registered valuer | Equity created by revaluation is not equity earned | +| Utilisation of borrowed funds and share premium: declarations on ultimate beneficiaries and intermediaries | Directly targets round-tripping and fund diversion | +| Undisclosed income surrendered in tax assessments | Income the company admitted to the tax authority but not to you | +| Compliance with the number of layers of companies; pending charge satisfactions | Structural opacity, measured | +| Schedule III ratio disclosures with explanation for any change >25% | Management is required to explain its own ratio deterioration in writing. Read the explanations — they are frequently the weakest paragraphs in the report | +| CARO: cash losses in current and preceding year; material uncertainty on meeting liabilities within one year; issues raised by the outgoing auditor; whistleblower complaints; fraud reported under s.143(12) | Each is a severe, auditor-attested signal that requires no computation from you | + +The US analogue is thinner but real: Item 9A internal controls, Item 3 legal proceedings, Exhibit 21 subsidiaries, the schedule of valuation and qualifying accounts (Schedule II) showing reserve additions and releases, 8-K Items 4.01/4.02, and SEC comment-letter correspondence on EDGAR. + +--- + +## 13. Independent verification: the part that actually catches frauds + +Everything above is derived from documents the company wrote. This section is not, which is why it is where frauds are actually caught. + +**Proof of existence — assets, customers, counterparties.** + +| Claim being tested | Independent source | +|---|---| +| Plants, stores, mines, hotels, data centres, warehouses exist and operate | Satellite and street-level imagery, building permits, environmental clearances, power and utility consumption, local news, site visits | +| Named top customers exist and buy at the stated volumes | The customers' own filings (a listed customer discloses major suppliers or purchase volumes), trade press, distributor and channel contact | +| Physical goods actually moved | Customs and shipping records, bills of lading, port and freight data; India: DGFT export data and e-way bills | +| Subsidiary results match the consolidation | India: subsidiary financials filed with MCA/ROC (AOC-4). Global: local registry filings such as UK Companies House and EU registries, which frequently contradict group presentations | +| The auditor, bankers and key suppliers are real firms capable of servicing a client this size | Firm registries, PCAOB/NFRA records, headcount and office footprint | +| Claimed headcount and scale | LinkedIn headcount trend, job postings, employee reviews and attrition; India: EPFO monthly payroll additions, and the employee-count disclosure in the annual report and BRSR | + +**Alternative-data corroboration of reported growth.** Web traffic and app-download trends, app-store and marketplace review volumes, card and transaction panels where available, hiring velocity, and freight volumes. **The test is divergence, not level:** reported growth accelerating while every external proxy flattens is the pattern that precedes disclosure. Independent data is the short-seller's actual edge, and a checklist confined to filings can only ever detect problems the company itself chose to disclose. + +**Scuttlebutt.** Use the product. Read customer reviews on app stores, G2, Amazon and industry forums. Talk to customers, distributors, suppliers or ex-employees where feasible and permissible. Financial statements lag; ground-level observation often reveals deterioration quarters ahead of the numbers. + +**Information-integrity screen.** Establish where the idea came from. Screen for paid promotion and pump-and-dump patterns: unsolicited tips, thinly traded microcaps, reverse mergers, recent shell-to-operating transitions, aggressive newsletter or social promotion. Identify the incentives of whoever is recommending the stock, and verify every claim against the audited filing rather than a deck or a forum post. + +**Report what you could not verify.** You will frequently lack access to satellite data, expert networks or customs records. That is a data gap, not an absence of risk. Write it explicitly: *"the existence of the [x] asset base and the [y] customer relationships could not be independently corroborated from available sources; this component of the analysis rests on management representations."* That sentence is honest, useful, and changes how a reader sizes a position. + +--- + +## 14. Composite forensic scores and statistical tests + +Use these as screens that direct attention, never as verdicts. Each was calibrated on a specific population, and applying it outside that population produces confident nonsense. + +| Model | What it does | Threshold | Limits — read before using | +|---|---|---|---| +| Beneish M-Score | Eight ratios — days-sales-in-receivables, gross margin, asset quality, sales growth, depreciation rate, SG&A, leverage and total accruals — combined into a manipulation probability | Above −1.78 flags elevated risk | Calibrated on US manufacturers; high false-positive rate for fast growers and acquirers; **undefined for banks, NBFCs, insurers and REITs**. Note that six of the eight inputs are tests you have already run individually in this file — the index adds aggregation, not new information | +| Dechow F-Score | Misstatement probability from accruals, performance and market variables | Above 1.0 = above-normal risk | Same population caveats; needs several years of clean, restatement-free data | +| Montier C-Score | Six binary earnings-manipulation flags | Score out of 6 | Blunt; useful as quick triage only | +| Altman Z-Score | Bankruptcy risk from five ratios | >2.99 safe, <1.81 distress (manufacturing variant); use Z″ for non-manufacturers and emerging markets | Measures distress, not fraud; **meaningless for financials**; sensitive to the market-cap input, so it moves with price rather than fundamentals | +| Piotroski F-Score | Nine-point fundamental quality score | 8–9 strong, 0–2 weak | A quality screen, not a fraud test | +| Benford's Law | First-digit distribution test | Deviation from expected frequency | Weak on the few dozen line items in a financial statement; only meaningful on large transaction-level datasets. Do not present a Benford result on annual-report figures as evidence | + +**Non-model statistical tells.** Earnings and margins far smoother than the industry's; margins implausibly above best-in-class with no identifiable moat; beating consensus by exactly a cent for many consecutive quarters; near-zero earnings volatility in a demonstrably cyclical sector; reported growth uncorrelated with cash generation. Real businesses are lumpy. Unnatural smoothness is manufactured, and the manufacturing is either legal smoothing or something worse. + +Whenever you report a score, report its inputs and its population caveat alongside it. An M-Score quoted without the note that it is undefined for the company's sector is a fabrication dressed as rigour. + +--- + +## 15. Sector translation: where these tests are undefined or inverted + +Do not run the generic battery on a business it was not built for. Consult the playbook in `references/sectors/` and substitute the right tests. + +- **Banks and NBFCs.** DSO, DIO, DPO, cash conversion cycle and the accrual ratio are meaningless; CFO is dominated by loan-book growth and is *negative* for a healthy growing lender. The manipulation vector is **credit-loss recognition**: GNPA/NNPA trends, provision coverage, restructured and SMA-1/SMA-2 books, evergreening (fresh loans repaying old ones), write-offs and "advances under collection" that flatter reported GNPA, sales of stressed loans to ARCs against security receipts, interest accrued but not received, capitalisation of interest into restructured loans, and rapid growth in a single unseasoned product. **India:** the RBI divergence disclosure — where the regulator's assessed NPAs and provisions exceed the bank's own — is a direct, auditor-independent red flag and must be checked every year. +- **Insurers.** Reserve adequacy is the manipulation vector; under-reserving inflates current profit. Look at reserve development triangles (prior-year releases propping current earnings), assumption changes in life valuation (discount rate, lapse, mortality, expense), and the composition of embedded-value movement. Margins and cash conversion do not apply. +- **REITs, InvITs and real-estate developers.** Depreciation makes accounting profit near-meaningless; use FFO/AFFO and NAV. Watch fair-value gains on investment property routed through the P&L (non-cash profit), capitalised interest into projects, and revenue-recognition timing on developer sales. +- **Miners, oil and gas.** Depletion, reserve estimates and the capitalisation-vs-expensing of exploration (successful-efforts vs full-cost) are the levers. Reserve revisions change both the asset and the depletion charge simultaneously. Judge on mid-cycle economics, not trailing. +- **Utilities and regulated infrastructure.** Regulatory assets and deferrals can hold years of costs; check the recovery mechanism and the regulator's actual orders, not management's expectation of them. +- **Project businesses (EPC, infra, defence, shipbuilding).** Percentage-of-completion estimates, unbilled revenue, retention money and claims recognised as receivables *are* the earnings-quality question. +- **Early-stage and platform businesses.** The statutory statements may say very little; the bespoke KPIs are the analysis, so Section 7 becomes the primary section rather than a supporting one. + +--- + +## 16. Calibration: how to report a red flag and what it changes + +Getting this wrong destroys the credibility of everything else in the report. + +**Distinguish three severities and label them.** +1. **Aggressive but disclosed and legal** — a capitalisation policy at the permissive end, a non-GAAP measure with generous add-backs, a low ETR from a disclosed holiday. Effect: adjust the numbers yourself, note the adjustment, move on. +2. **Unexplained anomaly** — a metric behaving in a way the disclosure does not account for. Effect: state the anomaly, state the innocent explanation, state what evidence would distinguish them, and raise the required margin of safety. +3. **Structural integrity risk** — auditor resignation, adverse IFC/SOX opinion, cash-existence KAM, a large unaudited share of a consolidated group, Big-R restatement, regulator enforcement, tunnelling through related parties. Effect: this belongs in the report's opening verdict, not a footnote, and can be sufficient on its own to stop the analysis. Several are legitimate kill criteria. + +**Require a cluster, not a single flag.** Base rates matter. Most individual flags have mundane explanations — one year of rising DSO because a large customer paid late, one year of high capex because a plant was built. What distinguishes a real accounting problem is **several independent flags pointing at the same line item**: rising DSO *plus* a shrinking allowance *plus* revenue concentrated in Q4 *plus* a related-party customer. One flag is a question. Four flags aimed at the same number is a finding. + +**Always state the innocent explanation.** For every flag, write the most plausible benign reading and what would distinguish it. This is not hedging — it is what makes the flag credible on the occasions you do not withdraw it. + +**Language discipline.** Do not assert fraud. Describe what the disclosure shows, what it does not permit you to rule out, and what evidence would resolve it. *"Reported cash of X earns an implied yield of ~1% against short rates of ~6%, which the filings do not explain; possible readings are non-interest-bearing operating float, restricted balances, or an overstated balance — the deposits note and any bank-confirmation KAM would distinguish these"* is rigorous, defensible and useful. "The cash is fake" is neither. Apply the same standard to short-seller allegations: attribute, do not adopt. + +**Quantify the dependency, then carry it downstream.** The most useful output of a forensic pass is not a list of flags but a sentence like: *"roughly X% of reported EBITDA over the last three years depends on capitalisation and one-off treatments the peer group does not use; on a peer-consistent basis EBITDA would be approximately Y."* Never invent that number — derive it from disclosed line items and show the working, or state that it cannot be derived. Then propagate it: the adjusted figures, not the reported ones, are what feed the returns work in `references/05-returns-and-dupont.md` and the valuation in `references/06-valuation.md`. A forensic finding that does not change a downstream number has not been finished. + +--- + +## Checklist + +- [ ] Five-year table built — PAT, CFO, capex, FCF; cumulative CFO ÷ cumulative PAT computed, and the gap tied to a named asset line. +- [ ] Accrual ratio computed on at least one basis; growth in non-cash operating assets attributed to a specific line item. +- [ ] Working capital as a % of sales checked before flagging any cash-vs-profit gap in a growing business. +- [ ] CFO re-derived on a common classification basis before any cross-company or cross-regime comparison. +- [ ] Cash-flow-statement working-capital movements tied to balance-sheet deltas; unexplained differences investigated. +- [ ] Sum of four quarters reconciled to the audited annual figure; India — Q4 margin, other income and tax rate compared to the 9M run-rate. +- [ ] Interest and investment income reconciled to average cash; implied yield compared to short rates; Ind-AS fair-value gains on liquid funds included. +- [ ] Simultaneous large gross cash and gross debt explained, with the cost of carry quantified. +- [ ] Restricted, pledged and non-repatriable cash identified and excluded from net-debt maths. +- [ ] DSO, DIO, DPO and the cash conversion cycle computed for five years and vs peers; receivables growth vs revenue growth checked. +- [ ] ECL allowance and inventory provisions checked against a growing and ageing book; India — receivables ageing table read. +- [ ] Revenue-recognition policy read in full; gross-vs-net presentation, unbilled revenue and any policy or estimate change identified and quantified. +- [ ] Quarter-end vs intra-period balances tested; implied average debt from interest expense compared to year-end debt. +- [ ] Capex ÷ depreciation, implied useful life, capitalised development costs, CWIP ageing and useful-life changes reviewed; EBITDA-to-FCF gap explained. +- [ ] "One-off" items tallied across five years; recurring ones returned to normalised earnings; SBC quantified as a real cost. +- [ ] Organic growth separated from acquired growth; purchase-accounting levers (step-ups, acquisition reserves, earnout remeasurement, bargain-purchase gains) inspected. +- [ ] Goodwill and intangibles vs equity computed; tangible book value checked; impairment-test assumptions read against the company's own cost of capital. +- [ ] Every bespoke KPI catalogued with its exact definition; definitions compared year over year. +- [ ] Year-over-year redline done; **deletions** from prior-year disclosure specifically hunted and listed. +- [ ] Audit opinion, KAMs/CAMs, IFC/SOX opinion, auditor changes and stated reasons, audit fee and non-audit fee ratio reviewed. +- [ ] Component-auditor coverage computed: % of consolidated revenue, assets and profit not audited by the principal auditor. +- [ ] Restatement, comment-letter, NFRA/SEBI/SEC enforcement and litigation history checked; short reports read as primary documents. +- [ ] CFO, controller, treasurer, internal-audit head and audit-committee-chair turnover mapped over 5+ years; resignation letters read. +- [ ] Group structure mapped; equity-method income vs dividends received; guarantees and contingent liabilities vs equity; standalone vs consolidated compared. +- [ ] Related-party revenue, receivables, loans and guarantees quantified; promoter pledge level and trend checked (India). +- [ ] ETR vs statutory vs cash tax rate reconciled; any tax holiday dated to its expiry. +- [ ] India — CARO clauses and the Schedule III forensic disclosures read in full, including the bank-statement-vs-books agreement and the >25% ratio-change explanations. +- [ ] At least one independent, non-company corroboration attempted for the core growth or asset claim; whatever could not be verified stated explicitly. +- [ ] Composite scores, if used, reported with inputs and population caveats; never applied to financials. +- [ ] Sector translation applied — lenders, insurers, REITs and miners assessed on their own manipulation vectors, not the generic battery. +- [ ] Each flag labelled by severity, paired with its innocent explanation and the evidence that would resolve it; no fraud assertion made. +- [ ] The dependency quantified and carried into the returns and valuation work, not left as a standalone list of flags. diff --git a/finance/skills/stock-analysis/references/08-governance.md b/finance/skills/stock-analysis/references/08-governance.md new file mode 100644 index 00000000..d1da89ec --- /dev/null +++ b/finance/skills/stock-analysis/references/08-governance.md @@ -0,0 +1,477 @@ +# Management and Corporate Governance + +Use this when: you are running the Stage 3 red-flag screen or the governance block of Stage 4, or any time the controlling shareholder, the board or the auditor could be the reason the numbers look the way they do. + +Governance is not a soft, optional overlay on the financial analysis — it is the question of whether the financial analysis belongs to you. Every ratio you compute downstream assumes two things: that the reported figures describe reality (the forensic question, `references/07-forensic-red-flags.md`), and that the economics they describe accrue to the security you are considering buying (the governance question, this file). A business can compound beautifully and still deliver nothing to minorities, because the cash was routed to a promoter entity, the earnings were diluted away at a discount, the voting shares are held by someone else, or the listed vehicle only holds contractual claims on assets it does not own. The skill's governing principle applies here too: governance norms are sector- and market-relative. A 60% family stake is a red flag in a US large cap and the default condition in Indian mid-caps; an externally managed REIT has a fee-conflict problem that simply does not exist for an operating company; a bank's "capital allocation" is underwriting, not capex. + +## Contents + +- [0. How to run this dimension](#0-how-to-run-this-dimension) +- [1. What does the security actually confer? Share class, DVR, ADR/GDR, VIE](#1-what-does-the-security-actually-confer-share-class-dvr-adrgdr-vie) +- [2. Capital allocation: build the deployment ledger](#2-capital-allocation-build-the-deployment-ledger) +- [3. Guidance versus delivery: tabulate it, do not characterise it](#3-guidance-versus-delivery-tabulate-it-do-not-characterise-it) +- [4. Promoter / insider holding: level, trend and mechanism](#4-promoter--insider-holding-level-trend-and-mechanism) +- [5. Share pledging and encumbrance (India-critical)](#5-share-pledging-and-encumbrance-india-critical) +- [6. Insider transactions: read them one trade at a time](#6-insider-transactions-read-them-one-trade-at-a-time) +- [7. Related-party transactions and tunnelling](#7-related-party-transactions-and-tunnelling) +- [8. Group structure complexity and holdco opacity](#8-group-structure-complexity-and-holdco-opacity) +- [9. Capital raising, dilution and financing behaviour](#9-capital-raising-dilution-and-financing-behaviour) +- [10. Executive compensation and alignment](#10-executive-compensation-and-alignment) +- [11. Board independence, composition and functioning](#11-board-independence-composition-and-functioning) +- [12. Auditor: quality, tenure, fees, resignations](#12-auditor-quality-tenure-fees-resignations) +- [13. CFO and finance-team turnover](#13-cfo-and-finance-team-turnover) +- [14. Minority-shareholder rights architecture](#14-minority-shareholder-rights-architecture) +- [15. Succession and key-man risk](#15-succession-and-key-man-risk) +- [16. Integrity, regulatory history and disclosure quality](#16-integrity-regulatory-history-and-disclosure-quality) +- [17. Sector translation: where these checks change or invert](#17-sector-translation-where-these-checks-change-or-invert) +- [18. Scoring, weighting and how to write it up](#18-scoring-weighting-and-how-to-write-it-up) +- [Checklist](#checklist) + +--- + +## 0. How to run this dimension + +Three rules before you start. + +**Governance is a multiplier and a gate, not an additive score line.** Good governance does not add much to the case for a mediocre business. Bad governance subtracts from everything — it widens the discount rate, caps the multiple you can justify, and in the severe cases it invalidates the analysis entirely rather than costing it a few points. Treat a small number of findings as hard kill criteria (Section 18), and treat the rest as an adjustment to the required margin of safety. + +**Separate structure from behaviour.** Structure is what the documents permit: share classes, board composition, RPT approval thresholds, group tree. Behaviour is what the controller has actually done with that latitude over a decade. A concentrated, founder-controlled structure with a decade of clean behaviour is usually a better holding than a textbook-compliant structure run by someone with a record. Score both, and never let a compliance checklist substitute for the track record. + +**Everything here is evidence-based or it is not written.** Governance is where an analyst is most tempted to editorialise. Every claim you make must trace to a specific filing, disclosure, vote, transaction or dated statement. "Management seems promoter-friendly" is worthless; "royalty to the parent rose from 1.8% to 3.5% of sales over four years while EBITDA margin fell 200bp, disclosed in Note 41" is a finding. + +**Where to look.** + +| Item | India (NSE/BSE, Companies Act 2013, SEBI LODR) | US / global (SEC EDGAR) | +|---|---|---| +| Ownership and its trend | Shareholding pattern filed quarterly under LODR Reg 31 (within 21 days of quarter-end); BSE/NSE corporate-announcements pages | DEF 14A beneficial-ownership table; SC 13D/13G and their amendments | +| Insider trades | SEBI PIT Reg 7(2) disclosures (trades above ₹10 lakh in a quarter, filed within 2 trading days); SAST Reg 29 for substantial acquisitions | Forms 3, 4 (within 2 business days) and 5 | +| Pledges | SAST Reg 31 encumbrance disclosures; shareholding-pattern pledge table | Rarely disclosed; look in 13D Item 6, margin-loan disclosures and proxy pledging policy | +| Related parties | Notes to accounts (Ind-AS 24); LODR Reg 23 RPT policy; half-yearly RPT disclosures to exchanges | Notes (ASC 850 / IAS 24); proxy "Certain Relationships and Related Transactions" | +| Board and pay | Corporate Governance Report in the annual report; Reg 27 quarterly CG report; MGT-7 | DEF 14A in full, including CD&A, pay ratio, pay-versus-performance table | +| Auditor | Auditor's report, CARO 2020 annexure, ICFR opinion under s.143(3)(i), Form ADT-3 on resignation, NFRA orders | Audit report, Item 9A (ICFR), 8-K Items 4.01 (auditor change) and 4.02 (non-reliance), PCAOB Form AP and inspection reports | +| Track record | 10 years of annual reports, MD&A, concall transcripts (LODR Reg 46 requires transcripts within 5 working days), analyst-meet decks | 10-K MD&A, earnings-call transcripts, investor-day decks, 8-K guidance releases | +| Integrity record | SEBI orders and adjudications, NCLT/NCLAT, SFIO, income-tax search reports, IiAS / SES / InGovern proxy notes | SEC litigation releases and AAERs, DOJ, class-action dockets, ISS / Glass Lewis reports | + +For foreign private issuers filing 20-F, note that the proxy rules do not apply, there is no DEF 14A, compensation may be disclosed only in aggregate, and the company may elect home-country governance practice in place of NYSE/Nasdaq standards (disclosed in Item 16G). The absence of disclosure is not the absence of a problem — say so explicitly rather than scoring the gap as neutral. + +--- + +## 1. What does the security actually confer? Share class, DVR, ADR/GDR, VIE + +Do this first, before any other governance work, because it can change the identity of the thing you are analysing. Establish, in one paragraph: which legal entity you would own a claim on, what fraction of votes and of economics that claim carries, and by what legal mechanism the operating profits reach it. + +**Dual-class and superior voting rights.** Compute the wedge: voting share minus economic share. A founder holding 12% of economics and 60% of votes has a 48-point wedge, and every minority-protection mechanism downstream (say-on-pay, director elections, majority-of-minority votes) is decorative. Check for a sunset provision — time-based, ownership-based, or transfer/death-triggered — and its date. India: SEBI's 2019 framework permits superior-voting-rights (SR) shares for founders of intensive-technology companies at IPO, with a sunset (5 years, extendable once by shareholder resolution) and coat-tail provisions that collapse SR to ordinary voting on specified resolutions. US: no sunset is required by law, so read the charter. + +**DVR (India).** Differential-voting-rights shares in India have historically carried *fewer* votes plus a higher dividend, and they have persistently traded at a large discount to the ordinary share — a discount driven by low liquidity and index exclusion as much as by the voting differential. If you are analysing a DVR line, value it separately: apply the company analysis to the business but the pricing to the specific security, and state the historical discount range and whether any conversion or cancellation scheme is pending. Never quote the ordinary-share multiple as though it applied to the DVR. + +**ADR / GDR.** Determine sponsored versus unsponsored; the ratio of ADS to underlying share; the depositary's fees (custody pass-through, typically deducted from dividends); whether the ADR holder can vote and by what instruction mechanism (many depositaries vote uninstructed shares with management); fungibility and whether the ADR can be converted to local shares; and the withholding-tax treatment of the dividend. An ADR premium or discount to the local line, adjusted for the ratio and FX, is a real fact about capital-flow restrictions, not an arbitrage you can assume away. + +**VIE and contractual control.** For China-domiciled ADRs and structurally similar EM listings, the listed Cayman holdco frequently does *not* own the operating company. It owns a wholly foreign-owned enterprise (WFOE) that holds a bundle of contracts — exclusive service agreements, equity pledges, powers of attorney — over an onshore entity owned by founders, engineered to satisfy foreign-ownership restrictions in licensed sectors. Establish: whether the operating licences, IP and cash sit inside or outside the consolidated legal perimeter; whether those contracts have ever been tested and enforced in the local courts; the legal route by which onshore cash is upstreamed as dividends and whether capital controls or tax gross-ups impede it; and audit-inspection access (PCAOB inspection status and HFCAA delisting exposure). If the answer is "profitable operating company, contractual claim only, unenforced in court, restricted upstreaming," you are not buying the earnings — you are buying a promise to route the earnings, and that belongs at the top of the risk section, not in a footnote. The same test applies in miniature anywhere the listed entity is a thin holdco whose value resides in entities it does not fully control (Section 8). + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Voting/economic wedge | Insider voting % − insider economic % | 0; any wedge above ~10pts needs explicit justification | Measures how much control has been bought without proportionate capital at risk | +| Sunset horizon | Years until superior votes collapse to one-share-one-vote | Defined and dated | An undated wedge is permanent entrenchment | +| DVR discount (India) | (Ordinary price − DVR price) ÷ ordinary price, vs its own 5-year range | Judge against own history only | Establishes whether the discount is normal or a signal | +| ADR ratio and fees | ADS-to-share ratio; depositary fee per ADS per year | Fees small relative to yield | Silently reduces realised income and distorts naive per-share comparisons | +| Consolidated-perimeter test | % of revenue/profit consolidated via contracts rather than equity | 0% for a straightforward company | Contractual consolidation means legal title to earnings is untested | + +Indicative ranges throughout this file vary by market, cycle and period. Peer comparison and the company's own history override every absolute band. + +--- + +## 2. Capital allocation: build the deployment ledger + +Over a decade, capital allocation is the largest single driver of per-share value, and it is the most persistent, most predictive management trait you can observe. Do not assess it with adjectives. Build a ledger. + +**The method.** For the last 7–10 years, tabulate every source and use of capital, then attach a return to each use. + +| Column | What goes in it | +|---|---| +| Year | Fiscal year of commitment | +| Source | Operating cash flow, debt raised, equity raised, asset sale | +| Use | Maintenance capex, growth capex, acquisition, buyback, dividend, debt repayment, cash build | +| Amount | In reporting currency (₹ crore for India; state units) | +| Promised return | What management said at announcement: IRR, payback, capacity, accretion, synergy — quote it with the date and source | +| Realised outcome | Incremental revenue/EBIT actually attributable, capacity actually commissioned, synergies actually visible in the segment numbers | +| Implied incremental ROIC | Incremental NOPAT ÷ capital deployed, once the asset is ramped | +| vs WACC | Spread in basis points | + +**Incremental ROIC — compute it properly.** Aggregate ROIC is dominated by legacy assets and hides recent decisions. Use return on incremental invested capital, lagged for ramp: + +- RoIIC = (NOPAT_t − NOPAT_{t−n}) ÷ (Invested capital_{t−1} − Invested capital_{t−n−1}), with n = 3 to 5 years, and invested capital lagged by at least a year because capital does not earn on the day it is spent. +- Compute it on a rolling basis and plot it. A business with 25% aggregate ROIC and 6% RoIIC is a good business being converted into a mediocre one; that fact is invisible in the headline ratio and is exactly the sort of single-metric error the skill's governing principle warns against. +- Sanity-check against the growth identity: sustainable growth ≈ reinvestment rate × incremental ROIC. If management guides to growth that this identity cannot produce at their historical incremental returns, either the returns must improve (why?) or the growth requires external capital (dilution — Section 9). +- Cross-check with the definitions and normalisation rules in `references/05-returns-and-dupont.md`; do not re-derive invested capital differently here. + +**Acquisitions.** Track cumulative goodwill and acquired intangibles as a share of total assets, and every subsequent impairment. Impairment is the accounting system finally admitting that the price paid exceeded the value received — a recurring impairment pattern is a confession of serial overpayment, and you should read each one as a repayment of a prior year's reported earnings. For serial acquirers, also run the roll-up distortions in `references/07-forensic-red-flags.md`: acquired growth presented as organic, restructuring charges that never end, and purchase accounting that suppresses acquired-entity revenue then flatters subsequent growth. + +**Buybacks.** A buyback is a capital allocation decision like any other and must be scored on price, not on existence. Compare the average repurchase price to your own intrinsic-value estimate for that year, or as a proxy to the multiple (P/E, EV/EBIT, P/B) at repurchase against the company's own 10-year range. Buying back stock in the top decile of the historical multiple, while simultaneously issuing cheap equity or options to insiders, is value transfer dressed as shareholder return. India-specific: buybacks may be by tender offer (with the mandated reservation for small shareholders) or open market, and the tax treatment changed materially in October 2024 — proceeds are now taxed in the shareholder's hands as deemed dividend rather than through the company-level buyback tax, which changed the buyback-versus-dividend calculus for Indian issuers. Do not apply pre-2024 payout logic to post-2024 decisions. + +**Dividends and debt paydown** are the honest options and should be scored positively when the alternative uses earn below WACC. A company with sub-WACC incremental returns that keeps reinvesting is destroying value more surely than one that pays out. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| RoIIC (3–5y) | Δ NOPAT ÷ Δ invested capital, lagged | Above WACC, and not falling | The only measure of whether *recent* decisions created value | +| ROIC − WACC spread | Aggregate ROIC less WACC, 5-year trend | Positive and stable | Sub-WACC growth destroys value; see `06-valuation.md` for WACC derivation | +| Cumulative FCF vs cumulative capital raised | Σ FCF (10y) ÷ Σ (equity + net debt raised) | >1 for a self-funding business | Distinguishes a compounder from a capital sink | +| Goodwill + acquired intangibles / total assets | From balance sheet | Judge against acquisition strategy | High values make reported ROE flattering and impairment risk structural | +| Cumulative impairments / cumulative acquisition spend | Sum both over 10 years | Near zero | Direct measure of M&A overpayment | +| Buyback multiple percentile | Multiple paid at repurchase vs own 10-year range | Below median | Tests whether buybacks were opportunistic or price-insensitive | +| TSR vs sector over CEO tenure | Total return, CEO start to now, against sector index | Above sector | The bluntest available scorecard; use as a check, never alone | + +--- + +## 3. Guidance versus delivery: tabulate it, do not characterise it + +Credibility is measurable. Build a table of every *quantified* forward statement management has made over the last 3–5 years and mark it to actual. + +| Date | Source | Statement | Horizon | Target | Actual | Variance | +|---|---|---|---|---|---|---| +| e.g. Q2 concall | Transcript | "capacity commissioned by Q4" | 2 quarters | Commissioning date | Actual date | Slip in quarters | + +Include: revenue growth, margin targets, capex budgets, capacity commissioning dates, order-book conversion, debt-reduction targets, acquisition synergies, product launch dates, store/branch openings, and stated payout policy. Then compute a hit rate and a mean *signed* error, because the sign matters: chronic over-promising is a credibility failure that should widen your discount rate; chronic sandbagging is a different behaviour with different implications for how to read current guidance. + +**Where guidance lives.** US issuers typically give formal guidance in the earnings release furnished on Form 8-K, repeated in the 10-Q/10-K MD&A. Indian issuers frequently give no formal guidance in filings at all, and the commitments live only in the concall — which is why LODR Reg 46 transcript availability (audio/video within 24 hours, transcript within 5 working days) matters so much for this exercise. Read the transcripts, not the summaries. + +**What to do with it.** A management team with a documented history of missing its own targets by wide margins has forfeited the right to have its forward statements used as an input in your model. State that explicitly and haircut the forecast, or model only what the existing asset base can produce. Conversely, a team that has hit dated, specific, falsifiable targets across a downturn has earned some forecast credibility — and note that the willingness to make *falsifiable* statements at all is itself a governance signal. Vague, unfalsifiable strategy language ("we will drive shareholder value") is an evasion, not a target. + +--- + +## 4. Promoter / insider holding: level, trend and mechanism + +The trend matters more than the level, and the mechanism matters more than the trend. + +**Read the mechanism, not just the delta.** A rising promoter stake means very different things depending on how it rose: open-market purchases with personal cash (strong positive), creeping acquisition within the SAST 5%-per-financial-year limit (positive), a preferential allotment of shares or warrants to the promoter at a formula price during a depressed market (self-dealing dressed as commitment — see Section 9), or a fall in the denominator via buyback (mechanical, no signal). A falling stake can be an ordinary estate-planning sale, a pledge invocation (Section 5), a dilution because the promoter did not participate in a raise, or an inter-se transfer within the promoter group that is not a sale at all. + +**India specifics.** Read the LODR Reg 31 shareholding pattern for at least 8–12 quarters, and read the *promoter group* table, not just "promoter" — stakes routinely migrate between family members, family trusts and promoter-group companies. Minimum public shareholding is 25%, so a promoter above 75% has a forced-sale overhang. The SAST open-offer trigger is 25%, and creeping acquisition beyond that is capped at 5% per financial year. Watch for promoter *reclassification* requests, which remove a person from the promoter group and with it certain disclosure and lock-in obligations — always ask why. For recently listed companies, map the IPO lock-in expiry calendar for promoter and pre-IPO investor shares, plus any anchor-investor lock-in; a known supply cliff is a price risk independent of fundamentals. + +**US specifics.** The proxy beneficial-ownership table is a point-in-time snapshot with its own record date; use SC 13D/13G (and their amendments) plus Form 4 history to build the trend. 13D signals an activist or control intent, 13G a passive position; a conversion from 13G to 13D is a material event. Note that beneficial ownership includes shares acquirable within 60 days, so option-heavy insiders look larger than their economic exposure. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Promoter / insider holding % | Latest shareholding pattern or proxy table | Sector- and market-relative; stability matters more than level | Skin in the game aligns the controller with minorities | +| 8–12 quarter trend | Absolute change in percentage points | Flat or rising | Persistent decline means the best-informed holders are reducing | +| Mechanism split | % of stake change from open market vs allotment vs dilution vs inter-se transfer | Open-market purchases dominant | Distinguishes conviction from self-allotment | +| Free float and institutional share | 100 − promoter %; DII/FII split and trend | Adequate float for liquidity | Low float distorts price discovery and raises impact cost | +| Beneficial-ownership opacity | % of promoter stake held via trusts, offshore vehicles or layered entities | Low and explained | Opaque holding chains obscure who actually controls and who is pledging | +| Lock-in / lock-up expiry (recent IPOs) | Date and volume of each tranche unlocking | Mapped in advance | Predictable supply shock | + +--- + +## 5. Share pledging and encumbrance (India-critical) + +This is the highest-yield India-specific governance check and has no close US equivalent, so run it on every Indian company and do not assume its absence elsewhere means it is irrelevant. + +**What it is.** Promoters borrow personally against their shareholding. The pledge sits outside the company's balance sheet, so the company can look conservatively financed while the controlling family is highly levered against the same equity you are buying. Disclosure comes via SAST Reg 31 encumbrance filings and the pledge column of the quarterly shareholding pattern. "Encumbrance" is defined broadly in SEBI's framework and includes non-disposal undertakings and similar arrangements, not just formal pledges — read the encumbrance number, not only the pledge number. + +**Why it is dangerous.** The exposure is reflexive. A price fall breaches the lender's loan-to-value threshold, triggering a margin call; if the promoter cannot post collateral, the lender invokes the pledge and sells into a falling market, which lowers the price, which triggers further calls. In the tail, the promoter loses control at the worst possible moment and the company acquires a distressed, motivated seller of its own stock. Before that point, a cash-strapped promoter has an acute incentive to move company cash toward personal obligations — which is why high pledging and rising related-party loans in the same year is one of the most reliable tunnelling signatures available (Section 7). + +**How to run it.** Pull the pledge percentage for 8 quarters. Express it two ways — as a share of promoter holding and as a share of total shares outstanding, because the second is the actual float-supply risk. Overlay the share price. Rising pledge percentage into a falling price means either fresh borrowing or an invocation already under way, and both are urgent. Read the disclosed purpose; "for business purposes of the company" is materially different from an undisclosed personal use. Identify the lender: NBFCs and promoter-affiliated lenders extend against collateral that a bank would refuse, and a pledge financed by a related entity may be circular funding rather than a genuine external loan. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Pledged % of promoter holding | Pledged shares ÷ promoter shares | 0 is clean; sustained >25% warrants a discount; >50% is severe | Direct measure of promoter financial stress and forced-sale risk | +| Pledged % of shares outstanding | Pledged shares ÷ total shares | Low relative to average daily volume | Converts pledge risk into the float that could hit the market | +| Trend over 8 quarters | Percentage-point change | Falling | Rising pledges into a falling stock is the pre-invocation pattern | +| Implied LTV | Pledged value at current price ÷ disclosed loan, where available | Comfortable headroom | Estimates how far the price can fall before a call | +| Encumbrance minus pledge | Disclosed encumbrance % less formal pledge % | Zero or explained | Captures non-disposal undertakings and side arrangements | +| Invocation events | Count in last 3 years | Zero | An invocation already occurred means the cascade has started | + +--- + +## 6. Insider transactions: read them one trade at a time + +Aggregate net insider buying is a weak signal because it mixes signal with mechanics. Go to the transaction level. + +**US — Form 4 transaction codes.** The code determines whether the trade carries any information at all: +- **P** — open-market purchase. The only strongly informative code. Real money, real decision. +- **S** — open-market sale. Informative only after you strip out pre-planned and mechanical sales. +- **A** — grant or award. No signal; it is compensation. +- **M** — option exercise. **F** — shares withheld for tax. A same-day M followed by S or F is a compensation event, not a view on value. Analysts who count these as "insider selling" manufacture false signals constantly. +- **G** — gift. **C** — conversion. Usually estate planning or instrument mechanics. + +Check the footnotes for 10b5-1 plan status. Since the 2023 amendments, officer and director plans carry a cooling-off period (the later of 90 days or two business days after the next periodic report, capped at 120 days), overlapping plans are restricted, single-trade plans are limited to one per 12 months, and adoption/termination must be disclosed quarterly (Item 408 of Reg S-K). That gives you two things: a genuine distinction between mechanical and discretionary sales, and a new signal — a plan *adopted or terminated* at a suspicious moment. Also check Item 402(x) disclosure on option-grant timing relative to material non-public information; award dates clustering just before good news or just after bad news is a live governance flag. + +**India — PIT and SAST.** SEBI (Prohibition of Insider Trading) Regulations require designated persons, promoters and directors to disclose trades exceeding ₹10 lakh in value in a calendar quarter within two trading days; these appear on the exchange websites. SAST Reg 29 requires disclosure on crossing 5% and on every 2% change thereafter. Additional India-specific checks: the trading-window closure around results (trades near the window edges deserve scrutiny), the contra-trade restriction (a designated person may not take an opposite trade within six months), the maintenance of a structured digital database of unpublished price-sensitive information, and whether the company has ever been the subject of a SEBI insider-trading proceeding. + +**What actually carries information.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Cluster score | Number of distinct insiders making open-market purchases within a 90-day window | 3+ buyers is a meaningful cluster | Independent decisions by several insiders is far stronger than one large trade | +| Trade size vs holding | Value of purchase ÷ insider's existing holding, and ÷ annual cash compensation | Material (>10–20% of holding, or >1× salary) | A token purchase is a press release; a large one is a decision | +| Discretionary sale share | Sales not under a pre-set plan ÷ total sales | Low | Isolates the informative subset from mechanical liquidation | +| Trade-to-news gap | Days between trade and the next material disclosure | Long | Systematically short gaps suggest information asymmetry or worse | +| Company-buys-insiders-sell | Overlap of buyback windows with insider sales | No overlap | Company capital supporting insider exits is a direct conflict | +| Silence signal | No insider buying despite a large price decline and public management optimism | Buying present | The cheapest possible confirmation of stated conviction, and its absence is informative | + +--- + +## 7. Related-party transactions and tunnelling + +RPTs are the primary channel through which controllers extract value from minorities. Read the full RPT schedule in the notes — every year, in full — and build a map of counterparties before you interpret any number. + +**What to quantify.** Sales to and purchases from related parties; loans, advances and deposits given; corporate guarantees issued; royalty, brand, trademark and technical-fee payments; management and consultancy fees; rent and property leases; asset purchases and sales; and remuneration to relatives of directors. Express each as a percentage of revenue, of PBT and of net worth, and plot the trend. A single year's RPT table tells you almost nothing; the five-year trajectory tells you whether extraction is intensifying. + +**The patterns that matter.** +- **Royalty and brand fees to a parent or promoter entity.** Classic in Indian subsidiaries of multinationals and in family groups. A royalty that rises as a percentage of sales while margins do not improve is a transfer, not a service. India: LODR Reg 23 requires majority-of-minority approval for royalty or brand payments to a related party exceeding 5% of annual consolidated turnover — check whether that threshold was approached, and whether the payment was structured to stay just below it. +- **Loans and advances to promoter entities**, especially interest-free or below-market, unsecured, or repeatedly rolled over. Then check whether they are being written off in "exceptional items." +- **Guarantees for unrelated promoter businesses.** Off-balance-sheet until they crystallise; size them against net worth. +- **Purchases through a single promoter-owned intermediary.** A captive distributor, logistics arm or raw-material supplier is a margin siphon that shows up as unexplained gross-margin underperformance versus peers. +- **Asset transfers near reporting dates** and at valuations supported only by a related valuer. +- **Related-party receivables ageing more slowly than third-party receivables** — the cleanest quantitative tunnelling test available, because it requires no judgement about pricing. + +**Approval quality (India).** Under LODR Reg 23 and s.188 of the Companies Act, RPTs require audit-committee approval by disinterested members, and material RPTs — above ₹1,000 crore or 10% of consolidated turnover, whichever is lower — require shareholder approval with related parties abstaining. Verify that this actually happened, and read the dissent. A high against-vote on an RPT resolution that passed only because the promoter group was arithmetically excluded but the institutions still lost is a strong signal about how minorities see the controller. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Total RPT value / revenue | Sum of RPT flows ÷ revenue | Low and stable; high is acceptable only where structurally necessary and priced transparently | Sizes the channel through which value can leave | +| Royalty + brand + management fees / PBT | From RPT note ÷ PBT, 5-year trend | Flat or falling as % of sales | Rising fees against flat margins is a transfer to the controller | +| Loans and advances to related parties / net worth | From RPT note and balance sheet | Near zero for an operating company | Company balance sheet financing the promoter | +| Guarantees to related parties / net worth | Contingent-liability note | Near zero | Off-balance-sheet exposure to entities you cannot analyse | +| RP receivable days vs third-party receivable days | Compute both separately | Similar or shorter for RPs | Divergence is tunnelling that needs no pricing judgement | +| Material RPTs approved by majority of minority | Count and against-vote % | All material RPTs approved; low dissent | Tests whether the approval architecture actually functions | + +--- + +## 8. Group structure complexity and holdco opacity + +Map the corporate tree before you interpret consolidated numbers. List subsidiaries, step-down subsidiaries, JVs, associates, trusts and offshore SPVs, with ownership percentages and jurisdictions. For India, the annual report's subsidiary list plus Form AOC-1 gives you the financial summary of each; MCA21 filings give you the group entities that are *not* subsidiaries but sit in the promoter group. + +Then answer four questions. **Where does the cash sit** relative to where the debt sits? A cash-rich subsidiary under a debt-laden listed parent means dividends must be upstreamed to service the debt, and minority interests in the subsidiary get paid first. **Are you structurally subordinated?** Debt at the operating company ranks ahead of the holdco's equity claim on that company. **Where is the value you are buying?** If the listed entity is a thin holdco whose assets are minority stakes in operating entities, you are buying a holdco discount that may never close, and you must value it sum-of-the-parts — route to `references/sectors/holdco-assetmgr.md`. **Why is it this complicated?** Complexity has legitimate causes (regulatory ring-fencing, JV partners, tax treaties, project finance at the SPV level). It also has illegitimate ones. Ask management for the rationale and judge whether the answer covers all the entities. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Subsidiary count and consolidation depth | Count entities and layers | Proportionate to the business | Proliferating entities with no disclosed activity is a hiding place | +| Intercompany loans + guarantees / net worth | From notes | Low | Measures how much of group solvency is internal circulation | +| Holdco vs opco debt split | Debt at listed entity vs at operating subsidiaries | Understood and stated | Determines structural subordination and dividend dependency | +| Entities in opaque jurisdictions | Count and % of assets | Zero or fully explained | Secrecy jurisdictions defeat verification | +| Holdco discount | Market cap ÷ sum-of-parts value of stakes | Judge against own history and peer holdcos | Persistent discounts are structural, not a mispricing you can assume closes | + +--- + +## 9. Capital raising, dilution and financing behaviour + +Per-share value is what you own. Build a 7–10 year share-count history and identify every event that changed it. + +**What to reconstruct.** Rights issues, QIPs and secondary offerings, preferential allotments, convertible bonds, warrants, ESOP/RSU grants and exercises, and buybacks. For each: who subscribed, at what price, and at what discount to the prevailing market. Then compute cumulative equity raised against cumulative FCF generated — a business that has raised more than it has produced across a full cycle is a capital sink regardless of its reported growth. + +**India specifics.** Preferential allotment pricing is formula-driven under SEBI ICDR (the higher of the 90-trading-day and 10-trading-day VWAP, with a specified relaxation regime); warrants require 25% upfront with 18 months to convert, which gives the holder a cheap 18-month option struck at a depressed-market price. Warrants issued to promoters during a downturn, converted after a recovery, are a well-worn route to increasing promoter stake at minority expense — always price the option value that was transferred. QIP pricing uses a two-week VWAP with a permitted discount of up to 5%. ESOP schemes fall under the SEBI (SBEB and Sweat Equity) Regulations; check the pool size, the exercise price relative to market, and the performance conditions. + +**US specifics.** Watch for at-the-market (ATM) programmes and shelf registrations that permit continuous issuance, convertible notes with reset features, and any structured or "toxic" financing with variable conversion prices — the latter is a near-terminal signal for small caps. Stock-based compensation should be treated as an expense in cash-flow terms and its dilution measured on the diluted count including unvested awards, per `references/03-earnings-quality.md`. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Diluted share-count CAGR | 5–10 year CAGR of fully diluted shares | ≤1–2% for a self-funding business; negative if buying back | The direct measure of how much of the business you keep | +| Cumulative equity raised ÷ cumulative FCF | 10-year sums | <1 | Distinguishes a compounder from a perennial capital consumer | +| Issue discount to market | (Market price − issue price) ÷ market price, per event | Small; large discounts to insiders are a transfer | Prices the wealth moved from minorities to subscribers | +| SBC / ESOP burn rate | Annual grants ÷ shares outstanding | ~1% or less outside early-stage | Compounds silently; large pools with no performance gate are pay, not alignment | +| Warrant option value to insiders (India) | Value of the 18-month option implicitly granted at the formula price | Zero or compensated | The favour is the optionality, not the price | +| Net issuance per share | Shares issued less repurchased, annually | Consistent direction | Issuing cheap to insiders while buying back dear is the classic two-handed transfer | + +--- + +## 10. Executive compensation and alignment + +Compensation design predicts behaviour better than any stated strategy. Read the actual plan documents, not the summary table. + +**What to extract.** Fixed pay, annual cash bonus, long-term equity (and its vesting horizon and performance conditions), pension, perquisites, severance terms and change-of-control triggers. Then identify the *metrics that gate the bonus*. Metrics that can be bought with capital — revenue growth, absolute EBITDA, adjusted EBITDA, total profit — reward empire building and encourage leverage and acquisitions. Metrics that resist manipulation — ROIC, FCF per share, relative TSR, economic profit — reward the behaviour you want. If a company's bonus plan pays on adjusted EBITDA and the adjustments are management-defined, the plan is paying for the adjustments. + +**India specifics.** Managerial remuneration is capped by s.197 of the Companies Act at 11% of net profits computed under s.198 (5% for a single MD/WTD, 10% for all of them together, 1% for non-executive directors where there is an MD, otherwise 3%), with excess requiring a shareholder special resolution — so read the resolution and the dissent when the cap is breached, particularly in a loss year where Schedule V limits apply. Aggregate the remuneration of *all* promoter-family members, including relatives holding office or place of profit, and express it as a percentage of PBT; family payouts are often individually modest and collectively large. The Reg 27 corporate-governance report and the annual report's remuneration section carry the median-employee pay ratio disclosures. + +**US specifics.** The DEF 14A CD&A, the Summary Compensation Table, the pay-ratio disclosure and the pay-versus-performance table (Item 402(v), showing Compensation Actually Paid against company TSR, peer TSR, net income and a company-selected measure) let you test alignment directly. Check clawback policy compliance with the Rule 10D-1 listing standards effective end-2023 — recovery of erroneously awarded incentive compensation on restatement is now mandatory, and how a board handled an actual clawback trigger is far more informative than the policy text. Read the say-on-pay result: sustained support below ~70–80% is significant institutional dissent, and a board that receives it and changes nothing has told you where power sits. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| CEO comp / net profit | Total comp ÷ PAT | Small; rising share needs explanation | Scales pay to what the business actually earns | +| Promoter-family aggregate comp / PBT (India) | Sum all related executives ÷ PBT | Low single digits at most | Catches extraction split across family members | +| Pay growth vs EPS/FCF/TSR growth | 3–5 year CAGRs side by side | Pay growth ≤ performance growth | Pay rising while owners lose is board capture | +| Long-term equity share of pay | Performance-linked equity ÷ total comp | Majority for senior executives | Fixed cash rewards tenure; equity rewards outcomes | +| Vesting horizon | Years to full vest, and post-vest holding requirement | 3+ years, with holding requirements | Short vesting rewards a quarter, not a decade | +| Quality of bonus metrics | Classify each KPI as manipulable or durable | Durable metrics dominant | Determines which behaviours get paid for | +| Say-on-pay / remuneration-resolution dissent | Against + abstain % | <10% | Measured institutional judgement, free of charge | +| Repricing and mega-grants | Count of option repricings or outsized grants after price falls | Zero | Repricing removes the downside that made the grant an incentive | + +--- + +## 11. Board independence, composition and functioning + +Assess genuine independence, not the label. Directors are classified as independent by the company; you classify them by evidence. + +**Adjust the count.** Deduct from the "independent" tally any director with: a prior executive role at the company or a group entity; family ties to the promoter; a professional relationship (law firm, bank, consultancy, audit) with the company; cross-directorships on other promoter-group boards; tenure long enough to have become part of the furniture; or a material commercial relationship disclosed in the RPT note. Report your adjusted independence percentage alongside the company's claimed figure and show the deductions. + +**India specifics.** LODR Reg 17 requires at least one-third independent directors where the chair is a non-executive unrelated to the promoter, and at least half where the chair is executive or promoter-related; the top 1,000 listed companies must have at least one woman independent director. Independent-director tenure is capped at two consecutive five-year terms with a cooling-off period (s.149), and since 2022 both appointment and removal of an independent director require a special resolution — which strengthens minorities somewhat, so check how such resolutions have actually been voted. Reg 18 requires an audit committee with a majority of independent members and financial literacy across it. Read the corporate-governance report for attendance, and read every independent-director resignation letter: SEBI requires the detailed reason to be disclosed, and resignations citing "pre-occupation" clustered around a contentious event are a signal regardless of the stated reason. + +**US specifics.** Exchange listing standards require a majority-independent board and fully independent audit, compensation and nominating committees, with the audit committee needing a financial expert (disclosed under Item 407(d)(5)). Foreign private issuers may follow home-country practice instead — check Item 16G of the 20-F before assuming any of this applies. Read director-election vote results: a director with 15%+ withheld votes has been formally rebuked. Check ISS/Glass Lewis recommendations and, in India, IiAS/SES/InGovern notes, for the specific reasons given. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Adjusted independence % | Genuinely independent directors ÷ board size, after deductions | Majority; at minimum the statutory floor | The board is the only structural check on a controller | +| Directors with tenure >9–10 years | Count and % | Low, with visible refreshment | Long tenure erodes independence of mind regardless of formal status | +| Chair/CEO separation | Yes/no; lead independent director if combined | Separated, or a genuinely empowered lead independent director | Concentrating both roles removes the agenda-setting check | +| Committee independence | Audit / nomination / remuneration composition | Fully independent; audit chair financially expert | Committees are where governance actually happens | +| Attendance | Board and committee attendance % per director | >75% consistently | Absent directors cannot challenge anything | +| Overboarding | Number of other listed boards per director | ≤4–5, fewer for executives | Capacity constrains scrutiny | +| Independent-director churn | Resignations in 3 years and stated reasons | Low; reasons benign | Resignations citing governance are among the strongest single signals available | +| Against-votes on director elections | Highest against/withheld % in last 3 AGMs | <10% | Independent institutional judgement, already tabulated for you | + +--- + +## 12. Auditor: quality, tenure, fees, resignations + +The auditor is the last independent gatekeeper on the numbers everything else depends on. + +**Establish the facts.** Who is the auditor; how long have they held the engagement; when was the last rotation; what are audit fees versus non-audit and tax fees paid to the same firm and its network; is the firm's scale and geographic footprint appropriate to the group's size and jurisdictions. India requires rotation under s.139 — a maximum of five consecutive years for an individual auditor and ten for a firm, with a five-year cooling-off — so the presence of the same firm beyond that is itself a question. In the US, tenure is disclosed in the audit report and can run for decades; long tenure is not disqualifying by itself but combines badly with high non-audit fees. + +**Read the opinion properly.** Work through: the opinion type (unqualified, qualified, adverse, disclaimer); emphasis-of-matter and material-uncertainty-related-to-going-concern paragraphs; and the Key Audit Matters (India/IFRS) or Critical Audit Matters (US). KAMs/CAMs are the auditor telling you exactly which balances required the most judgement — treat them as a to-do list for your forensic pass, not as boilerplate. In India also read the CARO 2020 annexure in full: it carries specific, checkable statements on undisclosed income, wilful defaulter status, diversion of short-term funds to long-term use, loans to related parties, benami proceedings and whistle-blower complaints. Read the ICFR opinion under s.143(3)(i); in the US read Item 9A and note whether an auditor attestation on internal control was even required — non-accelerated filers and emerging growth companies are exempt from 404(b), so a clean-looking ICFR section may reflect management assertion only. + +**Changes and resignations are the high-severity events.** In the US, an auditor change is reported on Form 8-K Item 4.01, including whether there were disagreements and whether the prior auditor's reports contained adverse or qualified opinions; a restatement appears at Item 4.02 (non-reliance). Read the outgoing auditor's exhibit letter, which is the auditor's own account. In India, a resigning auditor files Form ADT-3 and SEBI's framework requires disclosure of detailed reasons, with the auditor expected to complete the limited review or audit for the period before resigning. Any resignation citing lack of information, lack of cooperation, or inability to obtain sufficient appropriate audit evidence is a near-automatic stop: the person with statutory access to the books declined to certify them. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Auditor tenure | Years since appointment; date of last rotation | Within statutory rotation limits (India); disclosed and considered (US) | Familiarity erodes scepticism | +| Non-audit fees / total auditor fees | From proxy fee table (US) or payments-to-auditors note (India) | <25–30% | Consulting revenue is the classic independence solvent | +| Auditor scale vs group complexity | Firm size and network footprint vs group revenue, entities, jurisdictions | Proportionate | A small firm auditing a large multinational group cannot do the work | +| KAM/CAM count and subject | Number and which balances | Few, stable, unsurprising | Names the accounts where judgement is concentrated | +| Modified opinions / going-concern language | Presence and wording | None | The most explicit warning in the document | +| ICFR material weaknesses | Count and nature; whether 404(b) attestation applied | None; attestation present | Weak controls make every other number less reliable | +| Auditor changes in 5 years | Count, with stated reasons | ≤1, routine rotation | Serial changes are auditor shopping | +| Resignation mid-cycle | Yes/no, with the reason given | No | Highest-severity single governance event on this list | + +--- + +## 13. CFO and finance-team turnover + +Treat this separately from CEO succession, because it is a different signal with a different mechanism. The numbers are produced by the finance organisation; instability there is one of the most reliable pre-restatement tells available from public filings. + +**How to run it.** Build a 5–7 year tenure history for the CFO, the chief accounting officer or controller, the treasurer, the head of internal audit and the audit-committee chair. In the US these departures are disclosed on Form 8-K Item 5.02 with dates; in India they are announced under LODR Reg 30 as material events, and the annual report's KMP list gives you the year-by-year names. Then look for the patterns rather than any single departure: + +- Departures announced close to a period end, a filing deadline, an audit completion or an auditor change. +- A resignation with no successor named, or a long interim period covered by a promoted controller. +- More than two CFOs in five years, or a CFO and an auditor changing within the same twelve months — a combination that should raise your forensic priority immediately. +- Boilerplate reasons ("personal reasons", "to pursue other opportunities") attached to a short-tenured, senior finance hire. +- Departure of the audit-committee chair specifically, which removes the board-side counterpart to the auditor. + +A single CFO departure with a named successor, an orderly transition period and a plausible destination is ordinary corporate life. A pattern is not. When you find a pattern, do not merely flag it — go back to `references/07-forensic-red-flags.md` and re-run the accruals and cash-existence tests on the periods those individuals signed. + +--- + +## 14. Minority-shareholder rights architecture + +This is where minority wealth is preserved or expropriated at inflection points. Assess the machinery *before* an inflection point arrives. + +**What to examine.** Voting structure and the wedge (Section 1). Anti-takeover devices: poison pills, staggered boards, supermajority requirements, and — India — the promoter's ability to block special resolutions. The dividend record: consistency through a cycle, and whether payout policy serves all holders or primarily supplies the promoter's cash needs. The company's own history at inflection points: past delisting attempts and the price offered, open offers under SAST and whether the price reflected control value, related-party mergers and the swap ratios used, and the treatment of minorities in prior rights issues (were they able to participate, and on what terms). Responsiveness to dissent: how many resolutions have drawn heavy institutional against-votes, and what the board did afterwards. + +**India specifics.** Delisting proceeds by reverse book building, with the framework amended in 2024 to also permit a fixed-price route at a stated premium to the floor price; the historical pattern is that promoters attempt delisting after price weakness, so a delisting proposal arriving at a cyclical trough is a value-capture attempt, not a windfall. Majority-of-minority approval applies to material RPTs and to certain royalty payments. Class-action and derivative remedies exist under s.245 of the Companies Act but are used rarely; assume weak ex-post remedies and price the ex-ante structure accordingly. Read the e-voting results published after each AGM: they give you institution-versus-promoter voting splits resolution by resolution, for free. + +**US and global specifics.** Check the charter and bylaws for the wedge, classified board, written-consent and special-meeting rights, exclusive-forum provisions, and the state of incorporation (Delaware's fiduciary case law is a meaningful protection that many other jurisdictions do not replicate). For controlled companies, exchange rules permit exemptions from majority-independent-board and independent-committee requirements — verify whether the company has taken them. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Voting/economic wedge | See Section 1 | Zero | Determines whether any minority vote can ever bind | +| Payout consistency | Dividend paid in each of the last 10 years; payout ratio range | Stable policy through a cycle | Erratic payout alongside strong cash flow suggests cash is being retained for other purposes | +| Past delisting / open-offer pricing | Premium or discount to pre-announcement price and to intrinsic value | Fair premium | The single most direct evidence of how the controller treats minorities in a squeeze | +| Against-management vote share | Highest against % across resolutions in last 3 AGMs | Low | Aggregated professional judgement on the same questions you are asking | +| Board response to dissent | Documented changes following a high against-vote | Visible response | A board that absorbs dissent and changes nothing is not accountable | +| Anti-takeover provisions | Pill, staggered board, supermajority, exclusive forum | Few | Entrenchment removes the market for corporate control as a discipline | + +--- + +## 15. Succession and key-man risk + +Underpriced because it is low-probability and high-impact. Assess it explicitly rather than assuming continuity. + +Ask: how much of the strategy, the customer relationships, the lender relationships and the regulatory goodwill is personal to one individual? Is there a disclosed succession plan and a named or identifiable successor? What is the tenure and depth of the second line, and what has senior attrition looked like over five years? Is a family transition approaching, and are there signs of intra-family disagreement over control — a dispute among heirs can freeze capital allocation for years and has done so repeatedly in Indian promoter groups. Are there key-man clauses in debt covenants, JV agreements or major customer contracts that would accelerate or terminate on a departure? For founder-led businesses, note age and health disclosure, and whether the founder's stake will pass through a trust or be sold. + +An abrupt, unexplained CEO or CFO departure with no successor named is a material event in its own right and should trigger a re-read of Sections 12 and 13, not a routine note. + +--- + +## 16. Integrity, regulatory history and disclosure quality + +Past misconduct predicts future misconduct better than almost any other governance variable. Screen the controlling group and the senior team, not just the company. + +**The record.** India: SEBI orders and adjudication proceedings against the company, promoters or directors; director disqualifications under s.164; SFIO investigations; income-tax search and survey actions; NCLT/NCLAT proceedings; wilful-defaulter listings; and past appearances on the ASM/GSM surveillance frameworks (see `references/16-market-mechanics-and-tax.md`). US: SEC litigation releases and Accounting and Auditing Enforcement Releases, DOJ actions, FCPA matters, securities class actions and their outcomes, and officer-and-director bars. Search under individual names as well as the corporate name — people move between vehicles. + +**Disclosure quality is a live, quarterly signal.** Score it on evidence: does the annual report discuss the segments that did badly with the same specificity as the ones that did well; does management name mistakes; is segment disclosure granular enough to test the story; do defined KPIs stay defined, or do definitions change in the year the metric turns down (a change in KPI definition is a red flag in its own right — see `references/07-forensic-red-flags.md`); are filings timely; how does management handle hostile analyst questions on the call — engagement versus deflection versus refusing to take the question. Run a year-over-year redline of the risk factors and the MD&A: the language management quietly adds or removes is often the earliest disclosure of a deteriorating situation. + +**Short-seller and activist reports.** When a credible report exists, read the primary document, then read the company's rebuttal, and grade the rebuttal on specificity. A point-by-point response with documents refutes; a press release about "malicious motives" and a legal threat does not. A refusal to answer the specific quantitative allegations is itself evidence, and should raise your forensic priority sharply. + +**Credit and covenant history.** Rating rationales from CRISIL/ICRA/CARE/India Ratings (India) or S&P/Moody's/Fitch (global) contain governance commentary you will not find in the annual report, including agency views on group support, related-party exposure and promoter pledges. A downgrade citing governance or information quality, an "issuer not cooperating" rating status in India, or a covenant waiver history are all direct evidence. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Regulatory actions against insiders | Count and severity, 10 years, by name | Zero | The strongest single predictor of recurrence | +| Filing timeliness | Delayed filings, extensions, restatements in 5 years | Zero | Late filings are usually a symptom, not a process failure | +| Rating trajectory | Direction over 5 years; any "issuer not cooperating" status (India) | Stable or improving | Agencies see covenant and liquidity data you do not | +| Contingent liabilities / net worth | From the contingent-liability note | Low and stable | Sizes the tail of unresolved disputes | +| Rebuttal specificity | Grade any response to credible allegations | Point-by-point with evidence | Distinguishes a wronged company from a cornered one | + +--- + +## 17. Sector translation: where these checks change or invert + +The governing principle applies to governance too. Do not carry a generic checklist into a sector where its terms are undefined. + +**Banks and NBFCs (India: `references/sectors/banks.md`, `references/sectors/nbfc.md`).** Capital allocation *is* underwriting; there is no meaningful ROIC/WACC test, so assess capital allocation as ROE versus cost of equity, plus credit-cost discipline across a full cycle. The dominant governance risks are connected lending, evergreening of stressed exposures and promoter-group borrowing. India-specific checks: RBI's asset-classification divergence disclosure (required when the regulator's assessment exceeds the bank's by specified thresholds) is the single most valuable governance disclosure in the sector; RBI fit-and-proper norms and MD/CEO tenure caps for private banks; promoter shareholding dilution roadmaps; and mandatory joint statutory auditors with capped tenure for larger banks and NBFCs. Pledging by a bank promoter carries different consequences because of ownership caps and regulatory approval requirements. + +**Insurers (`references/sectors/insurance.md`).** Capital allocation is judged on value of new business and embedded-value movement, not ROIC. Governance focus: reserving discipline and the appointed actuary's independence, distribution-related-party arrangements with a bancassurance parent, and IRDAI ownership and fit-and-proper rules. + +**REITs, InvITs and externally managed vehicles (`references/sectors/realestate-reit.md`).** The central governance question is the manager's fee structure. Fees on gross assets or on acquisitions reward growing the vehicle regardless of per-unit value; fees on distributable income or total return align better. Every sponsor asset dropped down into the trust is a related-party transaction and must be tested against independent valuation. Check unitholder voting rights, the sponsor's mandated holding and lock-in, related-party approval mechanics excluding the sponsor, and leverage caps. Standard "promoter pledging" and "board independence" tests translate only loosely; ask instead who appoints and can remove the manager. + +**Miners, oil and gas, and deep cyclicals (`references/sectors/metals-mining.md`, `references/sectors/oil-gas.md`).** Capital allocation is nearly the entire investment case: the record of committing capex at the top of the cycle versus counter-cyclically is the scorecard. The reserve statement is a second set of accounts, and the competent person's report (JORC, NI 43-101, SEC S-K 1300) is a second auditor — check the qualifications, independence and revision history of reserve estimates the same way you check the financial auditor. Add resource-nationalism, licence-renewal and royalty-regime risk to the integrity screen. + +**PSUs and government-controlled companies (India, `references/13-situations.md`).** The promoter is the state, so the tests change rather than disappear: dividend and buyback demands driven by fiscal need, cross-holding bailouts of other state entities, disinvestment overhang, extended vacancies in board and CMD positions, and pricing decisions taken as policy rather than as commerce. Minority interests are structurally subordinate to policy objectives — price that, do not argue with it. + +**Holdcos and conglomerates (`references/sectors/holdco-assetmgr.md`).** Section 8 becomes the main event: cross-holdings, the persistence of the discount, and whether cash flows up. + +**Early-stage and recently listed companies (`references/13-situations.md`).** Governance maturity lags growth. Expect founder control, thin boards, large option pools and lock-in expiry supply. Weight structure heavily because there is no behavioural track record to weight instead. + +--- + +## 18. Scoring, weighting and how to write it up + +**Hard stops.** Treat these as kill criteria under Stage 3 rather than as score deductions. Each one means the analysis cannot be completed with confidence, and the correct output is a documented decline, not a lower target price: + +- Auditor resigned or was dismissed citing lack of information, lack of cooperation, or inability to obtain sufficient appropriate audit evidence. +- Adverse opinion, disclaimer of opinion, or unresolved going-concern doubt without a credible, funded remediation plan. +- Regulator has found fraud or securities violations against the current promoter, CEO or CFO and they remain in post. +- Cash balances that fail the existence tests in `references/07-forensic-red-flags.md`. +- Related-party flows large enough that the minority-attributable economics cannot be reliably determined. +- The listed security does not confer legal claim on the operating assets and that claim has never been tested (Section 1), with no compensating structural protection. + +**Graduated adjustments.** Everything else feeds the sector-relative score per `references/11-scoring-rubric.md`, and — where you can justify it — an explicit increment to the cost of equity or a cut to the exit multiple in `references/06-valuation.md`. Say which one you applied and by how much. A governance concern that changes no number in the model is a concern you have not actually incorporated. + +**How to present it.** Three parts, in this order: what the security confers; the capital-allocation and guidance-delivery evidence, with the ledger and the tabulation; the specific governance findings with their source citations and a severity label. Then state the adjustment you made and where. Distinguish clearly between *structure I dislike* and *behaviour I can evidence* — the second is a finding, the first is a risk factor. And where disclosure simply does not exist (a 20-F filer with aggregate compensation only, an unlisted group entity with no public accounts), say that the check could not be run, rather than scoring the absence as a pass. + +--- + +## Checklist + +- [ ] Establish what the security confers: class, votes versus economics, sunset, DVR/ADR/GDR mechanics, VIE or contractual control. +- [ ] Compute the voting/economic wedge and state it in the report. +- [ ] Build the 7–10 year capital deployment ledger: source, use, amount, promised return, realised return. +- [ ] Compute RoIIC (3–5y, lagged) and compare to WACC and to aggregate ROIC. +- [ ] Score every major acquisition against its announcement promises; sum impairments against acquisition spend. +- [ ] Score buybacks on price paid versus the company's own historical multiple range. +- [ ] Tabulate every quantified guidance statement of the last 3–5 years against actuals; compute hit rate and mean signed error. +- [ ] Pull 8–12 quarters of shareholding pattern; identify the *mechanism* of every change in promoter/insider stake. +- [ ] India: pull pledge and total encumbrance as % of promoter holding and of shares outstanding, trend over 8 quarters, lender and purpose. +- [ ] Analyse insider trades transaction by transaction; strip Form 4 codes A/M/F; isolate discretionary trades; look for clusters. +- [ ] Read the full RPT note for 5 years; compute RPT/revenue, fees/PBT, loans and guarantees/net worth, and RP versus third-party receivable days. +- [ ] Verify that material RPTs received disinterested approval, and read the against-vote. +- [ ] Map the group tree: entity count, layers, jurisdictions, intercompany loans and guarantees, where cash sits versus debt. +- [ ] Build the 7–10 year diluted share-count history; price every issuance discount and every insider warrant. +- [ ] Compare cumulative equity raised to cumulative FCF over 10 years. +- [ ] Classify every bonus metric as manipulable or durable; compute pay versus performance and family aggregate pay versus PBT. +- [ ] Recompute board independence after deducting conflicted and long-tenured directors; check attendance, overboarding, committee composition. +- [ ] Read every independent-director resignation reason from the last three years. +- [ ] Record auditor identity, tenure, rotation compliance, non-audit fee share, KAMs/CAMs, CARO exceptions, ICFR findings. +- [ ] Check for any auditor change or resignation and read the outgoing auditor's own statement (8-K Item 4.01 / ADT-3). +- [ ] Build a 5–7 year CFO, controller, treasurer and audit-committee-chair tenure history; flag patterns, not single exits. +- [ ] Review minority-rights machinery: anti-takeover devices, past delisting/open-offer pricing, AGM e-voting splits, board response to dissent. +- [ ] Assess succession, bench strength, key-man covenants and family-transition dynamics. +- [ ] Screen every insider by name against SEBI/SEC/court records; grade disclosure candour and any short-seller rebuttal. +- [ ] Apply the sector translation before scoring: banks, insurers, REITs/InvITs, miners, PSUs and holdcos change the questions. +- [ ] Apply hard stops where they trigger; otherwise state the explicit valuation or scoring adjustment made, and where disclosure was unavailable, say so. diff --git a/finance/skills/stock-analysis/references/09-risk-and-macro.md b/finance/skills/stock-analysis/references/09-risk-and-macro.md new file mode 100644 index 00000000..fcf6c330 --- /dev/null +++ b/finance/skills/stock-analysis/references/09-risk-and-macro.md @@ -0,0 +1,473 @@ +# Risk Factors: Company, Macro and External + +Use this when: you are at Stage 7 building the bear case and invalidation triggers, or any time you need to convert a pile of "things that could go wrong" into a ranked, sized set of risks that actually changes the recommendation. + +Most risk sections are useless because they are inventories. Twenty bullet points, each true, none sized, none ranked, none monitorable — the reader learns nothing and the analyst has bought deniability rather than insight. Your job is the opposite: identify the two or three exposures that could permanently impair the equity, quantify them against the specific business, name the observable event that would tell you they are materialising, and be explicit about everything else you deliberately excluded. The governing rule of this skill applies here as hard as anywhere: a risk metric means nothing until you know the sector and the company's own history. Net debt/EBITDA of 5x is a red alert for a consumer-goods company, unremarkable for a regulated utility, and an undefined quantity for a bank. + +## Contents + +- [0. The method: from risk list to sized risk map](#0-the-method-from-risk-list-to-sized-risk-map) +- [1. Balance-sheet risk: leverage, liquidity, refinancing](#1-balance-sheet-risk-leverage-liquidity-refinancing) +- [2. Operating leverage and cost-structure rigidity](#2-operating-leverage-and-cost-structure-rigidity) +- [3. Concentration: customers, suppliers, geography](#3-concentration-customers-suppliers-geography) +- [4. Supply-chain single-source dependency and business continuity](#4-supply-chain-single-source-dependency-and-business-continuity) +- [5. FX: economic exposure and the hedging book](#5-fx-economic-exposure-and-the-hedging-book) +- [6. Commodity and input-cost exposure](#6-commodity-and-input-cost-exposure) +- [7. Interest-rate sensitivity](#7-interest-rate-sensitivity) +- [8. Regulatory, policy, subsidy and tariff dependency](#8-regulatory-policy-subsidy-and-tariff-dependency) +- [9. Litigation, antitrust and enforcement exposure mapping](#9-litigation-antitrust-and-enforcement-exposure-mapping) +- [10. Tax disputes and transfer pricing](#10-tax-disputes-and-transfer-pricing) +- [11. IP portfolio and IP litigation](#11-ip-portfolio-and-ip-litigation) +- [12. Cybersecurity, data privacy and IT resilience](#12-cybersecurity-data-privacy-and-it-resilience) +- [13. Organisational health and human capital](#13-organisational-health-and-human-capital) +- [14. Country, political and sovereign risk](#14-country-political-and-sovereign-risk) +- [15. Sanctions, export controls and geopolitics](#15-sanctions-export-controls-and-geopolitics) +- [16. ESG: climate physical and transition risk, cross-sector](#16-esg-climate-physical-and-transition-risk-cross-sector) +- [17. Technological disruption and the AI-obsolescence test](#17-technological-disruption-and-the-ai-obsolescence-test) +- [18. Tail risk, hidden liabilities and contagion](#18-tail-risk-hidden-liabilities-and-contagion) +- [19. Macro regime and cycle positioning: the top-down gate](#19-macro-regime-and-cycle-positioning-the-top-down-gate) +- [20. Broad-market valuation context](#20-broad-market-valuation-context) +- [21. Sector translation: where the standard risk lens breaks](#21-sector-translation-where-the-standard-risk-lens-breaks) +- [22. Writing the bear case and the invalidation triggers](#22-writing-the-bear-case-and-the-invalidation-triggers) +- [Checklist](#checklist) + +--- + +## 0. The method: from risk list to sized risk map + +Do this **first**, then use sections 1–18 as the sweep that populates it. The output of this file is a table of at most seven risks, not a taxonomy. + +### Step 1 — Sweep + +Walk sections 1–18 and write one line per exposure that is *actually present* in this business. Discard generic risks that apply to all equities ("economic conditions may deteriorate"). A risk earns its place only if you can name the mechanism: what specifically happens to revenue, margin, capital or the multiple. + +Source it from primary disclosure, not memory: +- **US/global:** 10-K Item 1A (Risk Factors), Item 3 (Legal Proceedings), Item 1C (Cybersecurity, mandatory from FY2023), Item 7A (Quantitative and Qualitative Disclosures About Market Risk — this is where FX, rate and commodity sensitivity tables live), and the Commitments & Contingencies note. Redline Item 1A against last year's 10-K: **new or newly specific risk language is management telling you something changed.** +- **India:** the annual report's Risk Management section and Board's Report, the contingent-liabilities note (Ind-AS 37 / Schedule III), CARO 2020 reporting — especially clause 3(vii)(b), disputed statutory dues with the forum where each is pending — related-party note, and SEBI LODR Regulation 30 material-event filings on the exchange. Concall Q&A is often the only place where a single-source dependency or a customer loss is discussed candidly. + +### Step 2 — Size each risk + +| Dimension | How to score | Note | +|---|---|---| +| **Severity (S)** | 1 = <5% of intrinsic value; 2 = 5–15%; 3 = 15–30%; 4 = 30–50%; 5 = >50%, or forces a dilutive raise / default | Size in value or EPS terms, not adjectives. "A 300bp gross-margin hit is roughly 25% of EBIT at this cost structure" beats "significant". | +| **Likelihood (L)** over your stated horizon | 1 = <5%; 2 = 5–15%; 3 = 15–35%; 4 = 35–60%; 5 = >60% | State the horizon explicitly (typically 3 years). Probability without a horizon is meaningless. | +| **Permanence** | Cyclical (recovers) / semi-permanent (years) / permanent impairment | The single most important column. | +| **Lead indicator** | The specific observable that moves first | If you cannot name one, the risk is unmonitorable — that is a sizing argument, not a footnote. | +| **Mitigant** | Hedge, insurance, contract, balance-sheet buffer — and its expiry | Hedges roll off. Always state the tenor. | + +Expected loss = midpoint(S%) × midpoint(L%). Rank by expected loss, then apply two overrides: + +1. **Permanence override.** A 10% chance of a permanent 60% impairment outranks a 60% chance of a temporary 15% drawdown, even though the expected losses are similar. Permanent capital loss is not recoverable by waiting; cyclical drawdown is. Rank on permanence first when the expected losses are within a factor of two. +2. **Solvency-first ordering.** Any risk that can force a distressed equity raise, a covenant breach or a default ranks above every margin-and-multiple risk regardless of arithmetic, because equity is subordinated and the recovery is typically zero. + +### Step 3 — Cluster correlated risks + +Risks that share a driver are one risk, not three. A company selling discretionary goods on credit to a single cyclical end-market has one risk — the end-market — expressing itself through volume, receivable losses and covenant headroom simultaneously. Listing them separately triples the apparent diversification of the risk map and understates the tail. Explicitly ask: **which of these fire together?** Leverage, concentration and illiquidity are the classic cluster; they compound precisely when financing disappears. + +### Step 4 — Test what is already in the price + +A well-known risk that has already de-rated the stock is not a reason to avoid it; an unpriced risk is. Cross-check against the reverse-DCF in `06-valuation.md`: if the market-implied growth is already near zero, the cyclical-demand risk is largely priced and the *upside* asymmetry may be the more interesting finding. Say which of your top risks you believe are priced and which are not, and why you think you are seeing something the market is not. + +### Step 5 — Publish the map + +Report the top five to seven, with S, L, permanence, lead indicator and mitigant. Then add one line naming the risks you considered and deliberately excluded, and why. Excluding a risk explicitly is analysis; omitting it silently is not. + +--- + +## 1. Balance-sheet risk: leverage, liquidity, refinancing + +Full treatment is in `04-balance-sheet-and-cashflow.md`; here you are asking only one question — **can this company be forced into a transaction it does not want?** Forced asset sales, rescue rights issues and covenant renegotiations are where permanent equity loss happens. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Net debt/EBITDA | (Debt + leases − cash & liquid investments) ÷ EBITDA, on **trough** EBITDA not peak | <2x for cyclicals; <3x general industry; 4–7x normal for utilities/infra with contracted cash flows; undefined for banks and NBFCs | The peak-EBITDA denominator is the most common leverage error; a cyclical at 2.5x on peak earnings is at 5x mid-cycle | +| EBIT interest coverage | EBIT ÷ gross interest expense | >4–5x comfortable; <2–3x fragile | Coverage fails before leverage ratios do, and coverage covenants trip first | +| Covenant headroom | Distance to the tightest covenant, in % of the tested metric | >20–25% | Under ~15% management starts managing to the covenant instead of the business | +| Near-term maturity cover | (Cash + undrawn **committed** facilities) ÷ debt maturing in 12–24 months | >1.5x | Solvent companies fail from illiquidity; uncommitted lines vanish when needed | +| Weighted-average maturity | Debt-weighted years to maturity | Longer than the asset payback | Funding long-life assets with short paper (commercial paper, working-capital lines) is the classic ALM failure | +| Structural subordination | Where the debt sits: parent vs operating subsidiary | — | Cash at a subsidiary behind subsidiary-level debt is not available to the parent's creditors, let alone shareholders | + +Hunt for hidden debt: leases (IFRS 16 / Ind-AS 116 / ASC 842), receivables factoring and securitisation, supply-chain finance / reverse factoring parked in trade payables, PIK/toggle notes deferring cash interest, guarantees to associates and JVs, put options over minority stakes. + +**India-specific.** Check promoter share pledging (shareholding pattern, quarterly). A pledged promoter block plus falling price creates a margin-call feedback loop that destroys the equity independently of operating performance. Also check inter-corporate deposits and guarantees to group entities in the related-party note — the leakage channel is loans out, not just sales. + +--- + +## 2. Operating leverage and cost-structure rigidity + +Financial leverage magnifies whatever operating leverage delivers; the two multiply. Estimate the degree of operating leverage (DOL) as %ΔEBIT ÷ %ΔRevenue over the last downturn, and sanity-check it against a fixed/variable cost split. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| DOL | %Δ EBIT ÷ %Δ revenue, measured across a real downturn | <2x flexible; >3–4x fragile | Tells you how far revenue can fall before profit disappears | +| Fixed costs % of total | Employee cost + depreciation + rent + other fixed opex ÷ total cost | Sector-dependent; compare to peers only | Airlines, hotels, semiconductors, steel are structurally high; distribution and services are low | +| Contribution margin | (Revenue − variable cost) ÷ revenue | — | High contribution margin plus high fixed cost = violent operating leverage both ways | +| Breakeven utilisation | Utilisation/occupancy/load factor at which EBIT = 0 | Well below current | For hotels, airlines, cement, steel, this single number is the risk | + +Run a −10% and −20% revenue scenario explicitly and report EBIT, interest cover and covenant headroom at each. That one table does more work than a page of prose. Note where costs genuinely cannot flex: unionised labour, take-or-pay input contracts, long leases, minimum-offtake obligations, committed capex already under contract. + +--- + +## 3. Concentration: customers, suppliers, geography + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Top-customer revenue share | % of revenue from largest customer | <10% comfortable; >20% material; >30% is a single-point-of-failure | Loss or renegotiation by one buyer can reset earnings power overnight | +| Top-5 / top-10 share | Cumulative | <40% / <60% typical | Also proxies bargaining power over price and payment terms | +| Customer HHI | Σ (customer revenue share)² | — | Better than a top-1 number when the tail matters | +| Net revenue retention (subscription) | (Starting ARR + expansion − churn − downgrade) ÷ starting ARR | >100% healthy; >110–120% strong | Concentration is tolerable if retention is proven; concentration plus churn is not | +| Revenue/EBIT/assets by geography | Segment note | — | Demand concentration and asset concentration are different risks; separate them | + +**Disclosure.** US 10-K requires naming any customer >10% of revenue (ASC 280). India: Ind-AS 108 requires disclosure of revenue from customers exceeding 10%, though the customer is usually unnamed — the concall and the receivables ageing are your cross-checks. + +Escalating concerns, in order: a large customer that is itself in distress; a large customer that is vertically integrating or in-sourcing; concentration that is *rising*; dependence on a single platform, app store, distributor or channel that controls access to the customer; and — for India — dependence on government or PSU orders where payment cycles stretch and receivables become an unfunded working-capital loan (state power distribution companies are the canonical case). + +--- + +## 4. Supply-chain single-source dependency and business continuity + +Balance-sheet strength cannot offset a plant that cannot run. This is a physical, not financial, risk and requires a physical map. + +**Build a dependency map.** For each critical input: number of qualified suppliers, whether the sole source is contractual or technical (a qualified-vendor lock is much harder to break than a commercial one), lead time, days of inventory held against that lead time, geographic location of the supplier's *own* production, and the availability of a second source and how long qualification would take. Semiconductor, pharma API, specialty chemical and aerospace supply chains routinely have sole-source nodes three tiers upstream that tier-1 disclosure never reveals. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Sole-sourced % of COGS | Value of inputs with no qualified alternative ÷ COGS | As low as possible; >15–20% is a live risk | The size of the production you cannot protect | +| Inventory cover vs lead time | Days of inventory ÷ supplier lead time in days | >1.5–2x for critical parts | Thin buffers against long lead times mean any disruption stops the line | +| Supplier geographic HHI | Concentration of sourcing by country | — | One country + one hazard (earthquake, export ban, conflict) = correlated failure | +| Single-site revenue exposure | % of revenue produced at the largest single plant/site/data centre | <30–40% | Insurance pays for the asset, not for the lost customer relationship | + +**Business continuity.** Ask what the recovery time would be, not just whether a plan exists: alternate site capacity, qualification time for a replacement supplier, insurance including **business-interruption and contingent business-interruption** cover, and the deductible/sub-limits. Note that BI insurance replaces gross profit for a capped period; it does not replace a customer that qualified a competitor in the meantime. + +**India-specific.** Add pharma API and key-starting-material dependence on China, monsoon and water-availability risk for agri-linked and thermal/hydro assets, land acquisition and environmental-clearance delays for greenfield capacity, and freight/port chokepoints for exporters. + +--- + +## 5. FX: economic exposure and the hedging book + +The reported FX gain/loss line is the least important part of this. Analyse **economic** exposure: the mismatch between the currency of revenue, the currency of cost, and the currency of debt. + +Build a three-row table by currency: % of revenue, % of costs, % of debt. Then: + +| Exposure type | What it does | How to size it | +|---|---|---| +| Transaction | Contracted flows in a foreign currency | Net exposure per currency × expected move | +| Translation | Foreign subsidiaries restated into the reporting currency | Watch the cumulative translation adjustment (CTA) in equity; it is non-cash but it is real value | +| Economic / competitive | A competitor's currency devalues and undercuts you at home | Not on the balance sheet at all; the most-missed exposure | +| Balance-sheet mismatch | Hard-currency debt against local-currency revenue | The classic emerging-market blow-up; a devaluation becomes a solvency event | + +**Interrogate the hedging book, do not just note that one exists.** Hedge ratio, tenor, instrument (forwards vs options vs natural hedge), the rate at which existing hedges are struck versus spot, and the roll-off schedule. A company hedged 80% for 12 months at rates far better than spot is enjoying a temporary earnings subsidy that will reverse — that is a forecastable margin headwind, not a risk. Say when it lands. Hedges delay exposure; they do not remove it. + +- **US/global:** Item 7A carries the sensitivity table (typically EPS or fair-value impact of a 10% adverse move). Check for hyperinflationary subsidiaries under IAS 29 / ASC 830. +- **India:** the notes disclose hedged and **unhedged** foreign-currency exposure — the unhedged line is the one that matters. External commercial borrowings (ECB) carry RBI hedging expectations; IT exporters typically run long-dated USD forward books whose realised rate can differ materially from spot for several quarters. +- **Investor level (separate decision):** for a foreign-listed holding, the investor's base-currency translation is a distinct exposure from the company's operating FX. A correct stock call in a depreciating listing currency can still lose money. Flag it; do not conflate it with company risk. + +--- + +## 6. Commodity and input-cost exposure + +Two different situations, and conflating them produces nonsense: + +1. **Price taker on output** (miners, steel, oil and gas producers, commodity chemicals). The commodity price *is* the business, not a risk factor bolted onto it. The real risk is position on the industry cost curve — a first-quartile producer survives the trough that kills the fourth quartile — plus balance-sheet capacity to sit through the trough. Do not present "commodity prices may fall" as a risk; present the trough-price EBITDA and the cash cost per tonne/barrel versus the curve. +2. **Price taker on input** (FMCG, autos, cement, packaging, food processing). Here the question is pass-through: magnitude, lag and mechanism. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Key input % of COGS | Largest single raw material or energy ÷ COGS | — | Determines whether a 20% input move is noise or the whole margin | +| Gross-margin sensitivity | bps of gross margin per 10% input-price move, assuming no pass-through | — | Converts a commodity chart into an EPS number | +| Pass-through lag | Months from input move to realised price change | 1 quarter good; 2–3 quarters painful | The lag, not the level, is what hits reported quarters | +| Hedge coverage and tenor | % of next-12-month requirement hedged, and at what strike | — | Same roll-off logic as FX | + +A useful framing: **a distributor at 4% operating margin cannot absorb a 200bp input shock — it has no margin to absorb it with.** Thin-margin, high-throughput businesses are far more input-fragile than their revenue scale suggests. Contractual escalators (common in EPC, logistics and long-term supply agreements) materially change the answer; check whether they exist, what index they track, and the reset frequency. + +--- + +## 7. Interest-rate sensitivity + +Rates hit three channels at once — interest expense, demand, and the discount rate applied to the multiple — which is why rate shocks de-rate long-duration equities so violently. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Floating-rate debt share | Floating debt ÷ total debt | Lower is safer in a tightening cycle; not per se bad | Direct EPS transmission | +| EPS impact per +100bp | Floating debt × 1% × (1 − tax rate) ÷ shares | <3–5% of EPS is tolerable | Makes the exposure concrete | +| Repricing wall | Fixed debt maturing in the next 24 months × (current market rate − coupon) | — | Cheap legacy fixed debt repricing higher is a permanent, forecastable earnings cut | +| Duration gap (financials) | Asset duration − liability duration | Near zero for banks; deliberately positive for life insurers | See §21 — for lenders this replaces most of the above | +| Demand beta to rates | Historical volume correlation with policy rate / mortgage rate | — | Housing, autos, consumer durables, capital goods transmit rates through demand before interest expense | + +Long-duration equities (loss-making growth, businesses whose value sits in terminal cash flows) carry rate risk in the multiple even with zero debt. Say so; it is frequently the largest rate exposure in the name. + +--- + +## 8. Regulatory, policy, subsidy and tariff dependency + +The question that matters: **what fraction of current profit exists because of a policy that could be withdrawn?** + +Map the regimes that govern the business — price controls, licensing, environmental, sector regulators, data protection, tariffs — then quantify dependency: + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Subsidy/incentive-dependent profit | Incentive income + tariff-protected margin ÷ EBIT | The lower the better; >25% is a policy-reversal bet | Distinguishes an economic business from a policy arbitrage | +| Regulated-price revenue share | Revenue subject to administered or formula pricing | — | Caps upside and transfers the operating risk to a regulator's discretion | +| Compliance cost / revenue | Direct compliance and licensing spend | Rising trend is the signal | Rising compliance cost is a moat for incumbents and a margin drag for everyone | +| Tariff-exposed cost base | Imported inputs subject to duty ÷ COGS | — | Tariff changes hit COGS with almost no lag | + +Treat a policy tailwind as a **finite-life asset with an expiry date**, and check whether the market is capitalising it into a perpetual multiple. That mispricing is common and asymmetric. + +- **India-specific:** production-linked incentive (PLI) schemes, export incentives (RoDTEP and predecessors), anti-dumping and safeguard duties, GST rate changes, state-level capital and power subsidies, sector regulators (RBI, IRDAI, TRAI, CERC/SERCs, NPPA drug price control), and environmental clearances / NGT orders. Many mid-cap manufacturing theses are, in substance, PLI-and-anti-dumping-duty theses; name that when it is true. +- **US/global:** IRA and similar credits, Section 232/301 tariffs, FDA/EMA approval and pricing pathways, EU CBAM (a tariff in all but name for carbon-intensive imports), sector-specific rate regulation for utilities, and the pending-rulemaking docket in the relevant agency. + +--- + +## 9. Litigation, antitrust and enforcement exposure mapping + +Do not summarise the legal-proceedings note. **Map** it: for each material matter record the claim, the plaintiff type, jurisdiction, stage, amount claimed, amount reserved, insurance cover, and realistic timeline. + +| Check | What to look for | +|---|---| +| Reserve adequacy | Amount claimed vs amount reserved vs the disclosed "reasonably possible" range. Under ASC 450 a US filer reserves only when a loss is probable and estimable, and discloses a range for reasonably possible losses — that range is the number you should stress, not the reserve | +| Category | Product liability and mass tort (open-ended, compounding), class actions, environmental remediation and Superfund-type liability (long-tailed, joint-and-several), employment, contract, IP (§11) | +| Antitrust / competition | Market-share and pricing-conduct exposure; remedies can be structural (forced divestiture, mandated interoperability) rather than monetary — structural remedies impair the moat permanently, fines do not | +| Enforcement / regulatory | Bribery and corruption (FCPA, UK Bribery Act), securities enforcement, environmental prosecution. Look for deferred prosecution agreements and monitorships — they carry ongoing cost and constrain expansion | +| Serial pattern | Repeated settlements in the same category are a business-model signal, not bad luck | + +**India-specific.** Material litigation must be disclosed under SEBI LODR Regulation 30 and in the offer/annual documents; the contingent-liabilities note plus CARO 3(vii)(b) gives you disputed statutory dues by forum (Commissioner Appeals, ITAT, High Court, Supreme Court). Note the timelines — a matter at Supreme Court stage may be a decade from resolution, which changes the discounting entirely. Also check National Company Law Tribunal (NCLT) proceedings, Competition Commission of India (CCI) orders, and SEBI/ED actions against promoters (governance overlap, `08-governance.md`). + +**Sizing rule.** Compare the plausible adverse outcome to *annual earnings and to equity*, not to revenue. A single adverse judgment that exceeds two years of net profit is a solvency-adjacent event and belongs at the top of the risk map even at low probability. + +--- + +## 10. Tax disputes and transfer pricing + +An abnormally low effective tax rate is an earnings-quality issue *and* a risk. Both need saying. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Effective tax rate vs statutory | Tax expense ÷ PBT, compared to the domestic statutory rate | Within a few points, or explained by a **durable** reason (tax holiday with a stated expiry, R&D credit, geographic mix) | An unexplained gap normalises upward eventually and permanently cuts after-tax profit | +| Cash tax vs book tax | Taxes paid (cash flow statement) ÷ book tax expense | Converging over 3–5 years | A persistent gap means deferred liabilities accumulating or aggressive positions | +| Uncertain tax positions | Unrecognised tax benefits (ASC 740-10 / former FIN 48) balance and roll-forward | Small and stable vs earnings | Management's own estimate of what it might lose | +| Disputed tax demands | India: contingent-liabilities note, by tax head and forum | Small vs equity | Indian demands are often gross and include interest and penalty; assess winnability, not just size | +| DTA recoverability | Deferred tax assets ÷ equity, and the profit needed to use them | — | DTAs on carried-forward losses are worthless if profitability does not return; write-downs hit book value | + +**Transfer pricing.** For any group with cross-border intercompany flows, ask where profit is booked relative to where value is created. Indicators: a subsidiary in a low-tax jurisdiction holding the IP; management fees and royalties flowing to the parent; a principal/limited-risk-distributor structure. Exposure is multiplied because a single position can be challenged by **both** tax authorities. India: Form 3CEB filings, DRP/ITAT transfer-pricing litigation, advance pricing agreements (APAs — an APA in place materially de-risks the exposure, so check for one). Global: OECD BEPS Pillar Two 15% global minimum tax progressively removes the benefit of low-tax structuring, which mechanically raises the ETR of groups that had engineered it below 15% — quantify that specifically for the name rather than mentioning it in passing. + +--- + +## 11. IP portfolio and IP litigation + +Where the moat is legal rather than economic, the moat has an expiry date printed on it. + +- **Expiry mapping.** Build the revenue-weighted expiry schedule of the patents that protect the top products. For pharma this is the patent cliff and it is fully forecastable — the exclusivity date is public. Model the post-expiry revenue decline explicitly (generic entry can remove the majority of branded revenue within a year or two in an open market). +- **Validity risk.** A granted patent is not a safe patent. In the US, inter partes review at the PTAB invalidates a meaningful share of challenged claims; Paragraph IV ANDA filings signal a generic challenge years ahead; ITC Section 337 actions can block imports outright. India: Section 3(d) of the Patents Act restricts evergreening, and the compulsory-licence provisions exist — relevant for pharma theses built on patent protection in India. +- **Freedom to operate.** Is the company the defendant? Recurring infringement suits, non-practising-entity exposure, and royalty-bearing licences that could be renegotiated all sit on the cost line. +- **Trade secrets and non-patented know-how.** Protected by employment law and practice rather than registration; exposure runs through employee mobility (§13) and joint-venture technology transfer (§14–15). +- **Metrics worth carrying:** % of revenue from products losing exclusivity within five years; R&D spend versus the revenue at risk (does the pipeline replace the cliff?); litigation reserve versus the disputed royalty stream. + +--- + +## 12. Cybersecurity, data privacy and IT resilience + +For data-intensive, platform, financial and healthcare businesses this is now a first-order operational risk, and it is under-covered in most analyses because it produces no line item until it produces a very large one. + +| Check | What to look for | +|---|---| +| Disclosure | **US:** 10-K Item 1C describes risk-management processes, board oversight and management expertise; Form 8-K Item 1.05 requires disclosure of a material incident within four business days of the materiality determination. **India:** CERT-In directions require incident reporting within six hours; the Digital Personal Data Protection Act 2023 carries penalties up to ₹250 crore per instance of certain failures, and RBI/IRDAI/SEBI impose sector-specific IT and outsourcing frameworks | +| Incident history | Prior breaches, the disclosed cost, whether the remediation is complete, and whether the same failure mode recurs | +| Attack-surface concentration | Single data centre or single cloud region; a critical legacy core system (core banking, policy admin, ERP) mid-migration; third-party/vendor access as the ingress path — supply-chain compromise is now a leading vector | +| Regulatory regime | GDPR (up to 4% of global turnover), CCPA/CPRA, sectoral rules (HIPAA, PCI-DSS). Data-localisation requirements can force duplicated infrastructure | +| Resilience | Recovery-time and recovery-point objectives, tested failover, cyber-insurance limits and exclusions (many policies exclude nation-state acts) | +| Cost of a breach | Direct remediation + regulatory fine + customer attrition + class action, against annual EBIT | + +The value-relevant question is **whether trust is the product**. For an exchange, a payments processor, a bank, or a healthcare data business, a serious breach damages the franchise itself, not just the P&L — that is a permanence-column-5 risk. For a cement plant it is an IT expense. + +--- + +## 13. Organisational health and human capital + +For people-driven businesses (IT services, consulting, asset management, specialty pharma R&D, brokerages) human capital *is* the productive asset, and it is entirely off the balance sheet. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Voluntary attrition | Voluntary exits ÷ average headcount, trailing 12m | Highly sector-specific; compare to direct peers and to the company's own history only. Indian IT services disclose it quarterly and it swings widely with the demand cycle | Rising attrition raises replacement and wage cost before it shows in margin, and signals culture or compensation stress | +| Revenue and gross profit per employee | Revenue ÷ headcount, tracked over time | Rising | The cleanest productivity cross-check; falling revenue/employee while headcount grows is a margin warning | +| Utilisation and bench (services) | Billable hours ÷ available hours | Sector norm; disclosed by Indian IT firms | Both too low (idle cost) and too high (burnout, delivery risk) are bad | +| Employee cost / revenue | — | Stable or improving | A sudden jump usually means retention spending, i.e. an attrition problem being paid off | +| Senior-management turnover | Departures of CxO / business-head level in 24 months | Low | Repeated senior exits, especially CFO, are a governance and integrity signal — see `07-forensic-red-flags.md` | +| Key-person dependence | Is the franchise the founder, a star fund manager, a lead scientist? | — | Concentrated human capital can leave, and often takes clients with it | + +Read Glassdoor-type employee sentiment, LinkedIn headcount trend and job postings as **alternative-data corroboration** of the reported story: hiring that contradicts a growth narrative, or a shrinking sales organisation alongside guided acceleration, is a real signal. Also check succession planning, union/collective-bargaining agreements and their renewal dates, safety and injury rates for industrial operations, and — India — contract-labour dependence and the associated regulatory exposure. + +--- + +## 14. Country, political and sovereign risk + +For overseas operations, split **demand exposure** (revenue from a country) from **asset exposure** (production, licences, cash trapped there). Asset exposure is far harder to exit. + +Assess per material country: political stability and rule of law, contract enforceability and the local courts, expropriation and forced-localisation history, capital controls and repatriation restrictions, local-content mandates, currency convertibility and peg sustainability, sovereign rating and CDS spread, and the host regulator's track record with foreign owners. + +- **Trapped cash.** Quantify it. Cash that cannot be repatriated should be haircut or excluded from a net-debt calculation and from any sum-of-the-parts valuation; treating it at face value overstates value. +- **Sovereign linkage.** For companies whose customer is a government or state utility, sovereign stress arrives as receivables, not as headlines. +- **Valuation.** If you add a country risk premium in the discount rate, say the size and the basis (typically the sovereign default spread, sometimes scaled for equity volatility) — and do not also haircut the cash flows for the same risk. Double-counting country risk is a common error. +- **India-specific for inbound/outbound:** FDI sectoral caps and press-note restrictions on investment from land-bordering countries; ODI rules for Indian companies' overseas subsidiaries; and for domestically-focused names, state-level political risk (land, power tariffs, local approvals) is often more binding than national risk. + +--- + +## 15. Sanctions, export controls and geopolitics + +Distinct from country risk: here the risk is that a **third-country government** makes it illegal to keep doing what the company does. + +- **Sanctions.** OFAC SDN and sectoral lists, EU and UK regimes, secondary sanctions that reach non-US parties. Screen for revenue, assets, suppliers and counterparties in sanctioned jurisdictions, and for ownership links (the 50%-ownership rule captures entities not themselves listed). +- **Export controls.** US EAR and Entity List, the foreign direct product rule (which reaches products made abroad with US technology), ITAR for defence, and the equivalent EU/Japan/Netherlands controls that matter for semiconductor equipment. The relevant question is not only "does the company sell to a restricted party" but "could its product become controlled". Advanced computing, semiconductor equipment, and dual-use materials are the live categories. +- **Inbound/outbound investment screening.** CFIUS and equivalents can block M&A; outbound-investment rules restrict capital into specified technology sectors. This constrains the growth path, not just current operations. +- **Chokepoints.** Map physical supply routes: Taiwan Strait, Strait of Hormuz, Red Sea/Suez, Panama. Route disruption shows up as freight cost and inventory first. +- **The lesson to carry:** the 2022 Russia exit showed that geopolitical exposure resolves not as a discount but as a **write-off** — assets became unsaleable and unhedgeable at any price. Geopolitical asset exposure therefore belongs in the permanence column, not the cyclical one. + +--- + +## 16. ESG: climate physical and transition risk, cross-sector + +Ignore aggregate ESG scores as an analytical input; rating providers disagree with each other substantially. Analyse **financially material** exposures, and note separately that ESG scores matter as a *flow* signal because mandated funds trade on them. + +**Transition risk** (policy, technology, market shifting away from carbon): +- Carbon cost exposure: tonnes CO₂e × plausible carbon price ÷ EBIT. Under EU ETS and CBAM this is already a cash cost for European operations and for exporters into the EU in covered sectors (cement, steel, aluminium, fertiliser, electricity, hydrogen). +- Stranded assets: reserve life and asset life extending past plausible demand — thermal coal, refining, ICE powertrain tooling. +- Demand-side substitution: EV penetration against ICE component makers, renewables against thermal generation, and the second-order effects (grid, storage, copper). +- Financing and insurance exclusion: banks and insurers withdrawing from high-carbon assets raises cost of capital before it raises operating cost. + +**Physical risk** (the part usually skipped): geolocate the major plants, mines, ports, warehouses and data centres, then check flood plain, cyclone/hurricane exposure, wildfire, heat stress on process efficiency and labour, and — critically for India — **water availability**. Water is the binding physical constraint for thermal power, cement, textiles, beverages, paper and semiconductors well before sea-level rise is. + +**Social and governance components that convert into cash flow:** supply-chain labour practice and forced-labour import bans (which stop shipments outright), product safety and recall history, community and land-acquisition opposition to expansion, and safety incident rates for industrial operators. In India, mandatory disclosure sits in the **BRSR** (Business Responsibility and Sustainability Report) for the top 1,000 listed companies by market capitalisation, with BRSR Core assurance for the top tier — use its quantitative sections (energy, water, emissions, safety, complaints) rather than the narrative. Globally use CSRD filings, ISSB/IFRS S1–S2 reporting and the emissions notes. + +--- + +## 17. Technological disruption and the AI-obsolescence test + +The moat questions belong in `02-core-factors.md`; here the question is sharper and more uncomfortable. + +**Ask explicitly: could this product or service be structurally displaced within the holding horizon?** Then answer it with evidence rather than reassurance. Diagnostic indicators: market-share trend (not level), unit-price deflation, R&D or capex intensity versus the credible attackers, the share of revenue from products less than five years old, the age of the current product cycle, and whether new entrants are appearing and being funded. + +**The AI-obsolescence test.** For each major revenue line, classify: +1. **Displaced** — the value delivered is the production of text, code, images, routine analysis, tier-1 support, or the arbitrage of an information asymmetry that a model now closes. Per-seat or per-hour pricing on such work is the exposed configuration; effort-based pricing collapses faster than outcome-based pricing. +2. **Compressed** — the work survives but the labour content and therefore the price falls. Headcount-linked revenue models (staffing, traditional IT services, BPO) are structurally exposed even where demand persists. +3. **Neutral or amplified** — the constraint is physical, regulatory, relationship-based, or a proprietary data/distribution asset the model cannot access. Here AI lowers cost and may widen the moat. + +Then ask the harder second-order questions: does the company own **proprietary data or a distribution choke point** that makes it a beneficiary rather than a victim? Is the incumbency legal or regulatory (which AI does not dissolve)? And is the disruption arriving through the customer's budget rather than the product — for example, a customer whose own headcount falls buying fewer seats? + +Be calibrated in both directions. Disruption narratives are over-applied at the top of hype cycles and under-applied to slow structural decline. Where you conclude "compressed", give the timeline and the observable that would confirm it — pricing per unit of work, revenue per employee, and headcount trend are the fastest tells. + +--- + +## 18. Tail risk, hidden liabilities and contagion + +Inventory the exposures that do not appear in EBITDA and can nonetheless consume the equity: + +- **Unfunded pension and post-retirement obligations** versus market capitalisation. A deficit approaching a meaningful fraction of market cap makes the pension scheme a senior claim on future cash flow, and it is rate-sensitive in the opposite direction to the assets. +- **Guarantees**, letters of comfort, and support undertakings to associates, JVs and — India especially — group companies. +- **Derivative notionals** and counterparty exposure, especially where hedging has drifted into position-taking. +- **Asset-retirement and decommissioning obligations** (mines, oil and gas, nuclear, landfills), which are long-dated, discounted, and highly sensitive to the discount rate and cost inflation. +- **Warranty, recall and product-liability tails**, and environmental remediation. +- **Variable interest entities / structured entities** and any consolidation boundary that looks designed. +- **Insurance adequacy** against maximum probable loss, including the exclusions. + +Then run the contagion question: which of these fire **together** with the leverage and concentration risks already identified? The failure mode that actually destroys equity is rarely one risk at full size; it is three medium risks with a common driver arriving in the same quarter while financing is closed. + +--- + +## 19. Macro regime and cycle positioning: the top-down gate + +Bottom-up conviction with no top-down gate produces full investment at exactly the wrong point in the cycle. This section is not a forecast; it is a positioning statement. + +Locate the company in three cycles simultaneously — they do not move together: + +| Cycle | What to read | Why it matters for this name | +|---|---|---| +| **Business cycle** | PMI (manufacturing and services), IIP, GDP nowcasts, unemployment, capacity utilisation | Determines whether cyclical earnings are near a peak or a trough. Extrapolating peak earnings is the single most expensive cyclical error | +| **Monetary/liquidity cycle** | Policy rate and its direction, real rates, yield curve shape, central-bank balance sheet. India: RBI repo, CRR, system liquidity, credit growth | Sets the discount rate and risk appetite; long-duration equities are levered to this | +| **Credit cycle** | Corporate credit spreads, bank lending standards, default rates, issuance windows. India: bank credit growth, NBFC funding costs and spreads, corporate bond spreads | Determines refinancing availability — the difference between a leverage risk being theoretical and being live | +| **Capital cycle (sector)** | Industry capacity additions, capex announcements, incremental supply versus demand | Often the dominant driver for commodities, shipping, semiconductors, hotels, real estate: returns peak when supply is scarce and collapse when the new capacity lands | + +Then position the name honestly: is this a late-cycle cyclical at peak margins being valued on peak earnings? Is it a long-duration compounder being bought into a tightening cycle? Is the sector's capital cycle turning against it? For India add the specific overlays that drive earnings: monsoon and rural demand, government capex and the fiscal stance, GST collections as an activity proxy, and FII/DII flow direction, which drives small- and mid-cap valuations far more than fundamentals over one-to-two-year windows. + +State the conclusion as a sizing input, not a market call: *"Late-cycle for this sector; the capital cycle is adding supply through the next 24 months; that argues for a wider margin of safety and a smaller initial position rather than an avoid."* + +--- + +## 20. Broad-market valuation context + +A stock that is cheap against its peers can still deliver poor absolute returns if the whole market is expensive. Anchor the recommendation to an asset-class expectation: + +| Check | How to compute | Why it matters | +|---|---|---| +| Index valuation vs own history | Nifty 50 / S&P 500 forward P/E and trailing P/E, and CAPE where available, versus 10- and 20-year percentiles | Frames whether a "cheap" relative call is cheap in absolute terms | +| Equity risk premium | Index earnings yield − long government bond yield (India: 10y G-sec; US: 10y Treasury, real where possible) | When the yield gap compresses toward zero, equities are being priced for perfection and cash/bonds become a genuine competitor | +| Market cap to GDP | India: the Buffett indicator versus its own history | Crude, cycle-sensitive, and useful only as a percentile — not a timing tool | +| Breadth and dispersion | How much of the index return is a handful of names; small/mid-cap premium or discount versus large-cap | India's small- and mid-cap indices periodically trade at large premiums to large caps, which is a warning about the *cohort*, not any single stock | + +Use this as a gate on aggressiveness, not as permission to avoid analysis: an expensive market raises the required margin of safety and argues for staged entry rather than a full position. Say explicitly where the market sits and how it affected your conclusion. + +**Never turn this into personalised allocation advice.** State the market context as analytical background; asset allocation is the user's decision. + +--- + +## 21. Sector translation: where the standard risk lens breaks + +The ratios in sections 1–7 are undefined or inverted for several sectors. Use the sector playbook and replace the lens: + +| Sector | What breaks | What to use instead | +|---|---|---| +| **Banks** | Leverage ratios are meaningless — a bank is *supposed* to run ~10:1 or more; net debt is not a concept; interest expense is a cost of goods | Asset quality (GNPA/NNPA, PCR, slippage, restructured book), credit cost versus through-cycle normal, capital adequacy versus regulatory minimum plus buffers, LCR/NSFR, deposit franchise and CASA stickiness, ALM duration gap and repricing table, concentration by borrower and sector, unsecured-book share | +| **NBFCs / HFCs (India)** | Same as banks, plus no deposit base | Funding mix and concentration, ALM mismatch in the sub-1-year buckets (the classic Indian NBFC failure mode is a liquidity mismatch, not a credit event), bank-line dependence, co-lending and securitisation reliance | +| **Insurers** | Revenue and EBITDA are not meaningful; float distorts everything | Reserve adequacy and development triangles, combined ratio and its trend, catastrophe accumulation and reinsurance programme (including retention and reinstatement), investment-portfolio credit and duration risk, persistency for life | +| **REITs / InvITs** | EPS and P/E are distorted by depreciation; leverage looks high by design | Refinancing schedule against cap-rate and rate moves, LTV and interest coverage covenants, tenant concentration and WALE, lease expiry ladder, occupancy versus submarket supply, distribution coverage from AFFO | +| **Miners and E&P** | "Commodity price risk" is not a risk factor; it is the business | Position on the cost curve, reserve life and grade trend, jurisdiction and licence security, decommissioning liability, trough-price cash flow and balance-sheet survival | +| **Utilities / regulated infra** | High leverage is normal and financeable | Regulatory reset risk and the allowed return, counterparty (discom) receivables, tariff-formula durability, PPA tenor and renewal, capex approval | +| **Airlines / hotels / shipping** | Extreme operating leverage makes single-year metrics useless | Breakeven load factor/occupancy, fleet or fixture commitments, EV/EBITDAR with capitalised leases, fuel/bunker hedge book and tenor | +| **Early-stage / loss-making** | Coverage and leverage ratios are undefined | Cash runway in months, path to funding, dilution scenarios, and the terms of any structured or convertible financing | + +--- + +## 22. Writing the bear case and the invalidation triggers + +**The bear case must be the strongest version of the argument against the position, not a strawman you can knock down.** Standard for acceptance: someone who is short the stock would recognise their own thesis in it. + +Construct it as a narrative, not a list. Take the top three clustered risks and connect them into one coherent story of how the investment loses money, with numbers: what happens to revenue, to margin, to the multiple, and therefore to the price. Produce a bear-case fair value the same way you produced the base case, so the downside is a figure and not an adjective. Where a credible short thesis or a published bear argument exists, engage its specific claims rather than dismissing them. + +Then define **invalidation triggers**: specific, observable, dated events that would prove the positive thesis wrong. A good trigger is falsifiable and checkable from public disclosure. + +| Weak trigger | Strong trigger | +|---|---| +| "If growth slows" | "Two consecutive quarters of volume decline with pricing flat or negative" | +| "If margins deteriorate" | "Gross margin below X% for two quarters without an identified one-off" | +| "If leverage rises" | "Net debt/EBITDA above the covenant threshold minus 20% headroom at any test date" | +| "If governance worsens" | "Auditor resignation, a new qualification, CFO departure, or promoter pledge rising above X%" | +| "If competition intensifies" | "Market share below X%, or the top customer not renewing at the [date] contract expiry" | + +Attach a monitoring cadence: quarterly results, exchange filings, the shareholding pattern (India, quarterly), 8-K/Reg 30 events, and the two or three lead indicators identified in the risk map. Close by restating, in one line each, the top three risks with their severity, likelihood and permanence — that summary is what the reader will actually retain. + +--- + +## Checklist + +- [ ] Populated the risk map by sweeping sections 1–18 against **primary disclosure** (10-K Items 1A/1C/3/7A; India: risk section, contingent liabilities, CARO 3(vii)(b), LODR filings, concall Q&A). +- [ ] Redlined this year's risk-factor language against last year's; flagged anything newly added or newly specific. +- [ ] Scored each risk for severity, likelihood over a stated horizon, and permanence; applied the permanence and solvency-first overrides. +- [ ] Clustered correlated risks into single entries; named which ones fire together. +- [ ] Ranked and reported at most seven risks, each with a named lead indicator and mitigant (with the mitigant's expiry). +- [ ] Named the risks considered and deliberately excluded, with the reason. +- [ ] Ran a −10% and −20% revenue scenario through EBIT, interest cover and covenant headroom. +- [ ] Tested leverage on trough EBITDA, not peak; checked maturity wall, committed-vs-uncommitted liquidity, and structural subordination. +- [ ] Quantified top-customer, sole-source-input and single-site revenue concentration. +- [ ] Interrogated the hedging book: ratio, tenor, strike versus spot, roll-off date — for both FX and commodities. +- [ ] Quantified the share of EBIT dependent on a subsidy, tariff, tax holiday or other reversible policy, and its expiry. +- [ ] Mapped material litigation by claim, reserve, insurance and forum; compared the plausible adverse outcome to annual earnings and equity. +- [ ] Compared ETR to statutory and cash tax to book tax; checked transfer-pricing structure, APA status, and Pillar Two impact. +- [ ] Mapped revenue-weighted IP expiry and any live validity challenge. +- [ ] Assessed cyber/data-privacy exposure in proportion to whether trust is the product; checked incident history and disclosure regime. +- [ ] Checked attrition, revenue per employee, senior-management turnover and key-person dependence against the company's own history. +- [ ] Split overseas exposure into demand versus assets; quantified trapped cash; checked sanctions, export controls and chokepoints. +- [ ] Assessed material climate transition and physical risk, including water, using BRSR/CSRD quantitative data rather than ESG scores. +- [ ] Ran the AI-obsolescence test on each major revenue line: displaced, compressed, or neutral/amplified — with a timeline and a tell. +- [ ] Inventoried off-balance-sheet and contingent liabilities against market cap. +- [ ] Positioned the name in the business, monetary, credit and sector capital cycles; stated the implication for sizing and margin of safety. +- [ ] Anchored the call to broad-market valuation and the equity risk premium; did not turn it into allocation advice. +- [ ] Replaced the standard risk lens with the sector-appropriate one for banks, NBFCs, insurers, REITs, miners, utilities and high-operating-leverage sectors. +- [ ] Wrote a bear case a short-seller would recognise, priced it, and listed falsifiable invalidation triggers with a monitoring cadence. diff --git a/finance/skills/stock-analysis/references/10-peer-set.md b/finance/skills/stock-analysis/references/10-peer-set.md new file mode 100644 index 00000000..91fec110 --- /dev/null +++ b/finance/skills/stock-analysis/references/10-peer-set.md @@ -0,0 +1,282 @@ +# Building a Defensible Peer Set + +Use this when: you are at Stage 5 and about to make any statement of the form "margins are high", "the stock is cheap", "returns are best in class" — every one of those claims is a comparison, and the peer set is its denominator. + +This skill's governing rule is that a financial metric means nothing until you know its sector and the company's own history. The peer set is the machinery that makes the first half of that rule operational. Get it wrong and you do not get a slightly noisier answer — you get a confidently inverted one, because the peer set silently determines whether every metric reads as strength or weakness. It is also the easiest place in an analysis to cheat without noticing: quietly drop the two peers that outperform, and a mediocre company becomes a compounder. So construct the set explicitly, normalise its members onto one accounting basis before comparing anything, present results as ranks within the set rather than raw absolutes, and write down who you excluded and why. + +## Contents + +- [1. What a true comparable is: the six axes](#1-what-a-true-comparable-is-the-six-axes) +- [2. Operating comps vs valuation comps: two different sets](#2-operating-comps-vs-valuation-comps-two-different-sets) +- [3. Sourcing the candidate list](#3-sourcing-the-candidate-list) +- [4. Sizing and tiering the set](#4-sizing-and-tiering-the-set) +- [5. Peer-set quality diagnostics](#5-peer-set-quality-diagnostics) +- [6. Normalising peers before you compare anything](#6-normalising-peers-before-you-compare-anything) +- [7. Presenting the comparison: percentiles, not raw numbers](#7-presenting-the-comparison-percentiles-not-raw-numbers) +- [8. When the company has no good peers](#8-when-the-company-has-no-good-peers) +- [9. The traps](#9-the-traps) +- [10. Worked illustration: one company, three peer sets](#10-worked-illustration-one-company-three-peer-sets) +- [11. Sector translation: where the peer logic changes shape](#11-sector-translation-where-the-peer-logic-changes-shape) +- [12. Documenting the set so it can be audited](#12-documenting-the-set-so-it-can-be-audited) +- [Checklist](#checklist) + +--- + +## 1. What a true comparable is: the six axes + +A peer is not "a company in the same sector". A peer is a company whose economics respond to the same drivers in roughly the same way, so that a difference in a ratio is evidence about execution rather than evidence about structure. Test every candidate on all six axes below, and record the score. A candidate failing two axes badly is not a peer; it is context. + +| Axis | What to check | Why it matters | +|---|---|---| +| **Same sub-sector / end market** | Not the GICS or NSE sector tag — the actual revenue mix. What does the customer buy, and why do they switch? A speciality chemicals maker selling agrochemical intermediates and one selling pharma intermediates share a sector tag and almost no demand driver. | Sector tags mix distributors with manufacturers and marketplaces with retailers. Demand cyclicality, pricing power and working-capital rhythm all come from the end market, not the tag. | +| **Comparable business model and value-chain position** | Manufacturer vs assembler vs distributor vs franchisor vs marketplace. Owned vs asset-light. Gross vs net revenue recognition. Integration level (does the peer make its own key input?). | Margin *levels* are set by where you sit in the chain. A 4% net-margin distributor and a 25% net-margin brand owner can earn identical returns on capital. Comparing their margins ranks business models, not businesses. | +| **Similar capital intensity** | Gross block / revenue, capex / revenue over five years, asset turnover, working-capital days. Also: does the peer lease what the subject owns (or vice versa)? | Capital intensity is the hinge between margin and return. Two companies with the same ROCE can have a 3x margin gap purely from turnover. If capital intensity differs by more than ~2x, only ROCE/ROIC comparisons survive; margin comparisons do not. | +| **Similar geography and regulatory regime** | Where revenue is earned (not where the company is listed), tariff and price-control exposure, labour regime, tax regime, subsidy dependence, currency of revenue vs cost. | A domestic Indian formulations player and a US-generics exporter face different pricing regimes, different customer concentration, and different tax rates. Net margin and ROE differences between them are largely regime, not skill. | +| **Similar scale** | Revenue, and separately, unit scale (plants, stores, installed base). Aim to keep the largest/smallest revenue ratio inside ~10x. | Scale buys procurement discounts, fixed-cost absorption, distribution density and cheaper capital. A ₹500 crore company benchmarked against a ₹50,000 crore one is being measured against advantages it cannot buy. Also, small caps have structurally noisier ratios. | +| **Similar accounting framework and fiscal calendar** | IFRS (IASB), EU-endorsed IFRS, US GAAP, Ind-AS, J-GAAP, PRC GAAP — record it as a column per ticker. Then record fiscal year-end and the exact TTM window. | Ratios are not defined identically across frameworks; Ind-AS is IFRS-converged but has carve-outs, making it a third dialect. Without alignment you are ranking accounting policy and calendar luck. Section 6 handles this. | + +**Scoring convention.** Score each axis Pass / Partial / Fail and keep the grid in the comp sheet. Any candidate with a Fail on *end market*, *value-chain position* or *capital intensity* is excluded from the core set — those three cannot be fixed by adjustment. Fails on *framework* and *fiscal calendar* are fixable: normalise (Section 6) and keep. A Fail on *scale* means keep as reference-only, marked, and never let it into a percentile calculation. + +--- + +## 2. Operating comps vs valuation comps: two different sets + +Do not use one list for both jobs. They answer different questions and the criteria diverge. + +- **Operating comps** answer "is this a good business, run well?" Selection is driven by business-model similarity: same end market, same value-chain position, same capital intensity. Listing venue and valuation are irrelevant. A private-equity-owned competitor that files public accounts, or an unlisted subsidiary of a foreign group filing in India (MCA/ROC filings) is a perfectly valid operating comp even though it has no share price. +- **Valuation comps** answer "what should this trade at?" Selection adds three requirements the operating set does not need: comparable *growth*, comparable *return on capital*, and comparable *risk/liquidity/market regime*. A company can be an excellent operating comp and a terrible valuation comp — same business, but growing at 4% instead of 20%, or listed in a market that structurally trades at half the multiple. + +The single most common error here is importing the domestic-market multiple onto a foreign peer, or vice versa. Indian mid-caps have traded at a persistent multiple premium to global sector medians for long stretches; that premium reflects domestic liquidity, index flows and growth expectations, not accounting. If you cross markets in a valuation comp table, split the table by market and say what the cross-market spread has historically been, rather than blending into one median and calling the subject cheap or dear. + +--- + +## 3. Sourcing the candidate list + +Never build the list from memory or from a single screener tab. Triangulate — each source has a distinct bias, and the intersection is far more reliable than any one of them. + +**Universal sources (best first):** + +1. **The company's own competitive disclosure.** US: 10-K Item 1 "Competition" often names rivals directly. India: the annual report's *Management Discussion & Analysis* / "Industry Structure and Developments" section, plus the **earnings concall** — management naming a competitor unprompted in Q&A is the highest-signal peer identification available, because it reveals who they actually lose deals to. +2. **Customer-side and channel evidence.** Who else bids for the same tenders, sits on the same distributor's shelf, appears on the same approved-vendor list, or shows up in the same RFP. This is the ground truth the tags approximate. +3. **Credit rating agency reports** (CRISIL / ICRA / CARE / India Ratings; Moody's / S&P / Fitch). Rating rationales usually contain an explicit peer comparison table with the agency's own reasoning for the set. Free, and built by someone with a different incentive than the equity market. +4. **Regulatory market definitions.** Competition Commission of India (CCI) merger orders, and US DOJ/FTC filings, define the "relevant market" with evidence. Where they exist for your sector, they are the most rigorously argued peer sets you will find. +5. **Sell-side initiation notes and screener peer tabs** (screener.in, Trendlyne, Tijori for India; Bloomberg/CapIQ/FinViz/stockanalysis.com globally) — as a *starting candidate pool only*, never as the final set. These are tag-driven and inherit every classification error in Section 9. +6. **Index and classification codes** — GICS sub-industry, NAICS/SIC (US, in the EDGAR header), NIC codes and the NSE/BSE industry indices (India). Use them to *generate* candidates and to check you have not missed anyone. Never to *validate* the set. +7. **IPO documents.** India: the DRHP/RHP section "Basis for Offer Price" lists peers with their multiples — chosen by the issuer, so treat as a flattery-biased but informative list. US: the S-1 equivalent. +8. **Proxy / compensation peer groups.** US: DEF 14A compensation committee peer group. India: the remuneration section of the Board's Report. Useful and rarely used — but note the bias: comp peers are systematically chosen to be *larger*, because that justifies higher pay. Mine them for names, discard the framing. +9. **EDGAR full-text search** (efts.sec.gov) for the subject's own name: competitors frequently name the subject in their risk factors. India equivalent: full-text search of exchange filings and rating rationales. + +**India-specific note.** Many genuine competitors are unlisted (family-owned, MNC subsidiaries). Their financials are filed with the MCA/ROC and are purchasable cheaply; industry-association data (e.g. sectoral bodies publishing volume/capacity shares) often covers them too. Excluding them because they are unlisted systematically biases the peer set toward whoever chose to list — usually the larger and more governance-conscious operators. At minimum, note the unlisted share of the market so the reader knows how much of the competitive field the comp table omits. + +**Survivorship.** When you compare against peer *history*, include companies that were acquired, delisted or went bankrupt during the window. A five-year sector margin history built only from today's survivors overstates the sector's stability and its returns — the failures are exactly the observations that tell you what the downside looks like. + +--- + +## 4. Sizing and tiering the set + +**Target 5–10 core peers.** Below 4, percentile ranking is arithmetic theatre — with 3 peers a "75th percentile" is one company. Above ~12, you are almost certainly admitting members that fail an axis, and the median drifts toward the sector tag rather than the business. + +Tier explicitly: + +| Tier | Definition | Use | +|---|---|---| +| **Core** | Passes all six axes, or fails only on fixable axes (framework, fiscal calendar) and has been normalised. | The set that generates percentiles, medians and the relative verdict. | +| **Adjacent** | Same end market, different value-chain position or materially different capital intensity. | Context and directional sanity checks. Quote individually, never blended into the core median. | +| **Reference** | Global best-in-class operators in the same business, regardless of market or scale. | Answers "what does world-class look like structurally?" — a ceiling, not a benchmark. | +| **Excluded** | Failed an axis unfixably, or data unusable. | Listed with the reason. This list is part of the deliverable (Section 12). | + +If the core set has fewer than 4 members after honest filtering, do not pad it. Say so, and shift weight to own-history benchmarking (Section 8). A thin, honest peer set plus a deep own-history series beats a fat, contaminated one. + +--- + +## 5. Peer-set quality diagnostics + +Run these on the assembled set *before* drawing conclusions from it. They are cheap, and they catch most contamination. Ranges are indicative only — they vary by market, sector concentration and period, and a well-argued exception beats the band. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| **Core peer count** | Number of Tier-1 peers with usable normalised data | 5–10 | Below 4, percentiles are noise; above 12, the set has drifted to the sector tag. | +| **Size dispersion** | Largest core peer revenue ÷ smallest | ≤ 10x (≤ 5x preferred) | Scale advantages (procurement, fixed-cost absorption, cost of capital) are structural, not managerial. Wide dispersion turns a size effect into a false quality signal. | +| **Revenue-mix overlap** | % of the subject's revenue falling in segments the peer also serves (use segment notes / Ind-AS 108 / ASC 280) | ≥ 60% for core | Below this you are comparing two different companies that happen to share a label. | +| **Capital-intensity spread** | max ÷ min of (gross block / revenue) or (capex / revenue, 5-yr avg) across the set | ≤ 2–3x | Beyond this, margin comparisons are invalid and only ROCE/ROIC comparisons carry meaning. | +| **Framework homogeneity** | % of core peers on the same reporting framework, or restated onto one | 100% after normalisation; flag if <70% before | Mixed frameworks mean the ranking partly measures accounting policy. See Section 6. | +| **Period alignment** | Max offset between peer TTM windows | ≤ 1 quarter | A one-quarter offset can place two peers on opposite sides of a commodity move or rate turn. | +| **Gross-margin dispersion (CV)** | Standard deviation ÷ mean of gross margin across the set | < 0.30–0.40 | High dispersion in a genuinely homogeneous set almost always means *cost-classification* differences (depreciation/freight in COGS vs SG&A), not real margin differences. Treat a high CV as a data alarm, not a finding. | +| **Median stability** | Recompute the peer median with each single peer removed in turn (leave-one-out) | No single removal should move the median more than ~10–15% relative | If dropping one name moves the median materially, your conclusion is a statement about that one company, not about the sector. | + +--- + +## 6. Normalising peers before you compare anything + +This is the step analysts skip and the reason most comp tables are wrong. Before any ratio goes into a table, put every member on one basis. Work down this ladder in order — each step depends on the ones above it. Record every adjustment with its note reference; an unsourced adjustment is indistinguishable from a fudge. + +### 6.1 The adjustment ladder + +| # | Adjustment | What to do | Consequence of skipping | +|---|---|---|---| +| 1 | **Reporting framework** | Record IFRS / US GAAP / Ind-AS / local GAAP per ticker from the basis-of-preparation note. For ADRs, check whether the 20-F contains a full IFRS-to-GAAP reconciliation (only some do) or is filed under IFRS with none. | EV/EBITDA, ROCE, net debt/EBITDA and gross margin are not identically defined across frameworks. You end up ranking policy. | +| 2 | **Consolidation scope** | Identify full consolidation vs proportionate vs equity accounting. Reconcile net income attributable to owners against total net income; compute the minority share. Confirm EV adds minority interest and treats equity-accounted investments consistently across all members. Look for structured entities, ESOP trusts and off-balance-sheet JVs. | A company consolidating 100% of a 60%-owned subsidiary shows all its EBITDA but owns 60% of the earnings; if EV is not grossed up for minorities it looks artificially cheap. A peer running the same business through JVs shows almost no revenue at all. | +| 3 | **Gross vs net revenue (principal vs agent)** | Read the IFRS 15 / ASC 606 / Ind-AS 115 revenue note. Marketplaces, travel, distribution, telecom handset bundles, ad-tech and EPC are the danger zones. Cross-check the disclosed take rate against revenue; look for a presentation change between years. | Two identical marketplaces can report revenue differing by 10x. Every P/S, EV/Sales, revenue-growth and revenue-per-employee comparison collapses. It is also a favourite way to manufacture growth with zero economic change. | +| 4 | **Lease treatment** | Confirm IFRS 16 / Ind-AS 116 (all leases capitalised; rent becomes depreciation + interest) vs ASC 842 (operating leases stay a single operating expense). Pull ROU assets, lease liabilities, ROU depreciation, lease interest, the undiscounted maturity table and the discount rate. Then build **both** conventions across the whole set: (a) lease-neutral — add rent/operating-lease expense back out of IFRS EBITDA so everyone is post-cash-rent; (b) fully capitalised — add the PV of operating-lease commitments to net debt for US GAAP filers, and include ROU assets in capital employed for ROCE. State which convention the table uses. | IFRS 16 mechanically inflates EBITDA *and* reported debt; a US operating lease does neither. Retail, airlines, telecom, hotels and logistics are worst affected — an unadjusted EV/EBITDA screen ranks the IFRS lessee cheap and the US lessee expensive for no economic reason. Many screeners also exclude lease liabilities from "total debt". | +| 5 | **Capitalisation policy** | Development costs: IFRS/Ind-AS *require* capitalisation once IAS 38 criteria are met; US GAAP expenses most R&D (narrow software/cloud exceptions). Pull capitalised development additions from the intangibles note and cash flow statement; compute capitalised-dev as % of total R&D. Apply the same test to software, interest and major-maintenance capitalisation. Build a common baseline — usually expensing everything. | Capitalisation simultaneously inflates EBIT, EBITDA, CFO and invested capital while deflating FCF after capex. It is the largest single source of non-comparability in pharma, software, autos and engineering, and a classic earnings-management lever. | +| 6 | **Cost classification** | Determine what sits in COGS vs SG&A vs other income for each member: depreciation, freight and distribution, R&D, share-based comp, warranty, warehousing. Note whether the P&L is by nature (IFRS-common: material cost, employee cost, other expense) or by function. Rebuild margins at EBITDA and EBIT level where classification washes out. | Gross margin is among the least comparable metrics in existence — depreciation and freight inside COGS can cost several margin points versus an economically identical peer. Ranking a sector on gross margin reproduces exactly the single-metric error this skill forbids. | +| 7 | **Inventory costing (US-specific)** | US GAAP permits LIFO; IFRS and Ind-AS prohibit it. Read the inventory note for the LIFO reserve and any LIFO liquidation. Restate to FIFO: add the LIFO reserve to inventory and to equity (net of tax), and adjust COGS by the change in reserve. | In inflation, LIFO depresses reported gross margin and inventory while inflating cash flow via lower tax. Uncorrected, the US filer looks less profitable and less asset-heavy than an identical IFRS peer, and asset-turnover/ROCE comparisons are meaningless. | +| 8 | **Goodwill, PPA and acquired-intangible amortisation** | Check whether goodwill is amortised (some local GAAPs; US private-company alternative) or impairment-tested only. Pull the purchase price allocation for recent deals: goodwill vs amortisable intangibles, and assigned useful lives. Quantify acquired-intangible amortisation as a share of EBIT and show EBIT both with and without it. | An acquisitive company carries a PPA amortisation drag an organic peer does not, while goodwill inflates its capital base and depresses ROCE. Unadjusted EBIT comparisons arbitrarily penalise or flatter acquirers. | +| 9 | **One-offs and "adjusted" figures — symmetrically** | Reconcile every adjusted number back to statutory. Tabulate add-backs by type and year: restructuring, impairment, share-based comp, acquired-intangible amortisation, litigation. Count consecutive years each "one-off" recurs, and compute cumulative add-backs as % of cumulative reported profit. Then build your own normalised series: strip asset-sale gains, insurance recoveries, one-time tax settlements, FX on debt — removing *favourable and unfavourable* items with equal rigour. In cyclicals use mid-cycle margins over a full cycle, not the latest year. | Recurring restructuring is not a one-off and SBC is a real cost of labour. Investors habitually strip losses and keep gains, biasing normalised earnings up. Applied unevenly across a peer set, this alone can reverse a ranking. | +| 10 | **Currency and translation** | Record presentation currency, functional currency of major subsidiaries, and the translation method (current-rate: assets/liabilities at closing, P&L at average, difference to CTA; or IAS 29 restatement for hyperinflation). Convert peers using a *consistent* convention: average rate for P&L, closing rate for balance sheet, per year. Never apply today's spot rate to historical years. Check for a change of presentation currency. Look at the CTA balance and the P&L FX line. | Reported growth for a multinational can be entirely FX. Mixing rate conventions introduces errors of several percent; using spot on history destroys the growth series outright. | +| 11 | **Constant-currency / organic growth** | Find each company's own bridge from reported to organic growth — FX, acquisitions, divestments, scope, extra trading week — or rebuild it. Verify acquisitions are excluded for a full 12-month anniversary and divestments removed from the base year too. | "Organic" is unaudited and defined differently by each company. Without a like-for-like bridge you cannot tell whether a peer's superior growth is execution, currency, or debt-funded bolt-ons — which changes what the growth is worth. | +| 12 | **Fiscal-year offset** | Record each year-end: India and Japan typically 31 March; many US retailers use 52/53-week years ending late Jan/early Feb; others 30 June or 31 December. Where ends differ by more than a quarter, rebuild a **TTM series from quarterly data** so every member covers the same calendar window. Watch 53-week years and stub/transition periods after a year-end change. | Comparing "FY2025" across a March-end and a December-end company can offset the economic period by a full quarter — enough to put them on opposite sides of a commodity move and make one look like a share gainer when it is merely earlier in the calendar. | +| 13 | **Tax regime** | Reconcile effective to statutory rate per member and identify drivers: tax holidays, SEZ/incentive regimes, India's optional lower corporate-tax regime, unrecognised DTAs, one-off remeasurements. Compare at EBIT/EBITDA level, or normalise every member to a sustainable rate. | Cross-border comparisons of net margin, ROE and P/E are dominated by tax regime and by temporary incentives that expire. Only pre-tax or normalised-tax comparisons isolate operating performance. | +| 14 | **Share count and per-share integrity** | Use diluted weighted-average shares from the EPS note, not a data feed's current count. Adjust the whole history for splits, bonus issues, rights issues (theoretical ex-rights factor) and consolidations. Add options, RSUs, warrants, convertibles, ESOP-trust shares. Ensure market cap covers *all* share classes, including unlisted or dual-class lines. | Dual-class and multi-line issuers (common in India, Brazil, Korea, Europe) are routinely mis-capitalised by providers using only the listed line — understating EV and making the stock look far cheaper than it is. | +| 15 | **Restatements and transition years** | Search filings for "restated", "reclassified", "prior period error", "IAS 8", Item 4.02 (US 8-K non-reliance). Compare last year's reported comparatives line-by-line against this year's. For each new standard (IFRS 16/15/9, ASC 842/606/326, new Ind-AS notifications) record whether transition was full retrospective or modified retrospective. **Mark the transition year on every chart.** | Providers often store originally-reported figures for old years and restated figures for recent ones, silently corrupting CAGRs. Under modified retrospective, the adoption year is a hard break and growth rates across it are arithmetic nonsense. | +| 16 | **Provider field definitions** | For every screened metric, read the vendor's definition: does "debt" include leases, preference shares, acceptances? Is EBITDA EBIT+D&A or a vendor model? Is EPS basic/diluted/reported/adjusted? Trailing, forward or last-fiscal-year? Then hand-verify the top three and bottom three names against primary filings. | Screener errors cluster exactly where screens are most extreme — misparsed one-offs, missing quarters, stale share counts, mis-tagged currencies. The outliers your screen surfaces are disproportionately data artefacts. | +| 17 | **Cash-flow classification** | Check where interest paid, interest received and dividends sit — IFRS permits choices that US GAAP largely fixes. Reclassify all members to one convention before comparing CFO, FCF or FCF yield. Watch supply-chain finance / reverse factoring, receivables securitisation, and capex reclassified between operating and investing. | CFO and FCF yield are not directly comparable across frameworks without this. Reverse factoring in particular converts debt into trade payables and flatters both leverage and CFO. | + +### 6.2 Proportionality + +Not every comparison needs all seventeen. Apply the **materiality filter**: run the adjustment if it could plausibly move the metric you are ranking on by more than the gap between the subject and the peer median. If the subject is at a 22% EBITDA margin and the median is 21%, a lease-convention difference worth 400bp decides the entire conclusion and is mandatory. If the subject is at 22% against a median of 8%, it is not. + +In **Screen mode**, do steps 1, 4, 6 and 12 at minimum — framework, leases, cost classification and period alignment — because those four flip signs most often. In **Deep dive**, do all seventeen and show the adjustment bridge. + +--- + +## 7. Presenting the comparison: percentiles, not raw numbers + +Once the set is normalised, present **position within the set**, not absolutes. A raw table of numbers invites the reader (and you) to sort a column — which is precisely the single-metric ranking this skill forbids. + +**How to build it:** + +1. For each metric, compute the subject's **percentile rank** within the core peer set, plus the peer **median** and the **interquartile range**. Report as: `ROCE 19.4% — 80th pctile (peer median 14.1%, IQR 11–17%)`. +2. State the **direction convention** explicitly per metric (higher is better for ROCE; lower is better for net debt/EBITDA and working-capital days). Getting one inverted quietly corrupts a composite score. +3. Show the **dispersion**. An 80th percentile in a set where the IQR is 11–17% is a real gap. An 80th percentile in a set spanning 18.5–19.6% is a rounding difference. Percentile without spread is misleading precision. +4. With fewer than ~6 peers, report **rank out of N** ("3rd of 6") rather than a percentile. A percentile implies a distribution you do not have. +5. Report the subject's **own-history percentile alongside** the peer percentile — where does today's ROCE sit within the company's own 5–10 year distribution? Best-in-class-but-decaying and worst-in-class-but-improving are the two most valuable findings in the whole exercise, and only the two-axis view surfaces them. +6. Use **medians, not means**, throughout. One outlier peer moves a mean enough to reverse a verdict; that is how a comp table lies without a single wrong number. +7. Never collapse the peer table into a single composite score without showing the components and weights. Composite scores hide exactly the trade-offs (margin vs turnover, growth vs returns) the analysis exists to expose. + +**Always report absolutes too, in a secondary column.** A percentile tells you the relative position; it does not tell you whether the whole sector is destroying capital. A company at the 90th percentile of an industry earning 6% ROIC against a 11% WACC is the best of a value-destroying set — a fact percentiles alone will never reveal. Cross-check every relative conclusion against the absolute ROIC-vs-WACC spread. + +--- + +## 8. When the company has no good peers + +Genuinely peerless companies exist: sole domestic licensees, unusual conglomerates, first-of-kind business models, monopoly infrastructure concessions. The failure mode is inventing a peer set anyway. Do not. Say plainly that no defensible peer set exists, and substitute the following, in this order. + +**1. Own-history benchmarking becomes primary.** Build a 10-year (minimum 5-year) series for every core metric and compare the current value against the company's *own* distribution — median, range, and current percentile. Then split the variance into cycle and structure: overlay the series against the relevant cycle driver (commodity price, rate cycle, capacity utilisation, order-book/book-to-bill) and ask whether the current position is where you would expect the company to be at this point in the cycle. A company at the low end of its own margin range in a trough is normal; at the low end at a cycle peak, something structural has broken. Adjust the history for accounting-standard transitions (Section 6, item 15) or the series is not self-comparable either. + +**2. Cross-sector comparison only via ROIC vs WACC.** This is the one comparison that survives crossing industries, because it is unit-free and measures the same economic question everywhere: *is this business earning more on invested capital than the capital costs?* + +- Compute **ROIC = NOPAT / invested capital**, with NOPAT = EBIT × (1 − normalised tax rate), and invested capital = total debt + equity + lease liabilities − cash and non-operating assets (or, equivalently, net working capital + net fixed assets + capitalised intangibles). Use the same lease and capitalisation conventions you applied in Section 6 — the spread is only cross-sector-valid if the numerator and denominator are built consistently. +- Compare against **WACC**, built from a local risk-free rate (India: 10-year G-Sec; US: 10-year Treasury), an equity risk premium appropriate to that market, a beta reflecting the business not just the stock, and the company's actual after-tax cost of debt. +- Report the **spread (ROIC − WACC) and the growth rate**. Positive spread plus growth creates value; negative spread plus growth destroys it faster. That statement is true in software, cement and shipping alike. +- Report the **duration** of the spread — how many of the last ten years was it positive, and is it widening or narrowing? A single year's spread is a cycle observation, not a quality judgement. + +What does *not* transfer across sectors: margin, asset turnover, working-capital days, EV/EBITDA, P/E, net debt/EBITDA, gross margin. Do not use them cross-sector under any framing. + +**3. Sub-segment peering.** A conglomerate may have no company-level peer while each segment has excellent ones. Peer each segment separately using segment disclosures (Ind-AS 108 / ASC 280), then value sum-of-the-parts with an explicit holdco discount. This is nearly always better than forcing a company-level comp. + +**4. Value-chain and analogue peering.** Where a direct peer does not exist, an *analogue* may: a company with a different product but the same economic structure (subscription with high retention, toll-road-like annuity, franchised network with low capital intensity). Label it clearly as an analogue, use it only for structural questions (what should retention/capital intensity/incremental margin look like in a model like this?), and never for valuation multiples. + +**5. Historical-case reasoning.** Where a business model has played out before in another market or era, use it qualitatively — what typically happened to margins as the model matured, what killed the ones that failed. Qualitative only; do not import numbers. + +--- + +## 9. The traps + +**Conglomerate contamination.** A diversified peer's consolidated ratios are a revenue-weighted blend of businesses with different economics. Including one in a focused peer set drags the median toward a mixture nobody actually operates. *Fix:* use the peer's segment disclosure and compare segment-to-company, or move it to Adjacent tier. Segment data is imperfect — unallocated corporate costs and transfer pricing distort it — so state that limitation rather than pretending segment EBIT is clean. The same applies in reverse: if the *subject* is diversified, do not compare its consolidated ratios to focused peers. + +**Size mismatch.** Beyond about 10x revenue difference, you are measuring scale economics, not management. It runs both ways: large peers enjoy procurement, distribution and funding-cost advantages; small peers often show flattering ratios because a single contract or a lumpy capitalisation dominates a small base, and because they are earlier on the growth curve. *Fix:* cap dispersion, tier by size, and where scale is the explicit question, say so and compare unit economics (per store, per tonne, per MW, per seat) rather than consolidated ratios. + +**A peer set chosen to flatter.** The most dangerous trap, because it is invisible in the output. It happens through omission far more often than through commission: the strongest competitor is "not really comparable", the weakest is "close enough". *Fixes, applied together:* (a) fix the selection criteria in writing **before** you look at any peer's numbers; (b) keep the exclusion list with reasons in the deliverable; (c) run leave-one-out on the median (Section 5); (d) run the **adversarial test** — deliberately construct the most hostile defensible peer set and see whether the conclusion survives. If the verdict flips between two defensible sets, the honest output is "the answer depends on the comparison set", with both shown. That is a real finding, not a failure. Beware of inherited sets carrying someone else's incentive: IPO-prospectus peer lists (issuer wants a high price), compensation peer groups (management wants large comparators), and company-presentation peer charts (chosen to win). + +**Index and classification labels that mislead.** Sector tags are constructed for index and portfolio-construction purposes, not analytical ones. Recurring failures: payments and exchange businesses have been reclassified between technology and financials, moving the "sector median multiple" without any business changing; broad national indices labelled by consumption category bundle staples with hotels and tobacco; "Consumer Discretionary" spans autos and luxury and restaurants; "Industrials" spans defence primes and staffing agencies; "Diversified Financials" is not a business model. Also watch the *self-selected* tag: companies choose their own NAICS/SIC code on EDGAR and their industry classification on Indian exchanges, and they sometimes choose the one that trades at a higher multiple. *Fix:* treat every tag as a candidate generator and validate on the six axes in Section 1. If your peer set was produced by a single dropdown filter, it is not a peer set. + +**Time-varying peer sets.** A peer that was comparable five years ago may have divested its way out of the business. When you build a multi-year peer median, verify comparability *in each year*, not just today, or you will attribute an industry-mix shift to the subject's performance. + +**Circular valuation.** Concluding a stock is cheap because it trades below the peer median tells you nothing if the whole sector is expensive. Anchor at least one valuation leg to something absolute — a reverse DCF, a ROIC-vs-WACC spread, or the sector's own long-run multiple range — before letting relative cheapness carry a conclusion. + +--- + +## 10. Worked illustration: one company, three peer sets + +*Figures below are hypothetical and constructed to show the mechanism. They are not any real company's data.* + +**The subject.** A mid-sized manufacturer of engineered components, revenue ~₹4,000 crore, Ind-AS, March year-end. Reported EBITDA margin 14%, ROCE 17%, EV/EBITDA 13x. It owns its plants; it capitalises a modest amount of development cost; roughly 70% of revenue is domestic. + +**Peer set A — "the sector tag."** Everything in the exchange's broad "capital goods" industry index. Includes two large diversified engineering conglomerates (project EPC plus products), one pure distributor of imported components, and one asset-light design-and-outsource player. Median EBITDA margin: 9%. Median ROCE: 14%. Median EV/EBITDA: 22x. + +> **Conclusion this set produces:** margins 500bp above the sector, returns above median, and trading at a 40% discount to the sector multiple. *A high-quality compounder, unjustifiably cheap.* + +**Peer set B — "flattery by omission."** Four domestic peers, chosen after glancing at the numbers: three sub-scale players at ₹600–1,200 crore revenue and one loss-making turnaround. The two genuinely comparable ₹5,000–7,000 crore competitors were excluded as "not directly comparable — different product mix". Median EBITDA margin: 10%. Median ROCE: 11%. + +> **Conclusion this set produces:** best-in-class on every operating metric. *Category leader.* + +**Peer set C — the defensible set.** Six manufacturers of engineered components: revenue ₹2,000–9,000 crore (dispersion 4.5x), all owning their manufacturing, all majority-domestic revenue, four on Ind-AS and two on IFRS, fiscal years aligned to a common TTM window using quarterly data. Then normalised: one IFRS peer's development capitalisation expensed to match the baseline (subject margin −80bp, one peer −190bp); two peers' freight reclassified out of COGS for a like-for-like gross margin; one peer's ROU assets added to capital employed; one peer's recurring three-year "restructuring" add-back reversed into statutory EBIT; the subject's asset-sale gain in the latest year removed. + +Post-normalisation medians: EBITDA margin 15.5%, ROCE 21%, EV/EBITDA 12x. The subject's normalised figures: EBITDA margin 13.2%, ROCE 15.5%, EV/EBITDA 13x. + +> **Conclusion this set produces:** 2nd-lowest margin of 7, 6th of 7 on ROCE, and trading at a modest *premium* to the peer median despite weaker returns. Own-history check: ROCE at the 30th percentile of its own ten-year range, and the peer gap has widened for three consecutive years. *A share-losing operator at a full price.* + +**What changed between A, B and C was not a single reported number.** The subject's filings are identical in all three. Set A's median was dragged down by conglomerates, a distributor and an asset-light player whose margin structures are simply different, and dragged *up* on multiple by companies with faster growth — producing a false discount. Set B was contaminated by size mismatch and selective exclusion. Set C survived the six axes and the normalisation ladder, and reversed the verdict entirely. + +Two lessons to carry into every comp table: the largest single swing came from **who was in the set**, not from the normalisation adjustments — get selection right before you get precise. And the normalisation still mattered at the margin: without it, the subject's reported 14% margin sat above an unnormalised peer median of 13.9%, which would have read as parity rather than a deficit. + +--- + +## 11. Sector translation: where the peer logic changes shape + +The six axes hold everywhere, but for some sectors the metrics that go into the comparison must change entirely — the standard ratios are undefined or inverted. Read the relevant playbook in `references/sectors/` before building the table. + +| Sector | What breaks | Peer-set implication | +|---|---|---| +| **Banks / NBFCs** | EBITDA, EV and net debt are meaningless; debt is raw material. Provisioning models differ (IFRS 9 / Ind-AS 109 ECL vs US CECL vs older incurred-loss). | Peer on loan-book composition (secured/unsecured, retail/corporate, tenor), funding mix (CASA, borrowings), NIM, cost-to-income, credit cost through a cycle, GNPA/NNPA and coverage, and capital adequacy. Never blend a deposit-funded bank with a wholesale-funded NBFC. | +| **Insurers** | IFRS 17 broke the historical series outright; older embedded-value reporting is not comparable to it. Revenue is not a meaningful concept. | Peer within one reporting regime and one product mix (life vs general vs health; par vs non-par vs ULIP). Compare VNB margin, persistency, combined ratio, solvency. Mark the IFRS 17 transition year on every chart. | +| **REITs / real estate** | IAS 40 fair-value gains flow through the IFRS income statement; US GAAP cost model does not. EPS and P/E are near-meaningless. | Peer on FFO/AFFO, NAV, occupancy, WALE, cap rates, LTV — and only within the same measurement model. Fair-value vs cost model peers are not comparable on earnings at all. | +| **Miners / E&P** | Successful-efforts vs full-cost accounting; reserve-estimate standards differ by jurisdiction. Earnings are a commodity-price derivative. | Peer on cost curve position (all-in sustaining cost per unit), reserve life and grade, and mid-cycle rather than spot economics. Never compare a trailing-year P/E across the cycle. | +| **Utilities / regulated infra** | Regulatory assets, allowed-return frameworks and tariff regimes dominate outcomes. | Peer only within the same regulatory regime. Compare regulated asset base growth, allowed vs achieved RoE, and collection efficiency. A cross-regime "utility peer set" compares regulators, not managements. | +| **Conglomerates / holdcos** | No company-level peer exists by construction. | Peer each segment separately; value sum-of-the-parts; benchmark the holdco discount against other holdcos in the same market. | + +--- + +## 12. Documenting the set so it can be audited + +The peer table is a deliverable, not scratch work. Include this in the report: + +1. **The selection criteria, written before selection** — the six axes with the thresholds you chose (size band, revenue-mix overlap, geography). +2. **The inclusion table** — one row per core peer: ticker, exchange, revenue, framework, fiscal year-end, TTM window used, and a Pass/Partial/Fail on each of the six axes. +3. **The exclusion list with reasons** — every candidate considered and rejected, and which axis it failed. This is what makes the set defensible, and it is the single strongest defence against unconscious flattery. +4. **The adjustment log** — every normalisation applied, per company, with the note or filing reference and the quantum. A reader must be able to get from the reported number to your number. +5. **The convention statement** — one line naming the lease convention, the capitalisation baseline, the currency rate convention, the tax normalisation and the TTM window. Everything in the table obeys it. +6. **The as-of date and source for every price and multiple.** +7. **A sensitivity note** — how the conclusion changes under the adversarial peer set (Section 9). If it does not change, say so; that is the strongest form the relative claim can take. + +An undocumented comp table cannot be updated, audited or defended — and it quietly reintroduces single-metric ranking the moment anyone sorts a column. + +--- + +## Checklist + +- [ ] Selection criteria written down **before** looking at any peer's numbers. +- [ ] Every candidate scored on all six axes; end market, value-chain position and capital intensity treated as unfixable fails. +- [ ] Candidate list triangulated from at least three independent sources (company disclosure/concall, rating agency, regulator/index/screener) — never one dropdown filter. +- [ ] Unlisted and delisted/acquired competitors considered; survivorship bias in multi-year peer history noted (India: MCA/ROC filings). +- [ ] 5–10 core peers; size dispersion ≤10x; tiers marked (core / adjacent / reference / excluded). +- [ ] Operating comps and valuation comps kept as separate sets; cross-market multiple differences stated, not blended. +- [ ] Reporting framework recorded per ticker (IFRS / US GAAP / Ind-AS / local), and normalised or flagged. +- [ ] One lease convention applied to the whole set, stated explicitly; ROU assets in capital employed for ROCE. +- [ ] Capitalisation policy (development, software, interest) put on a common baseline. +- [ ] Cost classification checked (depreciation/freight/R&D/SBC in COGS vs SG&A); margins rebuilt at EBITDA/EBIT level. +- [ ] Gross vs net revenue recognition verified before any P/S or revenue-growth comparison. +- [ ] Consolidation scope and minority interests reconciled; EV grossed up consistently. +- [ ] One-offs normalised **symmetrically** — gains stripped as rigorously as losses; recurring "one-offs" counted. +- [ ] Currency converted on a consistent rate convention (average for P&L, closing for balance sheet, per year). +- [ ] Fiscal-year offsets fixed by rebuilding TTM from quarterly data; 53-week and stub periods flagged. +- [ ] Restatements and standard-transition years identified and marked on every chart. +- [ ] Provider field definitions read; top and bottom screen hits hand-verified against primary filings. +- [ ] Comparison presented as percentile/rank within the set with median and IQR — not raw sorted absolutes. +- [ ] Own-history percentile reported alongside every peer percentile. +- [ ] Absolute ROIC-vs-WACC spread reported so a "best of a value-destroying sector" verdict cannot hide behind percentiles. +- [ ] Leave-one-out test run on the peer median; adversarial peer set tested and the outcome disclosed. +- [ ] Sector-specific metric set used where standard ratios are undefined (banks, insurers, REITs, miners, utilities, holdcos). +- [ ] Exclusion list, adjustment log, convention statement and as-of dates published with the table. +- [ ] Indicative ranges in this file treated as starting points only — they vary by market, cycle and period, and peer/own-history evidence overrides them. diff --git a/finance/skills/stock-analysis/references/11-scoring-rubric.md b/finance/skills/stock-analysis/references/11-scoring-rubric.md new file mode 100644 index 00000000..7e953415 --- /dev/null +++ b/finance/skills/stock-analysis/references/11-scoring-rubric.md @@ -0,0 +1,389 @@ +# The Sector-Relative Multi-Factor Scoring Rubric + +Use this when: you are at Stage 8, the analysis is done, and you need to convert a pile of evidence into a scorecard that a reader can argue with line by line. + +A score is not a verdict; it is a disciplined summary of judgements you have already made and documented. Its value comes entirely from three properties: every metric is benchmarked against its own sector or the company's own record rather than a universal absolute, the weighting happens at the level of *categories* so no single ratio can dominate, and disqualifying findings cap or void the number instead of being averaged into it. Get any of those wrong and the composite becomes an authoritative-looking number that is confidently misleading — worse than publishing no score at all, because a number invites action in a way that prose does not. + +## Contents + +- [1. What the score is for, and what it is not](#1-what-the-score-is-for-and-what-it-is-not) +- [2. The eight categories, and why category weighting beats metric weighting](#2-the-eight-categories-and-why-category-weighting-beats-metric-weighting) +- [3. From a raw value to a sub-score: the 0–10 scale](#3-from-a-raw-value-to-a-sub-score-the-010-scale) +- [4. Choosing the benchmark: peer percentile, own history, sector band](#4-choosing-the-benchmark-peer-percentile-own-history-sector-band) +- [5. Sector-relative in practice: one metric, three sectors](#5-sector-relative-in-practice-one-metric-three-sectors) +- [6. Gates: findings that cap or void rather than average](#6-gates-findings-that-cap-or-void-rather-than-average) +- [7. Missing data, coverage, and the honesty of an incomplete score](#7-missing-data-coverage-and-the-honesty-of-an-incomplete-score) +- [8. Adjusting the weights to the investor's objective](#8-adjusting-the-weights-to-the-investors-objective) +- [9. Running the scorer](#9-running-the-scorer) +- [10. Multi-segment companies](#10-multi-segment-companies) +- [11. Worked example A — the lower-margin company scores higher](#11-worked-example-a--the-lower-margin-company-scores-higher) +- [12. Worked example B — a gate overrides a strong scorecard](#12-worked-example-b--a-gate-overrides-a-strong-scorecard) +- [13. Worked example C — renormalisation when data is missing](#13-worked-example-c--renormalisation-when-data-is-missing) +- [14. Interpreting a composite](#14-interpreting-a-composite) +- [15. The limits of scoring](#15-the-limits-of-scoring) +- [16. What goes in the report](#16-what-goes-in-the-report) +- [Checklist](#checklist) + +**Every band quoted in this file and in `scripts/benchmarks.json` is indicative only.** Benchmark levels move with market, sector, cycle, accounting regime, interest rates and period. A peer-set percentile or the company's own multi-year record overrides any absolute band printed anywhere in this skill. Treat an unedited benchmark file as a first draft and say so in the report. + +--- + +## 1. What the score is for, and what it is not + +The scorecard does three jobs: + +1. **It forces completeness.** Eight categories must each be addressed or explicitly marked missing, so a great story about a moat cannot quietly substitute for a look at the balance sheet. +2. **It makes disagreement cheap.** Because every metric shows its raw value, its benchmark band, its sub-score and its weight, a reader who thinks the ROCE band is wrong for this sector can dispute *that one line* rather than rejecting the whole analysis. This is the single most important property of the output. +3. **It resists the single-metric reflex.** "Y has a 30% margin and X has 20%, so Y is better" is the error this whole skill exists to prevent. A category-weighted composite makes that inference structurally impossible. + +It does **not** do these jobs, and the report must not imply otherwise: it is not a prediction of returns, not a recommendation, not a substitute for the written thesis, and not comparable across analysts who used different weights or edited the bands differently. A composite quoted without its weight vector, its coverage and its as-of date is not a reproducible number. + +--- + +## 2. The eight categories, and why category weighting beats metric weighting + +| Category | Default weight | What it answers | +|---|---|---| +| Business quality & moat | 15% | Are the economics structurally defensible, and is the advantage widening or decaying? | +| Profitability & returns on capital | 20% | What does the business earn on the money tied up in it? | +| Earnings quality & cash conversion | 15% | Does reported profit become cash? | +| Balance sheet & solvency | 12% | Does it survive a bad two years? | +| Growth & reinvestment | 12% | Is there somewhere to put the next rupee or dollar at the same return? | +| Governance & management | 10% | Who controls the cash flows, and do minority owners get their share? | +| Valuation & margin of safety | 10% | What does the price already assume? | +| Risk | 6% | What could invalidate the thesis regardless of the fundamentals? | + +**Why weight categories and not metrics.** Financial data is not evenly distributed across the things that matter. Any sector's metric set contains a dozen ways to measure profitability and perhaps three ways to measure governance, because profitability is easy to compute and governance is not. Average the metrics flat and the composite silently becomes 60–70% a profitability score with a governance rounding error attached — the exact failure this skill exists to prevent, reproduced one level up. Weighting by category fixes the *importance* of each dimension in advance, then lets each dimension use however many metrics the data supports. Within a category, individual metric weights (1.0 default, up to 2.5 for the decisive ones) express relative evidential value, not importance to the thesis. + +**Why these eight and not more.** They are close to independent. Adding a ninth category that overlaps an existing one double-counts the same fact — a common way scorecards get quietly captured by whatever is easiest to measure. + +--- + +## 3. From a raw value to a sub-score: the 0–10 scale + +Each metric maps onto 0–10 through four anchors defined in the sector's benchmark entry: + +| Anchor | Sub-score | Meaning | +|---|---|---| +| poor | 2.5 | Bottom of the sector's plausible range; a real weakness | +| average | 5.0 | Unremarkable for this sector, this cycle | +| good | 7.5 | Clearly better than the sector's middle | +| excellent | 10.0 | Best-in-sector territory | + +Values between anchors interpolate linearly. Beyond *excellent* the score clamps at 10 — a company twice as good as excellent is not 20/10, and letting one heroic number run away would recreate single-metric dominance. Below *poor* the score falls linearly to 0 over one further band width, so a catastrophic reading is distinguished from a merely weak one. + +Three metric shapes exist: + +- **higher_better / lower_better** — the usual directional metrics. +- **band** — metrics where *both* extremes are bad, scored 10 inside the excellent interval and tapering outward. Use it for advertising spend (cutting it buys a year of margin and loses a decade of brand), R&D intensity, loan or AUM growth (a lender growing at 3x the system is buying share with credit standards), capex/depreciation, current ratio, effective tax rate, and NBFC leverage. Any metric where you would be uneasy about the top decile belongs here. +- **judgement** — qualitative factors (moat width, capital allocation record, disclosure quality, regulatory exposure) that the analyst scores 0–10 directly. These are not a loophole. Each one requires a written justification tied to evidence, and the scorer warns when a judgement score arrives without one. A judgement metric with no note is an opinion dressed as a measurement. + +Judgement metrics are always oriented so **10 = good for the owner**. A risk metric scored 8 means low risk, not high risk. + +--- + +## 4. Choosing the benchmark: peer percentile, own history, sector band + +Precedence, strongest first: + +**1. Peer percentile.** If you have a defensible peer set (built per `references/10-peer-set.md`, normalised for accounting regime and fiscal calendar), pass the peers' values and score the company on where it sits among them. This is the best available benchmark because it controls for cycle, geography, accounting and market conditions simultaneously — all the things a shipped band cannot know. Three comparable peers is the practical minimum; below that, percentiles are noise. + +**2. Own history.** Where the peer set is weak — a company with no true comparables, a conglomerate, a market with three listed players — score the company against its own median over 5–10 years. Anchors sit at 0.85× / 1.00× / 1.15× / 1.30× the own median for higher-is-better metrics, inverted for lower-is-better. This answers "is this company getting better or worse", which no cross-sectional band can, and it is immune to sector-wide band error. It cannot detect a company that has been consistently mediocre, so never use it alone. + +**3. Sector band.** The shipped default in `scripts/benchmarks.json`. Adequate for a first pass and for sectors where the dispersion is well understood. Edit it whenever you have better information for the specific market and period, and say in the report that you did. + +State the basis used for each metric in the output — the scorer prints it in the `Basis` column. A reader who does not know whether 8.3/10 came from a peer set or from a shipped default cannot evaluate the claim. + +--- + +## 5. Sector-relative in practice: one metric, three sectors + +The same operating margin, scored against three sectors' bands from the shipped benchmark file: + +| Sector | poor / average / good / excellent | 4% margin scores | 20% margin scores | 30% margin scores | +|---|---|---|---|---| +| Retail & e-commerce | 2 / 5 / 9 / 14 | **4.2** | 10.0 | 10.0 | +| Generic operating company | 6 / 12 / 18 / 26 | 1.7 | **8.1** | 10.0 | +| IT services & SaaS | 10 / 18 / 25 / 35 | 0.6 | **5.7** | **8.8** | + +A 20% margin is exceptional in retail, good-to-strong in a generic industrial, and merely average in software. Scoring all three against one band would rank business models, not businesses. The same logic applies to every metric with a sector override: ROCE (asset-light branded consumer routinely earns 40%+, telecom rarely exceeds 15%), net debt/EBITDA (a regulated utility at 4x is normal, a cyclical at 4x is fragile), P/E (30× for a staple is not the same signal as 30× for a miner at the top of the cycle), and customer concentration (structurally extreme in semiconductors, alarming in FMCG). + +Sectors where the *entire metric set* changes rather than just the bands — because the standard ratios are undefined or inverted — are banks, NBFCs, insurers and REITs. Those use standalone sets: NIM, GNPA/NPL, PCR, CAR/CET1, ROA and cost-to-income for banks; ALM gap, credit cost and CRAR for NBFCs; VNB margin, ROEV and combined ratio for insurers; AFFO, occupancy, LTV and the cap-rate-to-cost-of-debt spread for REITs. Miners and other commodity producers keep the generic frame but score cost-curve position, reserve life and *mid-cycle* ROCE, because spot-price ROCE peaks exactly when the shares are most dangerous. + +--- + +## 6. Gates: findings that cap or void rather than average + +Some findings are not evidence to be weighed. They are statements that the weighing exercise does not apply. + +**Why averaging is the wrong operation.** A composite summarises a distribution of ordinary evidence, on the implicit assumption that the numbers being summarised are *true* and that the entity being scored will *continue to exist*. A going-concern paragraph attacks the second assumption; an auditor's qualification, a forensic audit or three years of cash flow running at half of reported profit attack the first. Blending such a finding into an average produces the absurd arithmetic where a superb ROCE, a fortress balance sheet and a cheap multiple "outvote" the auditor. In a flat average, scoring a single governance metric 0/10 inside a 10%-weighted category typically moves the composite by about two tenths — visually indistinguishable from a good company having a mediocre quarter. That is precisely the error pattern behind every scorecard that rated a fraud highly right up until the disclosure. + +So gates operate *outside* the arithmetic: + +| Severity | Effect | Examples | +|---|---|---| +| **Veto** | Composite is withheld entirely; verdict reads DISQUALIFIED | Going-concern material uncertainty; adverse or disclaimer audit opinion; active fraud/forensic investigation or regulator enforcement on the accounts; payment default, rating at D, or an unwaived covenant breach | +| **Cap 4.0–4.5** | Composite cannot exceed the cap | Qualified audit opinion; auditor resignation mid-term; **[India]** >50% of promoter holding pledged; cumulative CFO below 50% of cumulative PAT over 3+ years; material unexplained related-party leakage | +| **Cap 5.0–6.5** | Composite cannot exceed the cap | Material restatement; opaque group structure or unconsolidated material subsidiaries; receivables/unbilled growing far faster than sales for 2+ years; **[India]** 25–50% promoter pledging or pledging rising; **[India]** exchange surveillance (ASM/GSM) or a SEBI restraint order; compromised board/audit-committee independence; serial dilution at or below book; the analyst being unable to explain the revenue model or the key accounting judgement | + +Notes on use: + +- **A veto is not a score of zero.** It is a refusal to score. Report the finding prominently and early, state what would resolve it (a clean subsequent audit opinion, the forensic report, a completed refinancing), and re-run afterwards. +- **Raise a gate on evidence, not on suspicion.** Each gate in `benchmarks.json` carries an `evidence_needed` field naming the document that settles it: the auditor's report opinion paragraph, the Basis for Qualified Opinion, the quarterly shareholding pattern's encumbrance table **[India]**, an Item 4.01 or 4.02 8-K **[US]**, the rating rationale, the five-year cash flow statements. +- **Distinguish "cleared" from "not checked".** The scorer prints "GATES: none raised" either way. Say in the report which gate checks you actually performed. An unperformed check is not a pass. +- **The cap is a ceiling, not a target.** A capped composite of 4.0 does not mean the business is worth 4.0; it means no evidence can raise it above 4.0 while the finding stands. + +--- + +## 7. Missing data, coverage, and the honesty of an incomplete score + +Missing metrics are **dropped**, and the remaining category weights are **renormalised to 1.0**. They are never scored as zero. + +Scoring absence as failure would mean an under-disclosing company reads as fraudulent and a fully transparent one reads as risky, which inverts the signal you actually want. It also creates a perverse incentive in the analysis itself: the easiest way to raise a score would be to stop looking for hard-to-find numbers. + +What is reported instead: + +- **Category coverage** — the share of total category weight carried by categories with at least one scored metric. +- **Metric coverage** — the share of the sector's total metric weight actually scored. +- **Per-category coverage** — so a category resting on one metric out of eight is visible as fragile. + +**The confidence rule.** The composite is marked `** INDICATIVE ONLY **` when category coverage falls below the floor (default 70%) *or* when any category weighted 10% or more has no data at all. Both conditions matter: 85% coverage with governance entirely empty is not a scoreable company, it is a company you have not finished analysing. When the composite is indicative, say so in the report, name the empty categories, and state what data would close the gap. + +Where you have a strong qualitative view but no metrics — governance on a company with three years of listed history, say — you may set a category score directly. The output marks it `[MANUAL OVERRIDE]`. Use this sparingly and always with a written justification; it is the one place where the scorecard's discipline can be bypassed. + +--- + +## 8. Adjusting the weights to the investor's objective + +Weights are a statement of what the reader cares about, not a fact about the company. Change them deliberately, and always print them. + +| Preset | Bias | Use when | +|---|---|---| +| `default` | Balanced quality and price | No stated objective | +| `quality_compounder` | Business quality 22%, profitability 22%, valuation 5% | Long-hold compounding mandate that accepts a full price for durability | +| `deep_value` | Valuation 24%, balance sheet 20%, growth 4% | Asset- or price-led approach where survival and discount dominate | +| `income` | Earnings quality 22%, balance sheet 20%, growth 4% | Distribution durability is the objective | +| `forensic` | Earnings quality 26%, governance 26%, valuation 4% | A company you already distrust — use *with* the gates, never instead of them | + +Sector defaults already shift weights where the sector demands it: banks and NBFCs raise balance sheet to 18–20% because capital adequacy and ALM decide survival; holdcos raise governance to 20% because the entire question is whether subsidiary value ever reaches the parent's shareholders; shipping and metals raise valuation and balance sheet because entry price and leverage, not operating skill, decide cyclical outcomes; IT/SaaS raises growth and business quality and cuts balance sheet to 6% because a net-cash software company's solvency is not the interesting question. + +Two rules: **change weights before you see the scores, not after** (post-hoc weight tuning is how a scorecard becomes a rationalisation), and **run the alternative weighting as a sensitivity**. If a company scores 7.4 on quality-compounder weights and 5.1 on deep-value weights, that gap *is* the finding — it says the thesis depends entirely on paying up for durability, and the report should say so. + +--- + +## 9. Running the scorer + +`scripts/score.py` does the arithmetic. Standard library only. + +``` +python scripts/score.py --example > input.json # starter input, edit it +python scripts/score.py input.json # readable scorecard +python scripts/score.py input.json --json # same numbers, machine-readable +python scripts/score.py --list-sectors # the 21 sector keys +python scripts/score.py --explain # the method +python scripts/score.py --explain gates # every gate, with evidence required +python scripts/score.py --explain roce_pct --sector fmcg-consumer +python scripts/score.py input.json --preset deep_value --weight risk=0.10 +python scripts/score.py --example-segments > seg.json # multi-segment starter file +python scripts/score.py seg.json --segment-detail # per-segment + blended group score +``` + +Input is one JSON object: `sector`, `metrics`, optional `flags`, optional `overrides`. A metric value can be a bare number or an object carrying the workings: + +```json +"roce_pct": {"value": 22.4, "source": "FY25 AR consolidated", "period": "FY25"}, +"sssg_pct": {"value": 9.0, "peer_values": [3.0, 4.5, 6.0, 11.0]}, +"net_debt_to_ebitda": {"value": 0.4, "own_history": [1.8, 1.4, 1.1, 0.7], "basis": "own_history"} +``` + +Overrides let you narrow a band to your actual peer set (`overrides.thresholds`), change category weights, disable a metric that does not apply, or set a category score by hand. An unknown sector key falls back to the generic set with a loud warning — never accept that silently for a bank, NBFC, insurer or REIT, where the generic ratios are meaningless. + +--- + +## 10. Multi-segment companies + +A single sector key is wrong for a company that is 55% EPC, 30% IT services and 15% lending. Scoring the group against one set of bands benchmarks 45% of its profit against a sector it does not operate in, which is the precise error this whole rubric exists to prevent, committed one level up. The routing rules in `references/sectors/_index.md` (Step 3) already require per-segment analysis and sum-of-the-parts; the scorer makes it mechanical. + +**Input shape.** Add a top-level `segments` array. It is auto-detected — with no `segments` key nothing about single-sector behaviour changes. + +```json +{ + "company": "Example Diversified Industries Ltd", + "as_of": "2026-07-22", + "basis": "consolidated", + "weight_basis": "ebit", + "flags": {"opaque_structure": {"present": true, "evidence": "FY25 AR note 41"}}, + "segments": [ + {"name": "EPC & capital goods", "sector": "infra-capitalgoods", + "ebit": 12000, "capital_employed": 60000, "revenue": 150000, + "metrics": {"roce_pct": 16.5, "…": 0}, + "flags": {"receivables_blowout": {"present": true, "evidence": "…"}}}, + {"name": "Lending arm", "sector": "nbfc", + "ebit": 4000, "capital_employed": 28000, "revenue": 9000, + "metrics": {"roa_pct": 2.2, "nim_pct": 6.4, "…": 0}} + ] +} +``` + +`python scripts/score.py --example-segments` prints a complete, runnable three-segment example (industrial + IT + lending). Each segment is scored against **its own sector's** metric set, bands and category weights by the ordinary scoring machinery; only the finished composites are blended. Raw metrics are never blended across segments — an NBFC's NIM and an EPC contractor's order book are not commensurable quantities, and averaging them would be arithmetic without meaning. + +**Weighting.** `--weight-basis {ebit,capital_employed,revenue,explicit}`, default `ebit`, overriding `weight_basis` in the input. EBIT is the default because profit mix, not revenue mix, is what the owner owns: a trading segment can be 60% of revenue and 5% of profit. `explicit` reads a `weight` field per segment and normalises it to 1.0. + +**The negative-EBIT rule.** If *any* segment has EBIT at or below zero, EBIT weighting is refused outright and the scorer falls back automatically — to `capital_employed` if every segment supplies it, otherwise `revenue`, otherwise equal weights — printing a prominent warning that names the fallback and the reason. This is not fussiness about a rounding case. A negative weight does not down-weight a bad segment, it *subtracts* that segment's score from the group, so a business burning capital would mechanically raise the composite; and where losses roughly offset profits the denominator approaches zero and every weight explodes. The same positivity test is applied to whichever basis is chosen, so a zero or negative capital-employed figure is rejected the same way. Weights are never negative and never sum to zero. + +**A loss-making segment is reported prominently regardless of its weight**, flagged on its own row in the summary table and again in the diagnostics with the capital employed there and that capital's share of the group. The analytical point is that a segment destroying capital deserves attention in proportion to the *capital at risk*, not to the small weight a loss earns it in a blend. Say what capital sits there, what the group intends to do with it, and how the composite moves if it is closed, sold or fixed. + +**Diagnostics printed with every segmented run:** + +- **Concentration.** The mix, and the largest segment's share. Above 60%, that segment's playbook governs the analysis and the others are adjustments to it. If *no* segment reaches 40%, the company is a de facto conglomerate: run it through `references/sectors/holdco-assetmgr.md` as well and value it sum-of-the-parts. +- **Mixed families.** When the group spans a financial sector (`banks`, `nbfc`, `insurance`) and a non-financial one, the consolidated ratios are contaminated and must not be read at face value. The lending arm's loan-book growth sits inside consolidated operating cash flow, so group cash conversion measures disbursement rather than cash generation; and the lender's borrowings — its raw material, not its financing — inflate group debt/equity and net debt/EBITDA to levels that mean nothing. Use each segment's own metric set, and value the group sum-of-the-parts. +- **Valuation caveat**, printed every time: the blended composite scores quality across the group. It is not a valuation and it never substitutes for SOTP. Never apply a single consolidated multiple across a mixed group. + +**Gates.** Group-level `flags` cap or void the blended composite exactly as in single-sector mode. Segment-level `flags` bind that segment's own composite, and the capped number is what enters the blend — segment caps are not applied twice. But **any segment gate of severity `veto` escalates to the group** and withholds the group composite. A fraud investigation, an adverse opinion or a going-concern paragraph in one segment does not stay inside that segment: the numbers are consolidated into the group accounts, certified by the same auditor and signed by the same board. Blending a vetoed segment away at 15% weight would convert "we cannot believe these accounts" into a two-tenths deduction. The output labels every raised gate with the level it came from. + +**Coverage** is reported per segment and as a weighted group figure, checked against the same `--min-coverage` floor. A segment that could not be scored at all is dropped from the blend and the remaining weights renormalised, with the share of the weight base actually covered printed alongside the number — the same discipline applied to missing metrics, one level up. + +`--segment-detail` prints each segment's full scorecard below the group summary, which is what you reproduce in the report when a segment is doing the work. `--json` emits the group blend with every segment's complete result nested inside. + +**The blended composite never replaces sum-of-the-parts valuation.** It is a quality summary, weighted by size. Valuation of a mixed group is done segment by segment on each family's own basis — the lender on P/B or P/adjusted book, the brand on EV/EBITDA or P/E, property on NAV — net of holding-company debt and capitalised holdco costs, with a holding discount where the segments are not separately monetisable. A group composite quoted as though it were a valuation conclusion is a misuse of the tool. + +--- + +## 11. Worked example A — the lower-margin company scores higher + +Two illustrative companies, generic and hypothetical. **Distributor A**: 4% operating margin, negative working capital, high asset turnover. **Software B**: 30% operating margin, net cash, heavy stock-based compensation. Scored on their own sectors' bands and sector weights. + +Metric level, showing the margin metric doing the opposite of what the composite does: + +| Metric | Distributor A | sub-score | Software B | sub-score | +|---|---|---|---|---| +| Operating margin | 4.0% (band 2/5/9/14) | 4.2 | 30% (band 10/18/25/35) | **8.8** | +| ROCE | 26% (band 8/14/22/35) | **8.3** | 24% (band 15/25/35/50) | 4.8 | +| ROIIC | 24% | **9.0** | 13% | 5.4 | +| Cash conversion cycle | −20 days | 9.0 | +40 days | 7.1 | +| FCF margin | 2.0% | 3.8 | 12.0% | **8.9** | +| SBC / revenue | not applicable | — | 14% | 4.4 | +| 5y dilution | +2% | 7.8 | +18% | 4.7 | +| P/E | 34× (band 90/60/40/28) | **8.8** | 42× (band 60/38/25/17) | 4.6 | +| Reverse-DCF growth gap | +1.0pp | 6.7 | +4.0pp | 4.5 | + +Category level: + +| Category | Distributor A | Software B | +|---|---|---| +| Business quality & moat | 5.9 | 5.6 | +| Profitability & returns | 7.6 | 7.4 | +| Earnings quality | 6.9 | 6.5 | +| Balance sheet | 9.2 | 9.4 | +| Growth & reinvestment | 8.0 | 5.8 | +| Governance | 7.9 | 7.2 | +| Valuation | 6.4 | 4.3 | +| Risk | 5.5 | 5.8 | +| **Composite** | **7.14 — Above average** | **6.30 — Average** | + +Software B wins the margin comparison decisively — 8.8 against 4.2 — and still loses the composite. Three mechanisms produce that, and each is a real economic fact rather than a scoring artefact: + +1. **Sector-relative bands neutralise the structural margin gap.** 4% is strong for a distributor; 30% is unremarkable for software. The margin difference was never information about quality. +2. **Return on capital, not margin, is what compounds.** Distributor A converts a thin margin into 26% ROCE through turnover and supplier-funded working capital, and reinvests at 24% incremental returns. Software B's high margin sits on a capital base that earns less than its sector's median, and its incremental returns are half the distributor's. +3. **Per-share and price effects.** Software B's 18% five-year dilution and 14% SBC mean the owner captures less of the profit than the income statement implies, and it is priced 4pp of growth above what the analysis can defend. + +If Distributor A's numbers had come with three years of CFO at half of PAT, the cash-flow divergence gate would cap the composite at 4.0 and the entire comparison above would become irrelevant. That is the intended behaviour. + +--- + +## 12. Worked example B — a gate overrides a strong scorecard + +An illustrative company scores well across the board: profitability 8.1, earnings quality 7.4, balance sheet 7.9, growth 7.7, valuation 6.2 — a pre-gate composite around 7.6, comfortably "Strong". Then the shareholding pattern shows 62% of promoter holding pledged, up from 31% two years ago. + +- **Flat-average treatment**: promoter pledging is one governance metric at weight 2.0 inside a 10% category. Scoring it 0 instead of 10 moves the composite by 0.22 — from roughly 7.6 to roughly 7.4. The reader sees a strong company with a slight governance blemish. +- **Gate treatment**: composite capped at 4.0, printed with the pre-gate figure alongside so nothing is hidden, and the finding stated in the report's opening section. + +The gate treatment is right because the mechanism is not gradual. Heavy pledging couples the share price to control: a price fall triggers margin calls, invoked shares and forced selling, which drives a further fall. That reflexive loop is independent of business quality and has repeatedly destroyed operationally sound companies. Averaging spreads a step-function risk across a continuous scale and makes it disappear. **[India]** This gate is India-specific in its data source — the encumbrance table in the quarterly shareholding pattern — but the underlying risk exists anywhere insiders have pledged control blocks; in US filings, look for margin-loan disclosure in the proxy and Schedule 13D/G footnotes. + +--- + +## 13. Worked example C — renormalisation when data is missing + +A recently listed company: no governance history worth scoring and no reliable multi-year growth series. Six of eight categories carry data. + +| Category | Default weight | Score | Renormalised weight | Contribution | +|---|---|---|---|---| +| Business quality | 15% | 6.0 | 19.2% | 1.15 | +| Profitability | 20% | 8.0 | 25.6% | 2.05 | +| Earnings quality | 15% | 7.0 | 19.2% | 1.34 | +| Balance sheet | 12% | 6.5 | 15.4% | 1.00 | +| Growth | 12% | *no data* | dropped | — | +| Governance | 10% | *no data* | dropped | — | +| Valuation | 10% | 5.0 | 12.8% | 0.64 | +| Risk | 6% | 6.0 | 7.7% | 0.46 | +| **Composite** | | | **100%** | **6.65 — INDICATIVE ONLY** | + +Category coverage is 78%, above the 70% floor — but governance carries a default weight of 10%, so the empty-major-category rule fires and the composite is marked indicative. That is the correct outcome: a company whose governance you have not assessed is not a 6.65, it is an unfinished analysis. + +Had the two missing categories been scored 0 instead of dropped, the composite would read **5.19** — a full grade lower, and lower purely because of what the analyst could not find. The report would then be describing the state of the data as though it were the state of the business. + +--- + +## 14. Interpreting a composite + +| Composite | Grade | What it means in practice | +|---|---|---| +| 8.5–10 | Exceptional | Best-in-sector on most dimensions with a defensible price. Rare; re-check the inputs and the peer set before believing it. | +| 7.5–8.4 | Strong | Clear quality with no disqualifying weakness. Usually the top of a realistic range. | +| 6.5–7.4 | Above average | Good business, or a very good business at a full price. Read the category spread. | +| 5.5–6.4 | Average | Unremarkable, or excellent on some dimensions and weak on others. The spread matters more than the number. | +| 4.5–5.4 | Below average | Something material is wrong — usually returns, cash conversion or price. | +| 3.5–4.4 | Weak | Multiple failing dimensions, or a gate has capped it. | +| Below 3.5 | Poor | Avoid, or a special-situation case that this framework does not price. | +| Withheld | Disqualified | A veto gate is open. Not a low score — a refusal to score. | + +**Read the spread, not just the level.** A 6.5 built from eight scores between 6 and 7 is a genuinely average business. A 6.5 built from profitability 9.5 and governance 3.0 is a completely different object: a strong business with a control problem, where the whole question is whether the owner ever receives the economics. The composite is identical; the investment case is not. Always show the category table, never the composite alone. + +**Small differences are noise.** The difference between 6.8 and 7.1 is well inside the error of the bands, the estimates and the judgement scores. Treat gaps under roughly 0.5 as indistinguishable. Never rank a portfolio by composite to two decimals. + +--- + +## 15. The limits of scoring + +- **Garbage in, precision out.** The scorecard cannot detect a fabricated input. It will format a hallucinated ROCE to two decimals as readily as a sourced one. This is why `SKILL.md` treats "never invent a number" as the primary non-negotiable. +- **It cannot see what is not in it.** A technology shift that will halve demand in four years, a founder about to leave, a regulator drafting a rule — none of these appear unless you encode them in a judgement metric. The judgement metrics exist precisely as the entry point for what the ratios cannot see, and they are the least reliable part of the output. +- **Bands embed a period.** Thresholds calibrated in a low-rate decade misprice a high-rate one, especially in valuation and balance sheet. Re-derive from live peer data whenever you can. +- **Judgement scores can be reverse-engineered.** If you set the moat score after seeing that the composite came out lower than your prior, you have written down your prior with extra steps. Score judgement metrics before running the totals. +- **It is not comparable across analysts.** Different weights, edited bands and different judgement calibration make two composites incomparable unless both scorecards are shown in full. +- **It does not price a special situation.** Deep cyclicals at cycle extremes, turnarounds, pre-revenue businesses, holdcos trading at persistent discounts and companies in restructuring need `references/13-situations.md`, not a composite. Score them if it helps structure the evidence, but lead the report with the situation logic. +- **It says nothing about fit.** Position size, horizon, tax, currency and concentration are the user's, not the company's. Producing analysis, not advice, is a hard boundary of this skill. + +--- + +## 16. What goes in the report + +Reproduce, at minimum: + +1. The **composite and grade**, with the pre-gate figure shown separately if a gate bound. +2. The **category table** — score, default weight, renormalised weight, contribution. +3. The **per-metric workings** for at least the decisive metrics — raw value, basis used (peer / own history / sector band), the band itself, the sub-score. +4. The **weights and preset** used, and any band overrides you applied, with the reason. +5. **Coverage**, the missing categories, and what data would close the gap. +6. **Gates**: which were raised, which were checked and cleared, and which were not checked. +7. The line that every scorecard needs: bands are indicative, peer and own-history comparison override them, and this is research rather than advice. + +--- + +## Checklist + +- [ ] Sector key chosen deliberately; banks / NBFCs / insurers / REITs use their standalone metric sets, never the generic one. +- [ ] Multi-segment companies scored per segment against each segment's own sector, weighted by profit (or by capital employed where a segment loses money), with the blend never presented as a valuation — SOTP done separately. +- [ ] Bands edited to the actual peer set and period where better data exists, and the edit disclosed. +- [ ] Peer percentile used where 3+ comparable peers exist; own-history basis used where the peer set is weak. +- [ ] Every judgement metric carries a written, evidence-linked justification. +- [ ] Judgement scores set before the totals were computed, not after. +- [ ] Category weights chosen for the stated objective, fixed before scoring, and printed in the output. +- [ ] Sensitivity run under a second weight preset; any large gap reported as a finding. +- [ ] All gate checks explicitly performed; raised gates evidenced by a named document, not an impression. +- [ ] Veto findings reported early and prominently, with the composite withheld rather than lowered. +- [ ] Missing metrics dropped and weights renormalised — never scored as zero. +- [ ] Coverage reported; composite marked INDICATIVE ONLY below the floor or with an empty major category. +- [ ] Category spread discussed, not just the composite level. +- [ ] Differences under ~0.5 treated as noise; no ranking to two decimals. +- [ ] Every number in the input carries a source and a period; nothing recalled or estimated without being labelled. +- [ ] Report states plainly that this is research, not licensed financial advice. diff --git a/finance/skills/stock-analysis/references/12-report-template.md b/finance/skills/stock-analysis/references/12-report-template.md new file mode 100644 index 00000000..c4f06c86 --- /dev/null +++ b/finance/skills/stock-analysis/references/12-report-template.md @@ -0,0 +1,410 @@ +# Report Template — Final Output Structure + +Use this when: you have finished the analytical work and are assembling the deliverable, or you are in screen mode and need the short form. + +The report is where an analysis either survives contact with a reader or dies. A reader who stops after one screen must still receive the verdict, the reasoning that drives it, and the risks that would break it. Every number you print must carry its provenance — the reader cannot check your arithmetic if they cannot find your inputs, and an unsourced number is indistinguishable from a hallucinated one. Structure is not decoration here: the ordering below front-loads conclusions and pushes supporting evidence down, so the report degrades gracefully when read partially. + +## Contents + +- [Non-negotiables](#non-negotiables) +- [Formatting conventions](#formatting-conventions) +- [Full report template](#full-report-template) +- [Short-form variant (screen mode)](#short-form-variant-screen-mode) +- [Common failure modes in report writing](#common-failure-modes-in-report-writing) +- [Checklist](#checklist) + +--- + +## Non-negotiables + +Four rules govern every section below. They come from the skill's governing principle: a metric is meaningless until you know its sector and the company's own history. + +1. **Never print a bare metric.** Every ratio appears with at least one of: the peer-set median, the company's own 3–5 year range, or both. `ROCE 18%` is noise. `ROCE 18% (own 5y range 12–19%; peer median 15%)` is information. +2. **Never rank on a single metric.** If the report contains a ranking of any kind, it must be composite and the weights must be visible. +3. **State the sector playbook explicitly** and say which standard ratios you suppressed because they are undefined or inverted for that sector. Banks, insurers, REITs, miners, and asset-heavy utilities all break at least one default ratio. Silence here reads as an error. +4. **Mark every estimate.** A derived, interpolated, annualised, or eyeballed number is not the same class of object as a reported one, and the reader must be able to tell at a glance. + +--- + +## Formatting conventions + +Apply these consistently. They are what make the report auditable. + +### Showing a number with its source + +Inline form, for prose and table cells: + +``` +₹4,812 cr [FY25 AR, Consolidated P&L, p.142] +18.4% [computed: EBIT 4,812 / (TA 34,100 − CL 8,050), FY25 AR] +$2.31 [10-K FY2024, Item 8, Consolidated Statements of Operations] +``` + +Rules: +- Source goes in square brackets immediately after the number. +- For computed metrics, show the formula with the inputs, not just the label. The reader must be able to reproduce the arithmetic without opening the filing. +- Cite the statement and page/item, not just the document. "FY25 AR" alone is a weak citation; "FY25 AR, Note 32, p.211" is a real one. +- India: cite the Annual Report, the quarterly results filing (NSE/BSE intimation), the concall transcript with date, or the CARO annexure by clause number. Say `Consolidated` or `Standalone` every time — they are different companies for analytical purposes. +- US/global: cite 10-K/10-Q by Item number, 20-F for foreign private issuers, 8-K by item, or the EDGAR accession number. Say GAAP or IFRS where the treatment differs (leases, R&D capitalisation, goodwill amortisation). +- Prices and market cap must carry an as-of date and time zone or close reference: `₹1,842 (NSE close, 2026-07-21)`. + +### Marking estimates + +Use a consistent marker and define it once in the Data Quality Note. + +``` +~14.2% (est.) — derived or approximated by the analyst +[E] — compact marker for table cells +[TTM] — trailing twelve months, stitched from quarterlies; say which quarters +[Ann.] — annualised from a partial period; state the periods used +[Adj.] — analyst adjustment applied; the adjustment must be described in a footnote +``` + +Every `[E]` and `[Adj.]` needs a one-line note saying how it was produced and what would change if the assumption were wrong. An unexplained adjustment is worse than no adjustment, because it launders judgement as fact. + +### Showing not-available + +Never leave a cell blank and never substitute zero. Blank reads as an oversight; zero is an actual claim and usually a false one. + +``` +n/a — undefined for sector (e.g. inventory turnover for a bank) +n/a — not disclosed (company does not report the line) +n/a — not comparable (peer uses different segment definition or accounting basis) +n/d — not yet determined (you ran out of time or data; say so honestly) +``` + +`n/a — undefined for sector` is a *finding*, not a gap. It tells the reader you applied the right playbook. + +### Units and scale + +- India: state crore vs lakh explicitly in the column header (`₹ cr`). Never mix. If the source reports in ₹ lakh and you converted, mark the conversion. +- US/global: state `$ m` or `$ bn` in the header. For non-USD reporters, state the presentation currency and never silently FX-convert; if you do convert, give the rate and its date. +- Per-share figures: state whether basic or diluted, and whether the share count is period-end or weighted average. +- Percentages: one decimal is enough. More implies precision the inputs do not support. + +--- + +## Full report template + +Copy the structure below. Replace bracketed guidance; delete guidance lines that do not apply, but never delete a required heading — if a section is empty, say why. + +````markdown +# [Company Name] ([EXCHANGE:TICKER]) — Equity Analysis + +**Analysis date:** [YYYY-MM-DD] +**Basis:** [Consolidated / Standalone] · [Ind-AS / US GAAP / IFRS] · [Currency and scale, e.g. ₹ crore] +**Latest reported period:** [FY25 (Mar-2025) audited / Q1 FY26 (Jun-2025) unaudited / FY2024 10-K] +**Price reference:** [₹X,XXX, NSE close YYYY-MM-DD] · **Market cap:** [₹X,XXX cr] · **EV:** [₹X,XXX cr] + +--- + +## RECENCY STATEMENT +Most recent reported period incorporated: +Events checked through: +Material events since the last full-year data: +Any invalidation trigger already tripped at the time of writing: + +## DATA QUALITY NOTE + +> Read this before the numbers. It defines what the numbers are. + +| Item | Statement | +|---|---| +| **Primary sources** | [Annual Report FY25 (audited); Q4 FY25 results intimation; FY25 concall transcript dated YYYY-MM-DD; CARO FY25. / 10-K FY2024 filed YYYY-MM-DD; 10-Q Q1 FY2025; latest DEF 14A.] | +| **Secondary sources** | [Aggregator screens used, and for what — typically peer medians and price data only. Name them. Never source a fundamental from an aggregator when the filing is available.] | +| **As-of dates** | Financials as of [date]. Prices as of [date]. Shareholding as of [date]. Any data older than the latest reported period is flagged inline. | +| **Consolidated vs standalone** | [Consolidated used throughout. Standalone differs materially in X because of Y — noted where relevant.] India: if subsidiaries or JVs are significant, consolidated is the only honest basis; say so. | +| **Currency and units** | [All figures in ₹ crore unless stated. 1 crore = 10 million. / All figures in $ millions.] [FX conversions, if any, at rate R as of date D.] | +| **What is estimated** | [List every `[E]`, `[TTM]`, `[Ann.]`, `[Adj.]` used, with the method in one line each. If none, say "No analyst estimates used."] | +| **What is missing** | [Segment-level capital employed not disclosed; related-party pricing not disclosed; peer X has not filed FY25 so FY24 used and marked. Be specific — "some data gaps" is not a disclosure.] | +| **Known accounting comparability issues** | [Lease treatment differs between company and peer set; one peer capitalises development cost, company expenses it; company changed revenue recognition in FY24. State the direction of the distortion.] | + +--- + +## VERDICT AND KEY RISKS + +**Verdict:** [One sentence. State the assessment and the confidence level. Example: "Fundamentally sound compounder trading at a valuation that already prices in continued mid-teens growth — quality high, margin of safety thin. Confidence: moderate-high on fundamentals, low on the valuation call."] + +**Composite score:** [X.X / 10] · **Sector playbook applied:** [name] · **Situation flags:** [none / cyclical peak / turnaround / holding company / recent large acquisition] + +**The three things that matter most:** +1. [Claim in one line, with the single number that supports it and its source.] +2. [ditto] +3. [ditto] + +**Key risks — what could break this:** +1. **[Risk name]** — [What happens, how likely, what it does to earnings or the balance sheet. Quantify where you can: "a 200bps gross margin reversion takes EPS down ~18%".] +2. **[Risk name]** — [ditto] +3. **[Risk name]** — [ditto] + +**What would change the verdict:** [One line pointing forward to the invalidation triggers section.] + +--- + +## 1. The Business — What It Sells and How It Makes Money + +[3–6 short paragraphs, or a table plus prose. Cover:] + +- **What the customer actually buys, and why they pick this company.** Write it so a non-specialist understands. If you cannot explain the revenue model in three sentences, you do not yet understand it, and that is itself a finding. +- **Revenue build:** volume × price, or subscribers × ARPU, or AUM × yield, or loans × NIM. Show the actual driver decomposition, not just "sells products". +- **Revenue mix** by segment / geography / channel, with the share of each and the growth rate of each. Mix shift is usually the story. +- **Where the money leaks out:** the cost structure and its fixed/variable split, because that determines operating leverage in both directions. +- **The cash conversion path:** how long between spending and collecting. Working capital intensity is a structural feature of the business model, not an accounting detail. + +--- + +## 2. Sector Classification and Playbook Applied + +**Sector / sub-sector:** [e.g. Specialty chemicals — CDMO-weighted / Private sector bank / Equity REIT — office] +**Playbook applied:** [name of the playbook reference used] + +**Why this classification:** [One paragraph. Companies often sit between sectors, or report under one classification while economically belonging to another. Justify the choice — it determines which metrics are valid.] + +**Metrics suppressed as undefined or inverted for this sector:** + +| Standard metric | Status here | Why | +|---|---|---| +| [e.g. Debt/Equity] | n/a — inverted | [For a bank, leverage is the business; assess CAR / CET1 instead.] | +| [e.g. EV/EBITDA] | n/a — undefined | [EV is not meaningful for a lender; deposits are operating liabilities, not debt.] | +| [e.g. Operating margin] | Use with care | [For a REIT, use NOI margin and FFO; depreciation is non-economic on appreciating property.] | + +**Sector-specific metrics used instead:** [List, with the reason each is the right substitute.] + +--- + +## 3. Situation Classification + +[Include only if a special situation applies; if none, write "No special situation identified — analysed as a going-concern operating business."] + +**Situation:** [Cyclical at/near peak · Turnaround · Deep value / possible value trap · Holding company with cross-holdings · Post-large-acquisition · Recent IPO with short history · Regulatory overhang · Promoter-pledge stress (India)] + +**Implications for the analysis:** [What this changes. A cyclical at peak earnings must not be valued on peak-cycle P/E. A holding company needs a sum-of-the-parts with an explicit holdco discount. A turnaround needs the balance sheet weighted above the P&L. Say what you did differently.] + +--- + +## 4. Scorecard + +| Category | Score /10 | Weight | Weighted | One-line rationale | +|---|---:|---:|---:|---| +| Business quality & moat | [X] | [XX%] | [X.XX] | [why] | +| Earnings quality | [X] | [XX%] | [X.XX] | [why] | +| Balance sheet strength | [X] | [XX%] | [X.XX] | [why] | +| Cash flow | [X] | [XX%] | [X.XX] | [why] | +| Returns on capital | [X] | [XX%] | [X.XX] | [why] | +| Growth (quality & durability) | [X] | [XX%] | [X.XX] | [why] | +| Management & governance | [X] | [XX%] | [X.XX] | [why] | +| Valuation | [X] | [XX%] | [X.XX] | [why] | +| **Composite** | | **100%** | **[X.X]** | | + +**Weighting rationale:** [State why these weights, for this sector. Weights are not universal — balance sheet carries more weight for a lender or a leveraged cyclical; moat and returns carry more for an asset-light compounder. If you used the playbook's default weights, say so.] + +**Scoring basis:** [Scores are relative to the peer set and the company's own history, not to an absolute ideal. State the anchor: "6 = peer median, 8 = clearly above peer set on that dimension, 3 = materially below."] + +--- + +## 5. Core Analysis by Dimension + +Each sub-section: the numbers with sources, the trend over 3–5 years, the peer comparison, then the interpretation. Interpretation last — do not lead with your conclusion inside the evidence section. + +### 5.1 Business Quality and Moat + +[Evidence for or against durable advantage: pricing power (price realisation vs input cost trend), customer retention/churn, switching costs, scale economics, regulatory or distribution barriers, brand. The test of a moat is not that returns are high today; it is that returns stayed high while competitors were trying. Show the multi-year return series, not the latest year.] + +### 5.2 Earnings Quality + +| Metric | Value | Own 3–5y range | Peer median | Read | +|---|---|---|---|---| +| CFO / EBITDA | | | | | +| CFO / PAT | | | | | +| Accruals ratio | | | | | +| Other income / PBT | | | | | +| Effective tax rate vs statutory | | | | | +| Receivable days vs revenue growth | | | | | + +[Interpretation. Flag: profit growing faster than cash, one-off gains embedded in "operating" profit, tax rate anomalies, revenue recognition changes, capitalised costs that peers expense. India: check related-party transactions and CARO clauses on statutory dues and fund diversion. US: check non-GAAP-to-GAAP reconciliation and what is being added back.] + +### 5.3 Balance Sheet + +[Leverage, maturity profile, covenants, contingent liabilities, off-balance-sheet items, working capital structure, goodwill and intangibles as % of net worth. India-specific: promoter pledge %, inter-corporate deposits, guarantees to group entities. For lenders: capital adequacy, NPA/stage-3 movement, provision coverage, restructured book — not D/E.] + +### 5.4 Cash Flow + +[CFO, capex split maintenance vs growth (say how you split it and that the split is an estimate), FCF, FCF conversion, and the multi-year cumulative FCF vs cumulative PAT. The cumulative test over a full cycle is more informative than any single year.] + +### 5.5 Returns on Capital + +[ROCE, ROIC, ROE with DuPont decomposition, incremental ROIC on capital deployed over the last 3–5 years. Incremental return is the one that predicts the future; the average return reflects capital deployed long ago. State the capital base definition you used and be consistent with peers.] + +### 5.6 Growth + +[Revenue, EBITDA, PAT, and per-share growth over 3, 5, 10 years where available. Separate organic from acquired. Separate volume from price. Growth funded by equity issuance is not the same as growth funded by internal cash — show share count over the period. State reinvestment rate and whether growth is consistent with returns × reinvestment.] + +--- + +## 6. Peer Comparison + +**Peer set:** [List each peer with ticker.] + +**Why these peers:** [Justify explicitly. Peers must match on business model and economics, not merely on sector label or index membership. State what you excluded and why — "excluded X because 60% of its revenue is a different business", "excluded Y because it reports under a different accounting basis and is not comparable on margins". A weak peer set silently invalidates the entire relative analysis, so this justification is load-bearing.] + +**Comparability caveats:** [Size differences, geographic mix, accounting differences, fiscal year-end differences. If fiscal years differ, say which periods you aligned.] + +| Metric | [Company] | [Peer 1] | [Peer 2] | [Peer 3] | Peer median | +|---|---:|---:|---:|---:|---:| +| Revenue [₹ cr / $ m] | | | | | | +| Revenue CAGR 5y | | | | | | +| Gross margin | | | | | | +| EBITDA margin | | | | | | +| ROCE | | | | | | +| ROE | | | | | | +| Net debt / EBITDA | | | | | | +| CFO / EBITDA | | | | | | +| [Sector-specific metric] | | | | | | +| [Valuation multiple, sector-appropriate] | | | | | | + +[Two or three paragraphs of interpretation. Where the company sits above or below the median, say whether the gap is structural (business model, mix, geography) or performance-driven. A structural gap should not be scored as skill; a performance gap should not be assumed permanent.] + +--- + +## 7. Valuation + +**Method used:** [e.g. Reverse-DCF cross-checked against EV/EBIT vs own history and peers] +**Why this method for this sector:** [Justify. DCF for predictable cash generators; P/B and ROE-based for lenders; FFO/AFFO and cap-rate/NAV for REITs; EV/EBITDA through-cycle or P/NAV and reserve life for miners; EV/Sales only where margins are not yet representative and only with an explicit path to margin. Say why the default multiple is inappropriate if you rejected it.] + +**Key inputs:** [Discount rate and how derived; terminal growth; forecast horizon; tax rate; capex and working-capital assumptions. Every input gets a one-line justification. Do not import a discount rate as a convention — state the risk-free rate used and its date.] + +### Reverse-DCF: what the current price implies + +[State it as a sentence a reader can argue with: "At ₹X, the market is embedding roughly Y% revenue growth for N years at Z% EBIT margin, with terminal growth of T%." Then judge it: is that within what this company has actually delivered, and within what the industry can support? The reverse-DCF is the most useful single output in this section because it converts a price into a testable claim about the future.] + +**Historical reality check:** [Company's actual 5y and 10y delivery against the implied figures. Industry-wide growth ceiling if relevant.] + +### Scenario table + +| Scenario | Probability | Key assumptions | Implied value / share | vs current price | +|---|---:|---|---:|---:| +| Bear | [XX%] | [growth, margin, multiple — 1 line] | [₹X] | [−XX%] | +| Base | [XX%] | | [₹X] | [±XX%] | +| Bull | [XX%] | | [₹X] | [+XX%] | +| **Probability-weighted** | 100% | | **[₹X]** | **[±XX%]** | + +[Probabilities are judgements — say so, and say what drives them. A scenario table with a bear case that is not genuinely bad is a marketing document, not an analysis. The bear case should assume things you consider unlikely but possible, not merely slower growth.] + +--- + +## 8. Red Flags and Governance + +[List findings, most severe first. If none material, write "No material red flags identified" and list what you specifically checked — a clean bill of health is only credible if the reader knows what was tested.] + +| # | Flag | Severity | Evidence [source] | Why it matters | +|---|---|---|---|---| +| 1 | | High/Med/Low | | | + +Checked and clear: [enumerate — auditor changes, qualified opinions, related-party transactions, promoter pledge, contingent liabilities, frequent restatements, CFO/CEO turnover, dilution history, capital allocation record, subsidiary opacity.] + +**India-specific checks:** promoter shareholding trend and pledge %, auditor resignation history, CARO qualifications by clause, SEBI/exchange actions, related-party approvals, royalty payments to promoter entities, concall responsiveness (management that dodges the same question across three calls is telling you something). + +**US/global checks:** auditor opinion and any ICFR material weakness, restatements, insider selling patterns in Form 4, share-based compensation as % of revenue and its treatment in non-GAAP, buybacks at valuation peaks, board independence and related-party disclosures in the proxy. + +--- + +## 9. The Bear Case + +[Write this as though you were short the stock and had to defend the position. Not a list of generic risks — a coherent argument that the thesis is wrong. Cover: what the bull is assuming that may not hold; what would cause returns to mean-revert; which competitive, regulatory, technological, or cyclical force is being underweighted; and where the accounting could be flattering the picture. + +If you cannot write a bear case that you find at least partly persuasive, you have not done the work. Say explicitly what the strongest counter-argument is and why you still net out where you do — but do not defang the bear case in the process of writing it. Keep the rebuttal separate and after.] + +**Strongest counter to the bear case:** [1–2 sentences, kept honest.] + +--- + +## 10. Thesis-Invalidation Triggers + +Specific, observable, and time-bound. "Deteriorating fundamentals" is not a trigger. A trigger is something a reader could check in a future filing and get an unambiguous yes/no. + +| # | Trigger | Where to observe | By when | Action if hit | +|---|---|---|---|---| +| 1 | [Gross margin falls below XX% for two consecutive quarters] | [Quarterly results / 10-Q] | [Q2–Q3 FY27] | [Revisit — thesis rests on pricing power] | +| 2 | [Net debt/EBITDA exceeds X.Xx] | [Half-year balance sheet] | [FY27] | [Downgrade balance sheet score] | +| 3 | [Promoter pledge rises above X% / insider selling exceeds X% of holding] | [Shareholding pattern / Form 4] | [any quarter] | [Governance re-review] | +| 4 | [Incremental ROIC on last 3y capital deployed falls below cost of capital] | [Annual report] | [FY27 AR] | [Growth is value-destructive — thesis fails] | +| 5 | [Named competitor / regulatory event] | [specific source] | [date] | [specific] | + +--- + +## Disclaimer + +This document is research and analysis produced for informational purposes only. It is **not** investment advice, not a recommendation to buy, sell, or hold any security, and not a personalised financial recommendation. The author is not a licensed or registered investment adviser. Figures are drawn from public filings and may contain errors of transcription, computation, or interpretation; items marked as estimates are the analyst's own and are not company-reported. Past performance and historical financial trends do not predict future results. Any investment decision is the reader's own responsibility and should be made in consultation with a licensed financial adviser who is aware of the reader's circumstances, objectives, and risk tolerance. +```` + +--- + +## Short-form variant (screen mode) + +Use when the task is a screen across many names, a first-pass triage, or the user asked for a quick read. Target roughly one screen per company. Same provenance and estimate-marking rules apply — brevity does not license unsourced numbers. + +````markdown +### [Company] ([EXCHANGE:TICKER]) — [Sector] — [Score X.X/10] + +**Basis:** [Consolidated, Ind-AS, ₹ cr] · **Data:** [FY25 AR + Q1 FY26] · **Price:** [₹X,XXX, DD-MMM-YY] + +**Verdict:** [One or two sentences: what it is, what the composite score reflects, and the single biggest reason to look closer or pass.] + +| | Value | Peer med. | Own 5y | +|---|---:|---:|---:| +| [Sector-appropriate metric 1] | | | | +| [Sector-appropriate metric 2] | | | | +| [Sector-appropriate metric 3] | | | | +| [Valuation multiple] | | | | + +**Playbook:** [name] · **Suppressed:** [metrics n/a for this sector] +**For:** [strongest positive, one line, with a number] +**Against:** [strongest negative, one line, with a number] +**Flags:** [red flags, or "none found in screen-level checks"] +**Data gaps:** [what a full analysis would need to resolve] +**Next step:** [Full analysis / Pass — reason / Watch, revisit at trigger X] + +*Screen-level output. Research, not investment advice. Not a licensed adviser.* +```` + +Screen mode carries an extra obligation: state that it is screen-level. A short report that reads like a full one invites the reader to over-trust it. + +--- + +## Common failure modes in report writing + +Each of these has changed a reader's conclusion in the wrong direction. Check for them before finalising. + +- **The buried verdict.** Conclusion appears on the third screen after a wall of tables. Fix: front-load. +- **The decorative bear case.** Bear section says "valuation could de-rate" and nothing else. Fix: make it argue. +- **The metric without a home.** A ratio printed with no peer or history anchor. Fix: never print bare. +- **The wrong-sector ratio.** D/E for a bank, P/E for a loss-making biotech, EV/EBITDA for a REIT. Fix: run the suppression table. +- **The laundered estimate.** An analyst assumption formatted identically to a reported figure. Fix: mark everything. +- **The convenient peer set.** Peers chosen so the company looks good. Fix: justify the set before you compute, not after you see the results. +- **The unfalsifiable trigger.** "Watch for execution issues." Fix: name the line item, the threshold, and the filing. +- **The precision illusion.** A DCF output to two decimals off inputs that are ±30%. Fix: round to the precision the inputs support and show the scenario range, not a point estimate. +- **The peak-cycle P/E.** Cyclical valued on peak earnings and a peak multiple. Fix: the situation classification section exists to catch this. +- **Score without weights.** Composite presented as authoritative with weighting hidden. Fix: weights and rationale always visible. + +--- + +## Checklist + +- [ ] Title carries company, ticker, date, basis (consolidated/standalone), accounting standard, currency and scale. +- [ ] Data Quality Note appears before any number and lists sources, as-of dates, estimates, and gaps. +- [ ] Verdict, composite score, top-three drivers, and key risks all fit within the first screen. +- [ ] Sector classification stated, playbook named, and suppressed metrics listed with reasons. +- [ ] Situation classification present, or explicitly stated as "none". +- [ ] Scorecard shows category scores, weights, weighted contributions, composite, and the weighting rationale. +- [ ] Every dimension section shows value + own history + peer median before interpretation. +- [ ] Peer set listed, justified, and exclusions explained; comparability caveats stated. +- [ ] Valuation method justified by sector; discount rate and terminal growth each justified. +- [ ] Reverse-DCF stated as a testable sentence and checked against actual historical delivery. +- [ ] Scenario table with probabilities, assumptions, implied values, and a probability-weighted figure. +- [ ] Red flags listed by severity; "checked and clear" list included; India and US-specific checks run as applicable. +- [ ] Bear case written to persuade, with the rebuttal kept separate and after. +- [ ] At least three invalidation triggers that are specific, observable, sourced, and time-bound. +- [ ] Every number carries a bracketed source; every estimate carries `[E]`/`(est.)` with a method note. +- [ ] No blank cells and no zeros standing in for missing data — `n/a` with a reason instead. +- [ ] No single-metric ranking anywhere in the document. +- [ ] Disclaimer present and unedited: research, not licensed financial advice. diff --git a/finance/skills/stock-analysis/references/13-situations.md b/finance/skills/stock-analysis/references/13-situations.md new file mode 100644 index 00000000..9c9c6d60 --- /dev/null +++ b/finance/skills/stock-analysis/references/13-situations.md @@ -0,0 +1,551 @@ +# Situation and Lifecycle Playbooks + +Use this when: you are at Stage 2 classifying the company, or at any later stage where the standard metric set is producing an answer that feels mechanically correct and economically absurd. + +The sector playbook tells you which metrics exist for this industry. The situation playbook tells you which of them are *currently meaningful*. These are overlays, not substitutes: a steel company is a metals company **and** a deep cyclical, and both files apply. Almost every large valuation error in this skill's domain comes from applying the wrong lens rather than from arithmetic — a trailing P/E screen buys cyclicals at the top, sells them at the bottom, discards every loss-making grower, and rates a holding company on consolidated numbers it does not actually own. Choosing the framework is a bigger decision than the inputs you feed it. + +**Every indicative range in this file is indicative only.** Ranges shift with market, cycle stage, interest-rate regime and accounting period. A peer-set comparison and the company's own 5–10 year history override any absolute band printed here, always. + +## Contents + +- [0. Classify first — the step that prevents the error](#0-classify-first--the-step-that-prevents-the-error) +- [1. Loss-making growth](#1-loss-making-growth) +- [2. Deep cyclicals](#2-deep-cyclicals) + - [2.1 The low-P/E-at-peak trap](#21-the-low-pe-at-peak-trap) + - [2.2 Normalised earnings power](#22-normalised-earnings-power) + - [2.3 The capacity cycle and cost-curve position](#23-the-capacity-cycle-and-cost-curve-position) + - [2.4 Valuation anchors that work at the trough](#24-valuation-anchors-that-work-at-the-trough) + - [2.5 Surviving the trough](#25-surviving-the-trough) +- [3. Turnarounds](#3-turnarounds) +- [4. Distressed and restructuring](#4-distressed-and-restructuring) +- [5. Spin-offs and demergers](#5-spin-offs-and-demergers) +- [6. Merger arbitrage and open offers](#6-merger-arbitrage-and-open-offers) +- [7. Holding companies](#7-holding-companies) +- [8. Recent IPOs](#8-recent-ipos) +- [9. Micro and small caps](#9-micro-and-small-caps) +- [10. Asset-heavy vs asset-light](#10-asset-heavy-vs-asset-light) +- [11. Promoter and family-controlled companies](#11-promoter-and-family-controlled-companies) +- [12. State-owned enterprises (PSUs)](#12-state-owned-enterprises-psus) +- [13. Large treasury and investment books](#13-large-treasury-and-investment-books) +- [14. Serial acquirers and roll-ups](#14-serial-acquirers-and-roll-ups) +- [15. SPACs and de-SPACs](#15-spacs-and-de-spacs) +- [16. Catalyst, horizon and falsification](#16-catalyst-horizon-and-falsification) +- [Checklist](#checklist) + +--- + +## 0. Classify first — the step that prevents the error + +Before computing a single multiple, write down three lines in your working notes: + +1. **Situation label(s).** Pick from: normal operating company / loss-making growth / deep cyclical / turnaround / distressed / spin-off / merger-arb target / holdco / recent IPO / micro-cap / promoter-controlled / PSU / treasury-heavy / serial acquirer / de-SPAC. **Multiple labels are normal.** A newly demerged PSU cement company is four overlays at once. +2. **Metrics deliberately switched off.** State them: "trailing P/E is switched off — mid-cycle margins are ~40% below current; valuing on EV/tonne and normalised EPS." +3. **Re-classification date.** Situations expire. A turnaround that works becomes a normal company; a compounder that stops reinvesting becomes a treasury-heavy stub; a cyclical migrates from trough to peak. Re-label at least annually and on any transformative event. + +### Recognition triggers — run this scan + +| If you observe | Suspect | Go to | +|---|---|---| +| Negative EBIT with >25% revenue growth, heavy SBC or ad spend | Loss-making growth | §1 | +| Margin range across 10 years spans 3x or more; commodity or spread-driven revenue | Deep cyclical | §2 | +| Margins well below own history and peers; new management; restructuring charges | Turnaround | §3 | +| Net debt/EBITDA >5x with falling EBITDA, going-concern note, rating downgrade, covenant waiver | Distressed | §4 | +| Listing in the last 12 months without an IPO; scheme of arrangement in filings | Spin-off / demerger | §5 | +| Price pinned just below a fixed offer price; open-offer or scheme announcement | Merger arb | §6 | +| Principal assets are stakes in other listed companies; revenue mostly dividend income | Holdco | §7 | +| Listed <24 months; restated financials only; offer-for-sale in the prospectus | Recent IPO | §8 | +| Market cap below roughly ₹5,000 crore / $2bn, thin volume, no analyst coverage | Small/micro-cap | §9 | +| Capex/sales persistently >10% or persistently <2% | Asset-heavy / asset-light | §10 | +| Promoter or family holding >40%; group companies in the RPT note | Promoter-controlled | §11 | +| Government is the controlling shareholder; administered pricing; subsidy receivables | PSU | §12 | +| Cash + investments >25% of market cap | Treasury-heavy | §13 | +| Goodwill + intangibles >30% of assets; growth bridge dominated by acquisitions | Serial acquirer | §14 | +| Listed via SPAC merger; warrants outstanding; projections in an investor deck | De-SPAC | §15 | + +If two labels conflict on the same metric, the **more conservative overlay wins**. A cyclical holdco is valued on trough-adjusted NAV, not peak look-through earnings. + +--- + +## 1. Loss-making growth + +**Recognise it.** Negative operating profit, revenue growth typically >20%, gross margin positive, opex dominated by sales/marketing and R&D, heavy share-based compensation, funding from equity rather than operating cash. Common in SaaS, consumer internet, D2C, quick-commerce, biotech, EV. + +**What changes.** P/E, ROE and EV/EBITDA are undefined or meaningless. You are underwriting two separate questions that must be answered in order: (a) *are the unit economics positive?* and (b) *is there enough money to reach scale before the funding window closes?* A company losing money because it is spending ahead of a profitable unit is investable. One losing money on every unit sold is a subsidy, and growth makes it worse. Answer (a) first — if it fails, (b) is irrelevant. + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Contribution margin per unit | Revenue per order/customer − all direct delivery costs (COGS, fulfilment, payment gateway, support, hosting) | Positive and widening year on year | The single go/no-go test. Negative and static = the business scales its losses. | +| CAC payback | Fully-loaded S&M spend ÷ (new customers × monthly gross profit) | <12 months (SaaS <18) | Longer payback means growth must be funded externally for years; ties directly to dilution. | +| LTV/CAC | (ARPU × gross margin ÷ monthly churn) ÷ CAC | >3x on *gross* margin and realistic churn | Compute it yourself; management LTV usually uses revenue margin and optimistic churn. | +| Net revenue retention | Revenue from a cohort this year ÷ same cohort last year | >100% (SaaS >110%) | Above 100% the installed base grows without new sales spend — the strongest signal available. | +| Quarterly cash burn / runway | (OCF − capex − lease payments); runway = (cash + undrawn committed lines) ÷ burn | >8 quarters, or clear path to breakeven inside runway | Under ~4 quarters, the next financing sets the price, not the fundamentals. | +| SBC as % of revenue | Share-based comp ÷ revenue | <10%; >20% is a material transfer to employees | SBC is a real cost paid in your ownership. | +| Fully-diluted future share count | Today's diluted count + shares implied by the capital still needed to reach breakeven | — | Value the company **per future share**, never per today's share. | + +**Signals that invert.** +- **Revenue growth is a negative** if contribution margin is negative — every incremental sale enlarges the loss. +- **"Adjusted EBITDA" positive** is not profitability. Rebuild it to GAAP/Ind-AS operating profit and list every add-back. SBC, annually recurring "one-off" restructuring, capitalised software and marketing reclassified as "investment" are the four usual culprits. +- **Falling CAC** can mean brand strength — or that the company has stopped growing and is harvesting easy demand. Check volume, not just cost. +- **Rising capitalised R&D / content / development cost as a share of spend** flatters the P&L while cash burn is unchanged. Watch the ratio drift, not the level. + +**The trap.** Modelling the business correctly and ignoring dilution. You can be right about the company and still lose most of your money because your claim on it shrank through successive down-rounds and rescue raises. The dominant risk for a pre-profit company is not competition — it is a closed funding window. Ask explicitly: at today's gross margin and a normalised opex base, at what revenue level does this break even, and does the cash on hand plus committed lines get there? + +--- + +## 2. Deep cyclicals + +**Recognise it.** Selling price is set by an external market, not by the company: steel, aluminium, copper, cement, sugar, paper, shipping rates, refining and petrochemical spreads, memory chips, PVC/soda ash, dry-bulk freight, hotels, airlines, real-estate developers, capital goods with long order cycles. Diagnostic test: pull 10–15 years of EBITDA margin — if the range spans a factor of three or more, and peaks/troughs line up across all peers simultaneously, it is a deep cyclical. + +**What changes.** Nothing in the trailing P&L describes the business. Profits are set by the industry supply–demand balance, not company quality. Your entire job is to locate the company in the cycle, estimate mid-cycle earnings power, and determine whether the balance sheet survives the next trough. + +### 2.1 The low-P/E-at-peak trap + +**This is the single most expensive valuation error in equity analysis. Treat any cyclical trading at a low trailing P/E as a red flag until proven otherwise.** + +The mechanics: at the cycle peak, realisations and margins are at decade highs, so **E** is inflated far above sustainable levels. The market, which can see this, correctly assigns a **low multiple** to an earnings number it knows is temporary. The resulting 4–6x P/E is not a mispricing — **it is the market's forecast of an earnings collapse.** The stock then de-rates on falling earnings *and* often a falling multiple, producing losses far larger than the apparent cheapness implied. + +The inverse is equally important and equally counter-intuitive: at the trough, earnings are near zero or negative, so the P/E is enormous, meaningless or undefined. **A high or infinite P/E on trough earnings frequently marks the best entry point in the entire cycle.** Cyclical returns are made by buying at high/no P/E on depressed earnings and selling at low P/E on peak earnings — the exact opposite of what a screen instructs. + +Confirm which end of the cycle you are at, using at least three independent checks: + +| Check | Peak signature | Trough signature | +|---|---|---| +| EBITDA margin vs own 10-year band | At or above 90th percentile | Bottom decile, or negative | +| Trailing P/E | Low (4–8x) and falling | Very high, negative or undefined | +| P/B | Above 10-year median, often 2–4x | Near or below 1x | +| Capacity utilisation / occupancy / freight rate | >90%, spot above contract | Below cash-cost for marginal producers | +| Industry capex and new-project announcements | Booming; greenfield everywhere | Projects cancelled; consolidation, closures | +| Dividend yield and payout | High yield on peak EPS (looks attractive) | Cut or suspended | +| Balance sheets across the sector | Deleveraging fast, net cash appearing | Rights issues, covenant waivers, bankruptcies | + +If margins are at a decade high and the P/E is 5x, **treat the stock as expensive**, and write that sentence explicitly in the report so the conclusion is not quietly reversed later by a screen output. + +**Cross-check against the commodity itself.** Back out the realisation or spread implied by current earnings, and compare it to the long-run marginal cost of production (typically the 90th-percentile producer's all-in cost plus a return on capital). Prices persistently far above marginal cost are unsustainable by construction — high prices call forth the supply that destroys them. + +### 2.2 Normalised earnings power + +Build mid-cycle earnings before you value anything: + +1. Pull 10–15 years (at minimum one full peak-to-peak cycle) of volume, realisation, EBITDA margin, EPS and ROCE. +2. Take the **median** (not mean — means are dragged by peak outliers) EBITDA margin across the cycle. Adjust upward only for structural, evidenced improvements: a new low-cost plant commissioned, captive power, backward integration, a permanent shift in the cost curve. Do not adjust for "management's efficiency programme". +3. Apply the mid-cycle margin to *current* capacity and a realistic utilisation, not to peak revenue. Volume growth is real and permanent; price is not. +4. Deduct maintenance capex-adjusted depreciation and a normalised tax rate to get mid-cycle EPS and mid-cycle ROCE. +5. Value on 10–14x mid-cycle EPS (indicative; varies widely by industry and rate regime), and cross-check with §2.4 anchors. + +State clearly that mid-cycle EPS is an estimate, show the margin assumption, and show what the value is at ±200bps of margin. + +### 2.3 The capacity cycle and cost-curve position + +Cyclical profits are set by supply. Map it directly: + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Industry capacity pipeline | Announced capacity additions over next 3–5 years ÷ current industry capacity, vs expected demand CAGR | Additions below demand growth | Peer capex booms are the leading indicator of the next downturn, visible years before the P&L. | +| Cost-curve quartile | Company cash cost per tonne/unit vs industry cost curve | First quartile | A first-quartile producer survives the trough and buys distressed assets; a fourth-quartile one is a call option that can expire worthless. | +| Capacity utilisation | Output ÷ rated capacity | Compare to the 10-year band, not an absolute | Utilisation above ~90% precedes price spikes; below ~70% precedes closures. | +| Contract vs spot mix | Share of volume on long-term contracts | Higher = smoother, lower peak | Determines how violently earnings move; changes the correct multiple. | +| Channel inventory | Distributor/port/warehouse stocks in weeks of demand | Below historical average | Restocking and destocking amplify the apparent cycle by months. | +| Vertical integration | Share of key input self-supplied (ore, power, feedstock) | Higher in input-cost-driven cycles | Integration moves the company down the cost curve and stabilises the spread. | + +Also track imports/exports, anti-dumping and safeguard duties (**India:** DGTR investigations and Finance Ministry notifications; **US:** Section 232/301 tariffs and ITC determinations). Trade protection is often the difference between a domestic producer's peak and trough, and it expires on a known date. + +### 2.4 Valuation anchors that work at the trough + +At the trough, earnings-based multiples break entirely. Switch to: + +| Anchor | How to compute | Indicative use | Why it matters | +|---|---|---|---| +| P/B | Market cap ÷ tangible book | Compare to the company's own trough (often 0.5–0.8x) and peak (2–4x) | Book is a stable measuring stick when earnings are near zero. | +| EV per unit of capacity | EV ÷ tonnes, barrels/day, MW, rigs, rooms, TEU, wafer starts | Versus greenfield build cost per unit | Directly comparable across peers and against new supply economics. | +| EV / replacement cost (Tobin's Q) | EV ÷ estimated cost to rebuild the asset base today | <1 at trough; >1 invites new supply | This is *both* the valuation floor and the mechanism of recovery: below replacement cost, nobody builds, supply stops growing, and prices eventually recover. | +| Price / normalised earnings power | Market cap ÷ mid-cycle net profit (§2.2) | 10–14x indicative | Keeps you honest about what the business earns through a cycle. | +| EV / mid-cycle EBITDA | Use mid-cycle, never trailing | 5–8x indicative for heavy industry | The only EV/EBITDA formulation that is not cycle-contaminated. | + +Sanity check every asset-based anchor: what would it cost, and how many years would it take, to build this asset base today — including land, environmental clearances and grid/port connectivity? An asset that cannot be replicated for regulatory reasons is worth more than its accounting value; an obsolete asset is worth less than book regardless of what the balance sheet says. + +### 2.5 Surviving the trough + +The cycle can be right and the equity still be wiped out if leverage was set against peak cash flow. Survivorship *is* the thesis: the surviving low-leverage operator captures the exiting competitor's volume and earns super-normal returns for years. + +- Compute **net debt ÷ mid-cycle EBITDA**, never trailing peak EBITDA. Indicative comfort: below 2.5x for a deep cyclical; above 4x on mid-cycle numbers is a solvency question, not a leverage ratio. +- Stress-test at the **worst realisation of the last downcycle**: does EBITDA cover interest plus maintenance capex? If not, count the quarters of liquidity available. +- Line up the **debt maturity schedule against the expected trough years**. A refinancing due in the trough is the single most common route to permanent equity loss. +- Check covenant headroom (usually net debt/EBITDA and interest cover), fixed-vs-floating mix, and contractually committed capex that cannot be cancelled. +- Do the same for the two or three weakest peers. Their distress is your company's opportunity — or the trigger for a sector-wide price collapse as they dump inventory. + +**The trap, restated.** Buying a cyclical because it screens cheap on trailing earnings, high ROE and a fat dividend yield — all three of which peak together, at exactly the wrong moment. + +--- + +## 3. Turnarounds + +**Recognise it.** Margins materially below both peer median and the company's own history, a new CEO/CFO, restructuring provisions, asset sales announced, and a narrative of "transformation". Price is well off its highs. + +**What changes.** Before any valuation, diagnose *which of three* problems this is — the diagnosis determines whether there is a thesis at all: + +| Type | Signature | Fixable? | +|---|---|---| +| **Operational** | Revenue and volumes intact; margin gap traceable to identifiable causes — cost bloat, a bad plant, loss-making contracts, over-distribution | Yes, and usually within 2–4 years | +| **Financial** | Business economics fine at the EBIT line; capital structure broken — too much debt, wrong maturity, wrong currency | Yes, via refinancing, asset sale or equity raise — but ownership may transfer (see §4) | +| **Secular** | End-market shrinking, technology substitution, regulatory ban, permanent share loss to a structurally better model | **No.** This is not a turnaround, it is a melting ice cube | + +Distinguishing test: look at **volumes/units, not revenue** (price rises can mask volume collapse for years), market share trend, and whether peers are also struggling (industry problem, possibly cyclical) or thriving (company-specific, possibly fixable). Most "value trap" losses are secular decline misdiagnosed as an operational turnaround. + +**Primary metrics.** Gross margin trend quarter over quarter (the first place a real fix shows); fixed-cost base in absolute currency terms year on year; working-capital days; net debt reduction in absolute terms; capacity utilisation; share of revenue from products launched in the last 3 years. + +**Demand evidence, not intention.** Turnarounds re-rate on hard data points, and the market almost always gives you time to buy *after* the first verified inflection at a far better risk-adjusted price than at the announcement. Waiting filters out the large majority of plans that fail and costs you only a small part of the return. Hard markers to require: + +- A new CEO/CFO with a *relevant* prior track record, and their actual incentive plan (are targets tied to margin and ROCE, or to revenue and TSR over one year?). +- Divisions or assets **actually sold with cash received** — not "strategic review initiated". +- Headcount and fixed cost reductions visible **in the reported P&L**, not in a slide. +- Debt actually repaid on the balance sheet. +- Two consecutive quarters of sequential gross-margin or working-capital improvement. + +**Signals that invert.** +- **Restructuring charges every year for five years** means restructuring is a permanent operating cost, and "adjusted" earnings are fiction. +- **Promised savings** that never appear in reported opex have been "reinvested" — i.e. they did not exist. +- **Revenue stabilisation** is not evidence if it came from price increases while volumes fell; that is harvesting, and it accelerates the decline. +- A **low P/B on a shrinking asset base** is not a floor if the assets are industry-specific and the industry is disappearing. + +**The trap.** Underwriting the announcement instead of the evidence, and confusing a cheap price with a changed business. + +--- + +## 4. Distressed and restructuring + +**Recognise it.** Going-concern qualification, covenant breach or waiver, rating downgrade to junk, interest cover below 1.5x, debt trading well below par, auditor resignation, delayed filings, insolvency petition admitted. + +**What changes.** You are no longer valuing a business; you are valuing a **residual claim that ranks last**. Equity value = enterprise value minus everything senior to it, and that number is frequently zero or negative even when the business survives and prospers. Build the liability stack before anything else: + +Secured debt (by security and seniority) → unsecured debt → subordinated debt and converts → capitalised leases → pension/gratuity deficits → statutory and tax dues (often super-priority) → trade creditors → guarantees given to group entities and other off-balance-sheet exposures → preference shares → equity. + +**Primary metrics.** Enterprise value under a realistic (not hopeful) recovery scenario; the resulting equity stub after the stack; nearest maturity wall in months; liquidity runway; the "fulcrum" security — the layer at which value runs out, because that layer typically ends up owning the reorganised company. + +**Regime matters — check which applies.** +- **India:** Insolvency and Bankruptcy Code 2016. Once the NCLT admits a case, the CIRP timeline runs to 330 days including litigation, an insolvency professional displaces the board, and resolution plans routinely write existing equity down to a nominal value or extinguish it entirely. Section 29A bars defaulting promoters from bidding for their own company. RBI's prudential framework governs pre-IBC restructuring by lenders. Watch for the "delisting after resolution plan" outcome — minority shareholders can be cashed out at a token price. +- **US:** Chapter 11 (reorganisation, debtor-in-possession financing, absolute priority rule) versus Chapter 7 (liquidation). Equity receives nothing until creditors are made whole, though small "gifted" recoveries occur in negotiated plans. Watch for a shareholders' committee being *denied* — that is the court signalling the equity is out of the money. + +**Signals that invert.** +- **A very low price and a tiny market cap** make the equity look like a cheap option. It is an option, but the strike is the entire liability stack, and it can expire worthless while the business continues under new owners. +- **"Promoter/management is infusing capital"** dilutes you unless you can participate on the same terms. Rescue rights issues and debt-to-equity conversions routinely dilute existing holders by 90%+. +- **Asset value exceeding debt on the balance sheet** is not protection: distressed asset sales clear at a fraction of book, and the write-down happens on the way to the sale. +- **Rising share price on restructuring news** frequently reflects retail speculation, not a recovery calculation. + +**The trap.** Buying "cheap" distressed equity without doing the capital-structure arithmetic. In distress, value transfers to creditors or to the new-money provider; the operating recovery you correctly predicted accrues to someone else. + +--- + +## 5. Spin-offs and demergers + +**Recognise it.** A scheme of arrangement in the filings, a share entitlement ratio, a record date, and a new line item appearing in the shareholder's account. **India:** demerger under Sections 230–232 of the Companies Act 2013, approved by NCLT and SEBI, with a listing lag between record date and the new entity's first trade — often weeks to months, then a special pre-open price-discovery session. **US:** Form 10 registration statement (the primary diligence document) or Form S-1, usually tax-free under IRC §355. + +**What changes.** There are two independent things to analyse: the *mechanical mispricing* and the *standalone economics*. + +Mechanical: recipients did not choose the new stock, there is no analyst coverage, and index funds plus mandate-restricted holders must sell an unwanted small-cap stub regardless of value. This forced selling is indiscriminate and time-bounded — it is the structural reason spin-offs are a documented source of mispricing. Watch price behaviour in the first several weeks and note when index inclusion decisions land. + +Standalone: **the pro-forma segment disclosure is not the standalone P&L.** Add back the corporate costs the unit never carried (its own CFO, board, listing, audit, insurance, treasury, IT) and remove arbitrary parent allocations. Then read the scheme for how debt, pension/gratuity, tax liabilities, contingent liabilities and shared costs were split, what transitional supply or service agreements bind the two entities and on what terms, and any retained stake or cross-holding. + +**Primary metrics.** Standalone EBIT after real corporate costs; net debt allocated to each entity vs its EBITDA; the share of each entity's revenue that is a captive sale to the other; the parent's retained stake and its likely disposal path; the implied stub value of the parent after deducting the market value of the spun entity. + +**Signals that invert.** +- **Heavy selling with no news** in the first weeks is the opportunity, not a warning — but only if the standalone economics stand up. +- **The parent looking "cleaner"** is often because it kept the cash and pushed the debt and legacy liabilities into the spun entity. Read the allocation, do not assume symmetry. +- **A long transitional services agreement** flatters the spun entity's near-term costs; model the step-up when it lapses. +- **India-specific:** the cost basis of your original holding is apportioned between the two entities per the scheme — relevant to any after-tax return calculation. Verify the ratio in the scheme document, not from a news report. + +**The trap.** Valuing the new entity off the parent's old segment margins. Also: assuming the "good" business was spun out. Check where management's incentives, the better assets and the growth capex budget ended up — occasionally the spin is a disposal of a problem dressed as a value-unlock. + +--- + +## 6. Merger arbitrage and open offers + +**Recognise it.** The stock trades in a narrow band just below a stated offer price, volatility collapses, and volume spikes around approval news. + +**What changes.** Business quality becomes almost irrelevant. You are pricing a probability-weighted event, and the payoff is asymmetric in the wrong direction: **you win a few percent many times and lose 20–40% when a deal breaks.** Position sizing and break probability, not the headline spread, determine the outcome. + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative range | Why it matters | +|---|---|---|---| +| Gross spread | (Offer price − market price) ÷ market price | 1–4% for clean deals | The raw compensation. | +| Annualised return | Gross spread × (365 ÷ expected days to close), net of costs and adjusted for any dividends received in the interim | Compare to the risk-free rate plus a break-risk premium | A 3% spread over 3 months is very different from 3% over 18. | +| Downside to undisturbed price | Pre-announcement price (adjusted for market/sector moves since) vs current price | Typically −20% to −40% | This is the actual loss if the deal breaks — the number that governs sizing. | +| Break-even probability | Downside ÷ (spread + downside) | Compare to your own estimate of deal risk | Makes the implied market probability explicit. | + +**Enumerate every condition precedent** and give each a probability: antitrust/competition approval in each jurisdiction (**India:** CCI; **US:** HSR waiting period, DOJ/FTC second request), foreign-investment screening (**India:** Press Note 3 for land-border countries; **US:** CFIUS), sector regulator consent (RBI, IRDAI, TRAI, FERC, FCC), shareholder vote thresholds, financing certainty (committed facilities vs "best efforts"), MAC/MAE clause wording, break fees on each side, and litigation. + +**India-specific structures.** A SEBI SAST-mandated **open offer** is triggered at 25% acquisition or on change of control, and is for a minimum 26% of shares — so tendering holders typically receive *proportionate acceptance*, not a full exit; model the residual stub you will still own at the post-offer price. **Delisting** via reverse book-building has a different payoff shape entirely, driven by the discovered price and the 90% threshold. **Schemes of arrangement** require NCLT approval and majority-of-minority voting, which adds months and a real rejection risk. + +**Signals that invert.** +- **A wide spread is a warning, not a bargain.** It is almost always the market pricing a real regulatory, financing or political risk it understands better than you do. +- **Stock-for-stock deals** carry the acquirer's own risk and require a short hedge; an unhedged position is a bet on the acquirer, not an arbitrage. +- **Repeated extensions of the long-stop date** signal a deal in trouble even while the spread looks stable. + +**The trap.** Sizing on the spread rather than the downside, and treating a wide spread as free money. + +--- + +## 7. Holding companies + +**Recognise it.** The principal assets are equity stakes in other companies (listed or unlisted); standalone revenue is largely dividend and interest income; the market cap sits far below the market value of the stakes. Common in Indian promoter group structures and in European/Asian family conglomerates. See also `references/sectors/holdco-assetmgr.md`. + +**What changes.** **Consolidated financials are largely meaningless to a minority holder.** Consolidated revenue and EPS include subsidiaries whose cash you do not control and, in the case of associates, businesses you own a slice of but do not consolidate. You own a claim on cash that must travel *up* through dividend policy, tax and holdco operating costs. Valuation is sum-of-the-parts, full stop. + +**Build the NAV, in this order.** +1. Market value of each listed stake (price × shares held, as of a stated date). +2. A defensible valuation for unlisted stakes — an earnings or book multiple against listed comparables, disclosed clearly as an estimate, with a haircut for illiquidity. +3. Plus net cash / minus net debt at the **holdco standalone** level (not consolidated). +4. Minus holdco operating costs capitalised (annual holdco opex ÷ discount rate) — these are a perpetual leakage. +5. Minus estimated tax leakage on an eventual sale of the stakes (capital-gains tax on the embedded gain; **India:** verify the current LTCG rate and surcharge applicable to listed and unlisted shares separately). + +Then: **discount = 1 − (market cap ÷ NAV)**, plotted over 5–10 years to establish the company's *own* normal range. + +**Primary metrics.** Discount to NAV vs its own 5–10 year percentile; look-through earnings (your share of each investee's net profit); **cash dividends actually received** at the holdco (the only money that can ever reach you); holdco opex as % of NAV; share count trend. + +**Signals that invert.** +- **A low consolidated P/E** on a holdco is meaningless and frequently the reason a screen surfaces it. Switch it off explicitly. +- **A very wide discount is not automatically an opportunity.** Indian holdcos commonly sustain 50–70% discounts for a decade or more. The money is made only when the discount is wide *against its own history* **and** there is a mechanism to close it: buyback, demerger, listing of a subsidiary, dividend policy change, holdco merger, activist pressure. Without a mechanism, a 60% discount can simply stay a 60% discount forever, and your return is only the underlying's return. +- **A holdco continually issuing shares to buy more stakes** widens the discount rather than narrowing it, and dilutes look-through earnings per share. + +**The trap.** Treating NAV as a target price. Also: ignoring voting-vs-economic rights and cross-holdings — a circular structure where A owns B owns A inflates apparent NAV by double-counting; net it out. + +--- + +## 8. Recent IPOs + +**Recognise it.** Listed within roughly 24 months. No public reporting track record; only restated financials in the prospectus; analyst coverage originating mostly from the bookrunners. + +**What changes.** You lack the one thing the rest of this skill depends on — the company's own history under public scrutiny. **The information asymmetry is at its maximum**, and it runs entirely against you: IPOs are sold, not bought, and are timed by informed sellers into favourable markets. + +**Read the prospectus for:** +- **Fresh issue vs offer-for-sale split.** Fresh issue money goes into the company; OFS money goes to exiting shareholders. A 100% OFS means no capital is being raised for the business at all. +- **Selling shareholders' cost basis** and the valuation of the last pre-IPO round. A PE holder exiting at 8x their entry price two years later tells you what they think the business is worth. +- **Use-of-proceeds specificity.** "General corporate purposes" and "repayment of promoter loans" are far weaker than a named plant with a named capacity. +- **Lock-up expiry calendar.** **India (SEBI ICDR):** anchor investors — 50% of allotted shares locked for 30 days, remainder for 90 days; minimum promoter contribution locked for 18 months; other pre-issue capital typically 6 months. **US:** typically a 180-day underwriter lock-up, with earlier release triggers. Each expiry is a scheduled supply event. +- **3–5 years of restated financials**, looking specifically for a suspicious margin ramp into the IPO year, a working-capital squeeze (channel stuffing, stretched payables), related-party clean-ups executed just before filing, and one-off revenue booked in the final year. +- **Free float and index inclusion timeline** — small float plus future index addition creates mechanical demand that has nothing to do with value. + +**Signals that invert.** +- **A beautiful three-year margin ramp is a warning, not a strength.** Pre-IPO financial dressing is common and reverts within 4–8 quarters of listing. Check whether the trend continues in the first post-listing results. +- **Grey-market premium and listing-day pop** carry zero information about business value. +- **Heavy anchor/institutional subscription** reflects allocation dynamics and momentum, not diligence you can rely on. + +**The trap.** Valuing on prospectus-year margins. Wait for two to four quarters of *public* reporting and, where possible, past the first major lock-up expiry, before treating any margin as the base rate. In India, note that **SME-platform IPOs** (NSE Emerge, BSE SME) have materially lighter disclosure and post-listing scrutiny than main-board issues — apply §9 in full. + +--- + +## 9. Micro and small caps + +**Recognise it.** Market cap below roughly ₹5,000 crore or $2bn (indicative; adjust to the market), thin volume, few or no analysts, promoter/insider concentration. + +**What changes.** Two things simultaneously: the inefficiency is real (institutions structurally cannot participate), and the safeguards are absent (no analyst scrutiny, weaker audit, weaker disclosure). Fraud and governance-failure base rates are far higher here than in large caps, so **verification effort must go up, not down**, exactly where information is scarcest. + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Median daily traded value | Median of (volume × price) over 6 months | Enough to exit in <10 trading days at ≤25% of daily volume | A "cheap" stock you cannot sell without moving the price 15% is not cheap. | +| Days to exit | Intended position size ÷ (25% × median daily value) | <10 days | Determines position size before any valuation work. | +| Bid–ask spread | (Ask − bid) ÷ mid | <1% | Wide spreads are a permanent tax on entry and exit. | +| Free float | 1 − (promoter + strategic + locked holdings) | >25% | Low float exaggerates both rallies and collapses. | +| Auditor quality and tenure | Identity of the statutory auditor; any resignation or qualified opinion | No resignations; recognised firm | **Auditor resignation is one of the highest-signal red flags available in this segment.** | + +**Governance and existence checks — do these before valuation, not after.** Auditor/CFO turnover; qualified opinions and emphasis-of-matter paragraphs; board independence in substance; related-party transactions; contingent liabilities; regulatory action history. Then verify the business physically exists as described: plant visits or satellite imagery, customer and distributor references, employee headcount vs revenue, GST/tax filings, channel checks. **India:** CARO 2020 clauses (especially on statutory dues, undisclosed income, and diversion of funds), SEBI's ASM/GSM surveillance lists, trade-to-trade segment placement, and circuit filters — a stock locked at upper circuit cannot be sold, which converts a paper gain into a trapped position. **US:** SEC comment letters on EDGAR, Form 8-K Item 4.01 (auditor change) and Item 4.02 (non-reliance on prior financials), and PCAOB inspection status of the auditor. + +**Signals that invert.** +- **A strong price move on low volume** is not confirmation of anything; it may be one buyer or a coordinated operation. +- **Very high reported ROE with poor cash conversion** in an unaudited-by-a-major-firm small cap is a fraud pattern, not a quality signal. +- **Concentrated promoter holding**, normally alignment, becomes control risk when combined with thin float and heavy related-party flow (§11). + +**The trap.** Sizing a position by conviction rather than by liquidity. Do the days-to-exit calculation first; it caps the position regardless of how good the analysis is. + +--- + +## 10. Asset-heavy vs asset-light + +**Recognise it.** Asset-heavy: capex/sales persistently above ~10%, fixed assets several times revenue, high depreciation, long build cycles — utilities, cement, telecom, hotels, shipping, refining. Asset-light: capex/sales below ~2–3%, negative working capital, returns on a tiny capital base — software, franchising, asset-managers, brand licensors, platform businesses. + +**What changes.** Capital intensity determines whether growth *creates or destroys* value. Two companies with identical earnings growth can have opposite owner outcomes if one must reinvest 120% of its profit to achieve it. + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Capex / depreciation | Full-cycle average | ~1.0–1.3x for a steady business; >2x = heavy expansion | Persistently below 1.0x means the asset base is being run down and reported profit is overstated. | +| Maintenance capex | Floor estimate = depreciation grossed up for asset-price inflation; better = management disclosure or a per-unit engineering estimate | — | Growth capex is optional; maintenance capex is a cost of staying in business. Owner earnings = CFO − maintenance capex. | +| Incremental ROIC | Δ NOPAT over 5 years ÷ Δ invested capital over 5 years | Above WACC, ideally >15% | The only number that says whether *new* money earns a return. Averages hide it. | +| Fixed-cost share | Fixed costs ÷ total costs; test EBIT at −20% volume | — | Quantifies operating leverage in both directions. | +| FCF conversion | FCF ÷ net profit, full cycle | >70% | Asset-heavy companies can report rising profits while consuming every rupee in capex. | + +**Signals that invert.** +- **Asset-heavy:** strong EPS growth with FCF persistently negative is value destruction, not compounding. Ask where the cash went and what return it earns. +- **Asset-light:** a spectacular ROIC of 60%+ can signal a **reinvestment ceiling** — high returns on a base you cannot grow — which caps the compounding rate no matter how good the margin. Test whether the moat is real (brand, network effect, IP, switching costs, regulation) or merely an absence of assets, which is not a barrier to entry. +- **Asset-light with off-balance-sheet dependency** (outsourced manufacturing, leased everything, a single cloud provider) has real capital intensity sitting on someone else's balance sheet, with the associated fragility. Capitalise the leases and recompute ROIC before comparing to an asset-heavy peer. + +**The trap.** Comparing ROIC across the two models without adjusting for leases and off-balance-sheet capital, and concluding the asset-light business is a better *compounder* when it may simply be a better *cash cow*. + +--- + +## 11. Promoter and family-controlled companies + +**Recognise it.** **India:** promoter and promoter-group holding disclosed in the quarterly shareholding pattern, typically >40%. **Global:** founding family holding, dual-class share structures, board seats held by family members. See `references/08-governance.md` for the full treatment; this section covers the situation overlay. + +**What changes.** The primary risk shifts from business failure to **value extraction around minority shareholders through legal but one-sided transactions**. Diligence moves from the P&L to the notes. + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Related-party transactions | Sum of RPT sales, purchases, loans, guarantees ÷ revenue (and ÷ PAT) | Minimal, disclosed, at arm's length, stable | Every rupee routed through a promoter entity is a rupee that may not reach you. | +| Royalty / brand fee | Payment to promoter-owned entity ÷ revenue and ÷ PAT | Low single-digit % of revenue at most; scrutinise any increase | **India:** SEBI LODR requires shareholder approval where royalty to related parties exceeds 5% of consolidated turnover. | +| Promoter remuneration | Total managerial remuneration ÷ PAT; compare to peers and to the dividend payout | Well below the dividend paid to all shareholders | If the family takes more out as salary than all shareholders receive as dividend, the alignment argument fails. | +| Pledged shares | Pledged ÷ promoter holding (**India:** disclosed quarterly under SAST Reg 31) | 0%; anything above ~20% is a live risk | Pledging converts a price fall into a forced-sale spiral and possible loss of control. | +| Promoter holding trend | 5-year trajectory, and the reason for each change | Stable or rising via open-market purchases | Steady creeping increases signal confidence; a quiet sell-down signals the opposite. | + +**Governance-in-substance checks.** Are "independent" directors long-tenured associates, relatives or former employees? Is there a succession plan and which generation is operating? How many other group companies exist, and is cash routinely moved between them? Are there dual-class or differential voting rights? **India:** RPTs above ₹1,000 crore or 10% of consolidated turnover require audit committee and majority-of-minority shareholder approval under LODR Reg 23 — check whether large transactions have been sliced below the threshold. + +**Signals that invert.** +- **High promoter holding**, normally a positive alignment signal, becomes a risk when paired with heavy related-party flow, high pledging, or a history of minority-unfriendly schemes. +- **Promoter buying shares** is usually bullish, but ahead of a delisting attempt it is a squeeze on minorities, not an endorsement. +- **A low payout ratio** in a family firm may reflect long-horizon reinvestment (good) or cash being warehoused for the family's other ventures (bad). Distinguish using the ROIC on incremental capital. + +**The trap.** Treating "skin in the game" as a governance conclusion rather than a hypothesis. A genuinely aligned family owner with a long horizon is among the best structures to own; an extractive one is among the worst; **the diagnosis rests entirely on the related-party and remuneration record**, not on the size of the stake. + +--- + +## 12. State-owned enterprises (PSUs) + +**Recognise it.** Government (central or state) is the controlling shareholder. **India:** CPSEs, state utilities, public-sector banks, often with Maharatna/Navratna/Miniratna status. **Global:** national oil companies, state-owned banks and utilities in many emerging markets. + +**What changes.** The controlling shareholder has objectives other than the share price. First determine whether the company is run **for profit or for policy**, because that determines whether any quality metric can be extrapolated at all. + +**What to check.** Administered or subsidised pricing and who sets it; obligations to serve unprofitable customers or regions; mandated purchases from other state entities; subsidy receivables from government and the historical collection lag (this is where working capital goes to die); dividends and buybacks demanded by the state to plug its fiscal deficit; forced cross-holding purchases (one PSU made to buy a stake in another); capex mandated for strategic rather than return reasons; the appointment process and tenure of senior management (a chairman with 14 months left will not start a 5-year programme). **India:** DIPAM's disinvestment pipeline, the CPSE dividend policy floor, and the OFS route for government stake sales — announced government selling is a known overhang. + +**Primary metrics.** ROCE excluding subsidy receivables and excluding regulatory/policy assets; cash conversion (subsidy-driven receivables make accrual profit unreal); dividend as % of PAT and whether it is discretionary or state-mandated; capex approved on commercial vs strategic grounds; government stake and any announced sell-down; the persistent valuation discount to private peers, plotted over 10 years. + +**Signals that invert.** +- **A high dividend yield** is often the state extracting cash rather than a signal of shareholder-friendliness — and it can coexist with underinvestment. +- **Very low P/E and P/B** are usually a rational, permanent discount for policy risk, not a mispricing. The discount has existed for decades in most PSU universes. +- **Large capex programmes** may be strategically mandated and value-destroying; check the approved return assumption, not the size of the number. +- **Strong reported profit at a subsidised-price utility** can reverse the moment the subsidy formula changes — earnings are a policy variable. + +**The trap.** Buying statistical cheapness with no catalyst. The upside case in a PSU almost always requires a **specific event**: privatisation or strategic sale, pricing deregulation, a large one-off dividend or buyback, or a formal change in the dividend policy. Without one, the discount is a rational permanent feature and your return is dividends only. + +--- + +## 13. Large treasury and investment books + +**Recognise it.** Cash, bonds, listed equity stakes, real estate or non-consolidated subsidiaries exceed roughly 25% of market cap; a meaningful share of reported "other income" is interest, dividends or mark-to-market gains. + +**What changes.** Headline P/E and ROE describe a blend of two unrelated businesses. Split the company in two and value each separately: + +**(a) Core operating business.** Recompute core operating margin, core ROCE and core EPS **excluding** all investment income and mark-to-market. Value it on an operating multiple. **(b) Investment book.** Value at market (with a haircut for illiquid or strategic holdings) and net off any tax payable on realisation. + +Then: implied core P/E = (market cap − investment book value) ÷ core net profit. This is the number that matters, and it is often dramatically different from the headline. + +**Primary metrics.** Investments + surplus cash as % of market cap; core ROCE excluding the book; return earned on the investment book vs the cost of capital; share of PAT from non-operating income; capital-allocation history — what management has *actually* done with excess cash over 10 years. + +**The critical question: is the cash claimable?** Excess capital may be permanently trapped — held as regulatory capital, sitting in an overseas subsidiary subject to repatriation tax, locked inside a partly-owned entity, or simply reserved by the controlling family with no intention of distribution. **Trapped cash should be haircut heavily or excluded from the sum-of-the-parts**; treating it at face value can overstate value by a large factor. + +**Signals that invert.** +- **A low headline P/E** may exist only because a third of the market cap is cash earning treasury yields; the operating business can be far *more* expensive than it looks. It can also work the other way — do the arithmetic before concluding either. +- **A depressed ROE** may be entirely cash drag, and the operating business's return on its own capital may be excellent. Never judge such a company on consolidated ROE. +- **A rising cash pile with no distribution** is frequently the raw material for a value-destroying acquisition. Excess capital is a capital-allocation risk, not automatically a margin of safety. + +**The trap.** Double-counting: valuing the company on an EV/EBITDA multiple (which already nets off cash) and then *adding back* the cash. Pick one treatment and state it. + +--- + +## 14. Serial acquirers and roll-ups + +**Recognise it.** Several acquisitions a year, goodwill and intangibles above ~30% of total assets (often above 100% of equity), "adjusted" EPS given prominence, and a growth story told in deals. + +**What changes.** Reported growth is not a performance measure until you decompose it. Serial acquisition is either one of the best compounding models in existence or a machine for hiding organic decay and manufacturing EPS with cheap debt — **and the two look identical on a revenue chart.** + +**Primary metrics.** + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Growth bridge | Split annual growth into organic / acquired / currency, every year | Organic positive and steady | Decelerating organic growth masked by a larger deal is the first visible symptom of a roll-up breaking. | +| Return on acquisition capital | Cumulative cash spent on acquisitions over 5–10 years ÷ the incremental EBIT or FCF actually generated over the same period | >15% implied return | The single most honest test. It cannot be dressed by accounting choices. | +| ROIC **including** goodwill | NOPAT ÷ (invested capital + accumulated goodwill, including goodwill previously written off) | Stable or rising, above WACC | Excluding goodwill lets a serial overpayer report excellent returns forever. | +| Cash conversion | FCF ÷ net income | >80% sustained | Roll-ups with poor conversion are usually capitalising costs or under-investing in acquired units. | +| Purchase price allocation | Share of consideration allocated to goodwill vs amortising intangibles | More to identifiable intangibles = more conservative | Dumping consideration into non-amortised goodwill flatters reported earnings indefinitely. | +| Earn-outs / contingent consideration | Liability balance and payments due | Disclosed, modest | An off-radar claim on future cash that reduces equity value today. | + +**Accounting notes.** Under IFRS/Ind-AS 103 and US GAAP, goodwill is **not amortised** — it is impairment-tested, and impairment is discretionary in timing, so it usually arrives late and all at once. Acquisition costs, restructuring of acquired businesses and amortisation of acquired intangibles are the standard "adjusted EPS" add-backs; if a company acquires every year, these are recurring operating costs and the adjustment is not legitimate. + +**Signals that invert.** +- **Strong headline EPS growth** funded by debt at a cost below the target's earnings yield is arithmetic, not value creation. Ask whether ROIC including goodwill improved. +- **Rising goodwill with no impairment ever** is not conservatism; it is a deferred admission. +- **A large acquisition announced immediately after a weak organic quarter** is a pattern worth naming explicitly. +- **A decentralised "we never integrate" model** can be a genuine edge (low overhead, entrepreneurial units) or an excuse for no oversight — distinguish using cash conversion and same-unit organic growth. + +**The trap.** Roll-ups break when acquisition multiples rise or funding closes — both external conditions, not company decisions. Model what happens to growth if the company makes **zero** acquisitions next year, and check the funding mix (debt vs equity issuance) against the maturity schedule. + +--- + +## 15. SPACs and de-SPACs + +**Recognise it.** The company listed by merging with a special purpose acquisition company rather than through an IPO. Tell-tales: warrants trading alongside the shares, a sponsor holding "founder shares", a PIPE, and an investor presentation containing multi-year revenue projections. Predominantly a US phenomenon (**India:** domestic SPAC listings are not permitted on NSE/BSE; SPAC frameworks exist at IFSCA/GIFT City, and Indian companies have de-SPACed onto US exchanges). + +**What changes.** A de-SPAC is a **pre-IPO-quality company with public-market pricing and no IPO-grade diligence**. There is no underwriter due-diligence process of the traditional kind, no restated multi-year track record in many cases, and the merger was marketed on *projections* that a conventional IPO prospectus would not contain. Treat the projections as marketing, not guidance, and rebuild the model from historical financials only. + +**What to check.** +- **Redemption rate.** Before the merger closed, shareholders could redeem at the trust value (typically ~$10). Redemption rates above 90% were common, which means the announced cash-to-balance-sheet figure often did not arrive. Check what cash actually landed, in the 8-K/Super 8-K. +- **Dilution stack.** Sponsor promote (classically ~20% of the pre-merger share count, acquired for a nominal sum), public and private warrants, PIPE shares (often issued below the effective deal price), earn-out/vesting shares, and convertible notes taken to bridge redemptions. Compute a **fully-diluted, post-all-instruments** share count and value on that. The headline "enterprise value" of a de-SPAC deal routinely understates the true diluted cost per share. +- **Trust and timeline mechanics** (for a live SPAC, pre-merger): trust value per share, deadline to complete a deal, extension terms. A sponsor facing a deadline has a powerful incentive to complete *any* deal. +- **Post-close reporting.** Look for restatements, material weaknesses in internal control (very common), auditor changes, and delayed filings in the first 18 months. + +**Signals that invert.** +- **A projection deck showing revenue growing 10x in four years** is a negative signal about the promoter's seriousness, not evidence of opportunity. Compare the first two years of actual results against the deck — the gap is the most informative number available. +- **Trading near the $10 trust value** does not imply a floor once the merger has closed; the trust is gone and the price can go anywhere. +- **A famous sponsor** is a distribution advantage, not a diligence substitute; the sponsor's economics are earned on *completing* a deal, not on its performance. + +**The trap.** Valuing off the announced deal enterprise value and the projection deck, on a pre-dilution share count. Rebuild from actual historicals and a fully-diluted count, then apply §1 (loss-making growth) and §8 (recent IPO) in full — most de-SPACs are both. + +--- + +## 16. Catalyst, horizon and falsification + +Every situation in this file is a claim that a **value gap exists** *and* that a **mechanism will close it**. Without the mechanism, cheapness compounds at zero and the IRR decays with time even if your valuation is right. Before finishing, write down four things: + +1. **The catalyst.** The specific event: spin listing and index inclusion, deal close, refinancing completed, disinvestment or strategic sale, cycle turn evidenced by capacity closures, first profitable quarter, buyback or dividend policy change, lock-up expiry passing, resolution plan approval. +2. **The timeframe, and the IRR if it takes twice as long.** A 40% gap closing in 12 months is a 40% IRR; the same gap over 4 years is under 9% — often below the index alternative. Run both. +3. **The falsification test.** Two or three *observable* facts that would prove the thesis wrong: contribution margin still negative after two more quarters; mid-cycle margin assumption breached on the downside; the discount widening past its historical extreme with no buyback; organic growth negative ex-acquisitions; the auditor resigning. +4. **The base rate.** How often do situations of this type work? Turnarounds in structurally declining industries: rarely. Announced deals with clean regulatory paths: usually. Roll-ups after acquisition multiples rise: poorly. Anchor your probability to the reference class before adjusting for the specifics. + +Set the review trigger on the **catalyst date, not the price**. The characteristic failure mode of situational investing is endlessly re-underwriting a broken thesis because the stock keeps getting cheaper. + +--- + +## Checklist + +- [ ] Label the situation(s) explicitly before computing any multiple; multiple overlays are normal and the most conservative one wins conflicts. +- [ ] Write down which standard metrics you are switching off and why, in one sentence, in the report. +- [ ] Set a re-classification date; situations expire and companies migrate between them. +- [ ] **Cyclicals: never conclude "cheap" from a low trailing P/E.** Check margin percentile, P/B, utilisation and industry capex first — a low P/E at peak margins is the market forecasting an earnings collapse. +- [ ] Compute mid-cycle EPS from a median (not mean) full-cycle margin, and value on that; state the assumption and show ±200bps. +- [ ] At the trough, switch to P/B, EV per unit of capacity and EV/replacement cost; earnings multiples are undefined there. +- [ ] Measure cyclical leverage as net debt ÷ **mid-cycle** EBITDA and line maturities up against the expected trough years. +- [ ] Loss-makers: prove contribution margin per unit is positive and improving before anything else; value per **fully-diluted future** share count. +- [ ] Rebuild every "adjusted EBITDA" back to reported operating profit and list each add-back. +- [ ] Turnarounds: classify operational / financial / secular using volumes and peer performance; secular decline is not a turnaround. +- [ ] Require at least one hard, realised evidence marker before underwriting a turnaround — not an announcement. +- [ ] Distressed: build the full liability stack and compute the equity residual before looking at the share price; check IBC (India) or Chapter 11 (US) status and whether equity is typically extinguished. +- [ ] Spin-offs: model each entity standalone with real corporate costs added and parent allocations removed; read the scheme for how debt and liabilities were split. +- [ ] Merger arb: size on the downside to the undisturbed price, not on the spread; enumerate every condition precedent with a probability; check open-offer proportionate acceptance (India). +- [ ] Holdcos: value by SOTP net of holdco costs and tax leakage; plot the discount against its own history; require a named mechanism to close it. +- [ ] Recent IPOs: check fresh-issue vs OFS, seller cost basis, lock-up calendar, and treat a pre-IPO margin ramp as a warning. +- [ ] Micro-caps: compute days-to-exit and cap position size on liquidity before valuing anything; check auditor identity, resignations and qualified opinions. +- [ ] Split maintenance from growth capex and compute incremental ROIC before calling any asset-heavy business a compounder. +- [ ] Test whether an asset-light business's high ROIC comes with a reinvestment ceiling; capitalise leases before cross-model ROIC comparisons. +- [ ] Promoter-controlled: read every RPT, royalty and remuneration line, and check pledged-share percentage and trend. +- [ ] PSUs: identify profit-vs-policy objectives, subsidy receivable collection lags, and require a named catalyst — statistical cheapness alone is a permanent discount. +- [ ] Treasury-heavy: separate core operations from the investment book, compute implied core P/E, and haircut trapped cash. +- [ ] Serial acquirers: build the organic/acquired/currency growth bridge and compute cumulative cash spent on deals vs incremental EBIT generated. +- [ ] De-SPACs: rebuild from historicals, ignore the projection deck, and value on a fully-diluted count including sponsor promote, warrants, PIPE and earn-outs. +- [ ] Name the catalyst, the timeframe, the IRR if it takes twice as long, and two or three facts that would falsify the thesis. +- [ ] Set the review trigger on the catalyst date, not on the price. diff --git a/finance/skills/stock-analysis/references/14-accounting-comparability.md b/finance/skills/stock-analysis/references/14-accounting-comparability.md new file mode 100644 index 00000000..94609fdf --- /dev/null +++ b/finance/skills/stock-analysis/references/14-accounting-comparability.md @@ -0,0 +1,493 @@ +# Accounting Standards, Comparability and Data Integrity + +Use this when: you are about to put two or more companies in the same table, or chart one company across a period in which a standard, a currency, a year-end or a share count changed. + +Every relative conclusion in this skill rests on an unstated assumption — that the numbers on both sides of the comparison mean the same thing. They usually do not. Reporting framework, lease convention, gross-versus-net revenue, cost classification, consolidation scope, fiscal calendar and currency all move headline ratios by more than the differences in business quality you are trying to detect. This file is the pre-processing layer: establish that the inputs are comparable, or state explicitly that they are not and by how much. A comp table built on uncorrected accounting differences ranks accounting policy, not businesses — the same failure mode as ranking a sector on OPM alone. + +## Contents + +- [1. The comparability gate — record the framework before anything else](#1-the-comparability-gate--record-the-framework-before-anything-else) +- [2. The break-list: which differences actually move ratios](#2-the-break-list-which-differences-actually-move-ratios) +- [3. Inventory costing — LIFO vs FIFO/weighted average](#3-inventory-costing--lifo-vs-fifoweighted-average) +- [4. Development cost capitalisation vs expensing](#4-development-cost-capitalisation-vs-expensing) +- [5. Leases — IFRS 16 / Ind-AS 116 vs ASC 842](#5-leases--ifrs-16--ind-as-116-vs-asc-842) +- [6. Building lease-neutral EBITDA and lease-inclusive debt](#6-building-lease-neutral-ebitda-and-lease-inclusive-debt) +- [7. Revenue recognition — gross vs net (principal vs agent)](#7-revenue-recognition--gross-vs-net-principal-vs-agent) +- [8. Percentage-of-completion, contract assets and variable consideration](#8-percentage-of-completion-contract-assets-and-variable-consideration) +- [9. Cost classification — COGS vs SG&A vs other income](#9-cost-classification--cogs-vs-sga-vs-other-income) +- [10. Consolidation scope, minorities and associates](#10-consolidation-scope-minorities-and-associates) +- [11. Goodwill, PPA and acquired-intangible amortisation](#11-goodwill-ppa-and-acquired-intangible-amortisation) +- [12. Restatements, prior-period errors and re-presentation](#12-restatements-prior-period-errors-and-re-presentation) +- [13. Transition method and the adoption-year break](#13-transition-method-and-the-adoption-year-break) +- [14. Fiscal-year misalignment and TTM reconstruction](#14-fiscal-year-misalignment-and-ttm-reconstruction) +- [15. Currency — presentation, functional and translation](#15-currency--presentation-functional-and-translation) +- [16. Constant-currency and organic-growth reconciliation](#16-constant-currency-and-organic-growth-reconciliation) +- [17. Deferred tax, effective tax rate and tax-regime differences](#17-deferred-tax-effective-tax-rate-and-tax-regime-differences) +- [18. Non-GAAP figures and the quality of the adjustments](#18-non-gaap-figures-and-the-quality-of-the-adjustments) +- [19. Symmetric normalisation of one-offs and cycle](#19-symmetric-normalisation-of-one-offs-and-cycle) +- [20. Share count, dilution and per-share integrity](#20-share-count-dilution-and-per-share-integrity) +- [21. Data-provider field definitions and error patterns](#21-data-provider-field-definitions-and-error-patterns) +- [22. The cash-flow reconciliation integrity check](#22-the-cash-flow-reconciliation-integrity-check) +- [23. Sector gate — where comparability is a different language](#23-sector-gate--where-comparability-is-a-different-language) +- [24. The comparability worksheet you must produce](#24-the-comparability-worksheet-you-must-produce) +- [Checklist](#checklist) + +--- + +## 1. The comparability gate — record the framework before anything else + +Open the basis-of-preparation note (first note to the accounts) and the audit report, and record the **exact** framework for every company in the set — not "IFRS-ish". The distinctions that matter: + +| Framework | Where you meet it | What to remember | +|---|---|---| +| IFRS as issued by the IASB | Most non-US listings, many 20-F filers | The reference dialect | +| EU-endorsed IFRS | EU issuers | Endorsement lag and occasional carve-outs | +| US GAAP | 10-K/10-Q filers on EDGAR | LIFO allowed, R&D expensed, ASC 842 dual-model leases | +| **Ind-AS** (India) | Listed Indian companies, Schedule III Division II | IFRS-converged **with carve-outs** — a third dialect, not IFRS | +| Indian GAAP (I-GAAP) | Indian filings before the Ind-AS transition; small unlisted subsidiaries | Not comparable to Ind-AS; hard series break | +| J-GAAP / PRC GAAP / other local GAAP | Japan, China A-shares, several EMs | Goodwill amortisation, different consolidation practice | + +Cross-checks worth two minutes each: + +- **ADRs and 20-F filers:** a 20-F may be prepared under IFRS with **no** US GAAP reconciliation. Do not assume a US listing means US GAAP numbers. +- **India:** every listed Indian company publishes **standalone and consolidated** statements. Use consolidated unless you are explicitly analysing the parent; mixing the two across years is one of the most common silent errors in Indian data. +- **India — Ind-AS carve-outs that change numbers:** bargain-purchase gains go to capital reserve via OCI rather than the P&L; investment property is carried at **cost only** (fair value disclosed in a note); a first-time-adoption option allows continued capitalisation of exchange differences on long-term foreign-currency monetary items; foreign-currency convertible bonds may be equity-classified where IFRS would create a derivative liability. + +**Why it matters:** EV/EBITDA, ROCE, net debt/EBITDA, gross margin and P/S are not defined identically across these dialects. If the framework column is missing from your comp sheet, every ranking downstream is partly a ranking of accounting policy. + +--- + +## 2. The break-list: which differences actually move ratios + +Not all GAAP differences are worth your time. These are the ones large enough to change a conclusion, ordered roughly by how often they do: + +| Difference | IFRS / Ind-AS | US GAAP | Metrics it corrupts | +|---|---|---|---| +| Operating leases | On balance sheet; rent split into D&A + interest | Dual model; operating lease stays a single operating cost | EBITDA, EBIT, net debt, EV/EBITDA, ROCE, interest cover | +| Inventory costing | LIFO prohibited | LIFO permitted | Gross margin, inventory days, asset turnover, ROCE, cash tax | +| Development costs | Capitalised when IAS 38 criteria met | Mostly expensed (narrow software/cloud exceptions) | EBIT, EBITDA, CFO, capex, FCF, invested capital | +| Impairment reversal | Permitted (not goodwill) | Prohibited | Asset base, depreciation, later-year earnings | +| PPE revaluation | Revaluation model permitted | Cost only | Equity, D&A, ROE, ROCE, P/B | +| Defined-benefit pensions | Net interest on net liability; remeasurements to OCI | Expected return on plan assets in P&L | Operating and net margin, EPS | +| Interest/dividends in cash flow | Policy choice of section | Largely fixed | CFO, FCF, FCF yield | +| Goodwill | Impairment-only | Impairment-only (public); amortisation alternative elsewhere | EBIT, ROCE, book value | +| Bargain purchase gain | **Ind-AS:** capital reserve. IFRS: P&L | P&L | Reported PAT in acquisition years | +| Investment property | IAS 40 fair-value model permitted (**Ind-AS: cost only**) | Cost | Real-estate earnings, book value, P/B | + +Use this as a triage list: identify the two or three rows that are live for the peer set in front of you and fix those. Do not attempt a full GAAP-to-GAAP conversion — it is not achievable from public data, and the residual noise is smaller than the errors you would introduce. + +--- + +## 3. Inventory costing — LIFO vs FIFO/weighted average + +**What to do.** For US filers, read the inventory note for the **LIFO reserve** (the FIFO-minus-LIFO difference) and for any **LIFO liquidation** disclosure. Restate to a FIFO basis before comparing to IFRS or Ind-AS peers: + +- Inventory (FIFO) = reported inventory + LIFO reserve +- Equity (FIFO) = reported equity + LIFO reserve × (1 − tax rate) +- COGS (FIFO) = reported COGS − increase in LIFO reserve during the year +- Deferred tax liability increases by LIFO reserve × tax rate; net debt is unchanged + +**Why.** In an inflationary period LIFO charges newer, higher costs to COGS. The US filer shows a lower gross margin, a smaller inventory balance and a lower cash tax bill than an economically identical IFRS peer — so it looks less profitable *and* more capital-efficient at the same time, and asset turnover, inventory days and ROCE comparisons are all meaningless. A **LIFO liquidation** (selling old, cheap layers) does the reverse: a non-repeatable gross-margin gain, to be stripped under §19. + +**India:** LIFO is prohibited under Ind-AS 2, as under IFRS. The Indian check is different — confirm the cost formula (FIFO vs weighted average), overhead absorption at abnormal capacity, and the basis of net-realisable-value write-downs in the inventory note. + +--- + +## 4. Development cost capitalisation vs expensing + +**What to do.** Pull, from the intangibles note and the investing section of the cash flow statement: additions to internally generated intangibles, the amortisation charged on them, the carrying value of assets under development, and total R&D spend from the expense note or MD&A. Compute: + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Capitalisation rate | Capitalised development ÷ total R&D spend | Low and *stable*; a rising trend is the signal | A rate drifting upward converts current cost into a future asset — the cheapest way to buy margin | +| Capitalised dev ÷ EBIT | Annual capitalised additions ÷ EBIT | Material above ~10% | Sizes the EBIT overstatement versus a full-expensing peer | +| Amortisation ÷ capitalised additions | Yearly amortisation ÷ additions | Approaching 1.0 in steady state | Persistently below 1.0 means the asset balance is inflating; write-off risk builds | + +*Indicative ranges vary by market, cycle and period; the company's own history and the peer median override any absolute band.* + +**The common baseline.** The only reliably comparable treatment across an IFRS/Ind-AS and US GAAP peer set is to **expense everything**: reduce EBIT/EBITDA by capitalised additions, add back the related amortisation, reduce CFO by the same additions (they sit in investing), and remove the intangible from invested capital. Do it for every member of the set, including the ones that already expense (where the adjustment is zero), and state that you did. + +**Why.** Capitalisation simultaneously inflates EBIT, EBITDA, CFO *and* invested capital, and deflates capex-adjusted FCF. It is the single largest comparability gap in pharma, software, autos and engineering peer sets, and a well-worn earnings-management lever — capitalising in bad years, writing off in a "kitchen sink" year. + +--- + +## 5. Leases — IFRS 16 / Ind-AS 116 vs ASC 842 + +Confirm the convention for each company, then extract the same five items from every one: right-of-use asset, lease liability (current + non-current), ROU depreciation, lease interest, and the undiscounted maturity table with the discount rate. + +| | IFRS 16 / Ind-AS 116 | ASC 842 operating lease | ASC 842 finance lease | +|---|---|---|---| +| Balance sheet | ROU asset + lease liability | ROU asset + lease liability | ROU asset + lease liability | +| Income statement | Depreciation + interest | **Single operating lease cost** (straight-line) | Depreciation + interest | +| EBITDA effect | **Inflated** (rent removed) | None | Inflated | +| Reported debt in most screeners | Often excluded from "total debt" despite being a liability | Excluded | Sometimes included | +| Cash flow classification | Principal in financing → **CFO inflated** | Entirely in operating → CFO unaffected | Principal in financing | + +**Why.** For a lease-heavy business the difference is not cosmetic: retail, airlines, telecom towers, hotels, QSR, hospitals, diagnostics and 3PL logistics can see EBITDA move by tens of percent and reported debt by a multiple of pre-lease net debt. An unadjusted EV/EBITDA screen ranks the IFRS lessee as cheap and the US operating lessee as expensive, purely because of where rent sits. IFRS 16 also inflates CFO because only the interest portion stays in operating — so FCF-based screens are corrupted in the same direction. + +**Watch the discount rate.** The incremental borrowing rate is management's estimate. A low rate inflates the ROU asset and liability and back-loads interest; compare the disclosed rate to the company's own marginal borrowing cost and to peers. A rate materially below the bond curve is a soft red flag and distorts the liability you are about to add to net debt. + +--- + +## 6. Building lease-neutral EBITDA and lease-inclusive debt + +Compute **both** conventions across the *entire* peer set, then pick one, apply it to everyone, and say which you used. Never mix. + +**Convention A — pre-IFRS 16, "everyone pays cash rent" (EBITDAR-style, then deduct rent).** Best for operating comparisons and margin trends across the transition year. + +- For IFRS/Ind-AS filers: EBITDA(A) = reported EBITDA − cash lease payments (principal + interest from the cash flow statement), i.e. remove the rent benefit. +- For US operating-lease filers: EBITDA(A) = reported EBITDA (already after rent). +- Net debt(A) = interest-bearing debt only; exclude all lease liabilities from both sides. +- Capital employed(A) excludes ROU assets. + +**Convention B — fully capitalised, "all leases are debt".** Best for leverage, credit and EV work. + +- EBITDA(B) = EBITDA before all lease costs (add back rent for US operating lessees; IFRS filers already exclude it). +- Net debt(B) = interest-bearing net debt + lease liability. For US operating leases, use the reported ASC 842 operating lease liability where available; if you must estimate, use the present value of the disclosed maturity table at the company's marginal borrowing rate. A crude 8× rent multiple is a last resort — say so if you use it. +- Capital employed(B) includes ROU assets; EV includes lease liabilities. + +| Ratio | Restate under | Why | +|---|---|---| +| EV/EBITDA | B (EV and EBITDA both lease-inclusive) | The only internally consistent lease treatment for a multiple | +| Net debt/EBITDA | B, and report A alongside | Rating agencies and covenants differ; a turn of leverage is a rating notch | +| Interest cover | B: EBITDA(B) ÷ (interest + lease interest) | Rent is a fixed charge whether or not GAAP calls it interest | +| ROCE | Include ROU assets in capital employed when using B | Omitting them flatters a lease-heavy retailer's ROCE | +| EBITDA margin trend across the transition year | A | Otherwise the adoption year shows a fake margin expansion | + +**Why this matters more than it looks.** Leverage screens, covenant headroom and "cheapness" all shift by turns of EBITDA depending on convention. Most screeners exclude lease liabilities from "total debt" — meaning a lease-heavy IFRS retailer can appear both high-EBITDA and low-debt in the same row. That is not an opportunity; it is a definition. + +--- + +## 7. Revenue recognition — gross vs net (principal vs agent) + +**What to do.** Read the revenue note (IFRS 15 / ASC 606 / Ind-AS 115) and answer one question: does the company book gross transaction value or only its commission? Then triangulate — disclosed take rate × GMV should reconcile to net revenue; revenue per employee, receivable days and gross margin should look like the business model you think it is. + +High-risk models: marketplaces and aggregators, travel, ticketing, distributors and stockists, telecom handset bundles, ad-tech and media resellers, EPC contractors with pass-through equipment, pharma CDMO with customer-supplied materials, and commodity traders. + +**Why.** Two identical marketplaces can report revenue differing by an order of magnitude. Every P/S, EV/Sales, revenue-growth, revenue-per-employee and gross-margin comparison collapses if one books gross and the other net. A **change** in presentation between years is worse: it manufactures apparent revenue growth or margin expansion with zero economic change, and screeners rarely flag it. + +**Tell-tale signs to search for:** "principal versus agent", "gross versus net", "reclassification of revenue", a gross margin that jumps by many points with no cost story, or revenue growth wildly out of line with volume/GMV disclosures. + +**India note.** The introduction of GST in July 2017, combined with Ind-AS 115, removed excise duty from reported revenue for manufacturers. Reported revenue for affected companies fell by a high single-digit to low double-digit percentage with **no economic change**, and margins on revenue rose correspondingly. Any Indian revenue series or margin chart spanning FY2017–FY2018 must be flagged; never compute a CAGR straight across it without restating the earlier years net of excise. + +--- + +## 8. Percentage-of-completion, contract assets and variable consideration + +For construction, EPC, defence, capital goods, shipbuilding and long-cycle software, revenue is an estimate, not an event. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Unbilled revenue ÷ revenue | Contract assets ÷ trailing revenue | Stable; a rising multi-year trend is the signal | Rising unbilled means revenue recognised ahead of the customer's agreement to pay | +| Contract liabilities ÷ revenue | Advances and deferred revenue ÷ revenue | Healthy when high and rising in advance-funded models | Customer-funded working capital; a fall can precede an order drought | +| (Receivables + unbilled) days | (Trade receivables + contract assets) ÷ revenue × 365 | Compare to peers and own history only | The honest working-capital number in POC businesses | +| Cost-to-complete revisions | Disclosed changes in estimates ÷ segment EBIT | Small and two-sided | Recurring favourable revisions are a margin-smoothing footprint | + +*Indicative ranges vary by market, cycle and period; peer median and the company's own history override any absolute band.* + +**What to read:** the method of measuring progress (input/cost-to-cost vs output/milestone), disclosures on variable consideration, claims and incentives and the constraint applied to them, onerous-contract provisions, and the order-book-to-revenue conversion commentary. + +**Why.** A rising unbilled-to-revenue ratio is a leading indicator of optimistic cost-to-complete assumptions and future write-backs. It also makes revenue non-comparable against a peer recognising on delivery or milestones. **India:** real-estate developers moved from percentage-of-completion to completed-contract on Ind-AS 115 adoption; developer revenue and profit series are not continuous across that transition, and lumpy project completions dominate any single year. + +--- + +## 9. Cost classification — COGS vs SG&A vs other income + +**Gross margin is among the least comparable metrics in existence.** A company that puts depreciation, inbound freight, warehousing and direct labour in COGS will show a gross margin many points below an economically identical peer that puts them in SG&A. Ranking a sector on gross margin without checking classification produces a spurious ordering — exactly the single-metric failure this skill exists to prevent. + +**What to do:** + +1. Determine whether the P&L is presented **by nature** (material cost, employee benefits, other expenses — the IFRS/Schedule III convention) or **by function** (COGS, SG&A, R&D — the US convention). They are not mechanically convertible from the face of the statement. +2. For each company, locate: depreciation, freight and distribution, R&D, share-based compensation, warranty, warehousing, and royalty. Note which line each sits in. +3. Rebuild the comparison at **EBITDA and EBIT**, where most classification differences wash out. If you must use gross margin, define it yourself identically for every peer and say what you included. +4. Check "other income": is it treasury income, scrap sales, government incentives, forex, or genuine operating income? Indian filers routinely park operating items there. + +**India specifics.** Schedule III has **no gross profit line** — construct it as revenue from operations less (cost of materials consumed + purchases of stock-in-trade + changes in inventories), and apply that identical definition to every peer. "OPM" in Indian screeners and concalls means **EBITDA margin excluding other income**; a US "operating margin" means EBIT margin. Government incentives (PLI and state subsidies) may appear as other operating revenue for one company and as a credit netted against cost for another — same economics, different margin. See `03-earnings-quality.md` §1 and §3. + +--- + +## 10. Consolidation scope, minorities and associates + +**What to check.** For each material subsidiary and JV: fully consolidated, equity-accounted, or (in older data and some JV-heavy sectors) proportionately consolidated. Reconcile net income attributable to owners against total net income and compute the minority share. Look for structured entities, ESOP trusts, SPVs in infrastructure, and off-balance-sheet JVs. + +**Why.** A company with 60%-owned operating subsidiaries consolidates **100%** of revenue and EBITDA but owns **60%** of the earnings. If EV is not grossed up for minority interest, EV/EBITDA looks artificially cheap — a systematic distortion in Indian infrastructure, hospitals, cement and telecom-tower structures, and in Korean and Japanese group companies. Conversely, a peer running the identical business through equity-accounted JVs reports almost no revenue at all and looks tiny on EV/Sales. + +**Consistency rules for the EV bridge (apply to every peer identically):** + +- Add minority interest to EV — at market value where the sub is separately listed, otherwise at an implied multiple, not book value, and say which. +- Subtract the value of equity-accounted investments from EV **only if** their earnings are excluded from the EBITDA denominator. Never subtract the investment *and* keep the associate profit in the numerator metric. +- Where a listed subsidiary or holding structure dominates, switch to the sum-of-the-parts and holdco approach in `13-situations.md` rather than forcing a multiple. +- Check whether the peer's consolidation scope changed mid-year (acquisition/divestment): part-year consolidation makes growth and margin non-comparable until the anniversary. + +--- + +## 11. Goodwill, PPA and acquired-intangible amortisation + +**What to check.** Whether goodwill is amortised (some local GAAPs; the US private-company alternative) or impairment-tested only (IFRS, Ind-AS, US GAAP public). For recent acquisitions, pull the **purchase price allocation**: how much went to goodwill versus amortisable intangibles (customer relationships, brands, technology), and the useful lives assigned. Then compute acquired-intangible amortisation as a share of EBIT, and ROIC both including and excluding goodwill. + +**Why.** An acquisitive company carries a PPA amortisation drag that an organic peer does not, while goodwill inflates its capital base and depresses ROCE. Unadjusted EBIT comparisons therefore penalise acquirers and flatter organic peers arbitrarily — and adding back all intangible amortisation (the standard non-GAAP move) flatters acquirers just as arbitrarily, because the acquired customer relationships genuinely do decay. The defensible treatment: report both, and judge whether maintenance spend on the acquired asset is already inside opex (if yes, the add-back is more justifiable; if no, it is not). + +**Red flags:** an allocation overwhelmingly to goodwill (defers all cost recognition), useful lives far above the peer norm, goodwill never impaired through a demonstrable downturn, or a single cash-generating-unit structure that lets a strong business shelter a failing acquisition from impairment testing. Cross-reference `07-forensic-red-flags.md` for the serial-acquirer pattern. + +--- + +## 12. Restatements, prior-period errors and re-presentation + +**How to detect one without being told.** Put last year's annual report next to this year's and compare the **comparative** column line by line. Any difference is a restatement, a reclassification, or a discontinued-operations re-presentation. This mechanical check finds restatements that were never announced as such. + +**What to search for:** "restated", "reclassified", "prior period error", "Ind-AS 8" / "IAS 8", "revision to previously issued financial statements", and in the US, an **Item 4.02 8-K** (non-reliance on previously issued statements). In India, also check exchange filings for revised results, auditor qualifications carried into the next year, and any NFRA or SEBI action. + +**Classify what you find** — the four types have very different meanings: + +1. **Error correction / non-reliance** — a governance event. Among the strongest standalone predictors of further negative surprises. Treat as a hard flag, not a data-cleaning task. +2. **Voluntary accounting policy change** — read the justification; policy changes that raise reported profit deserve scepticism. +3. **Discontinued operations re-presentation** — benign, but it silently rebases historical revenue and margin; your prior-year series must be re-pulled. +4. **Business-combination measurement-period adjustment** — mechanical, but it moves goodwill and PPA amortisation retrospectively. + +**Why it matters for data integrity.** Providers commonly store the **originally reported** figure for old years and the **restated** figure for recent ones. Multi-year growth rates and CAGRs computed across that seam are arithmetic nonsense, and the corruption is invisible in the output. When a restatement exists, rebuild the series from filings for the affected years. + +--- + +## 13. Transition method and the adoption-year break + +For every new standard adopted in your window (IFRS 16 / Ind-AS 116, IFRS 15 / Ind-AS 115, IFRS 9 / Ind-AS 109, ASC 842 / 606 / 326 CECL, IFRS 17), determine the transition method: + +- **Full retrospective** — comparatives restated; the series is continuous. +- **Modified retrospective / cumulative catch-up** — comparatives **not** restated; a plug goes to opening retained earnings. The adoption year is a hard break, and growth, margin and leverage computed across it are meaningless. + +Mark the transition year on every chart you build and in any table spanning it. + +**India — the series breaks you will actually hit:** + +| Break | Effect on the series | +|---|---| +| I-GAAP → Ind-AS (phased from FY2017 for larger companies, FY2018 for the rest) | Pre-transition years are a different framework. Long-run charts crossing this point mix two GAAPs. | +| GST / excise removal from revenue (FY2018) | Reported revenue steps down for manufacturers with no economic change (§7). | +| Ind-AS 115 for real estate (POC → completed contract) | Developer revenue and PAT series discontinuous and lumpy thereafter. | +| Ind-AS 116 leases (FY2020) | EBITDA and reported debt step up for lease-heavy sectors. | +| Section 115BAA tax election (from FY2020) | Statutory rate step-down plus one-off deferred-tax remeasurement (§17). | + +**US/global equivalents:** ASC 606 (2018-19), ASC 842 (2019), CECL for lenders (2020-23 phased), IFRS 17 for insurers (2023) — IFRS 17 in particular broke the entire historical earnings series for insurers; do not chart through it. + +--- + +## 14. Fiscal-year misalignment and TTM reconstruction + +Record every company's fiscal year-end. Common patterns: **India and Japan 31 March**; many US retailers a **52/53-week year** ending late January/early February; Australia and several others 30 June; most of the rest 31 December. + +**Rules:** + +- If year-ends differ by **more than one quarter**, do not compare annual figures — rebuild a **trailing-twelve-month** series from quarterly data so every company covers the same calendar window, and state the window explicitly ("TTM to 30 June 2026"). +- Beware the **label collision**: an Indian "FY25" means the year ended March 2025; a US "FY2025" often means calendar 2025. Comparing them offsets the economic period by nine to twelve months. +- Flag **53-week years** (an extra ~2% of trading in retail) and remove the extra week before computing growth. +- Flag **stub / transition periods** when a company changes its year-end — a 9-month or 15-month "year" destroys every ratio computed on it. +- **India:** quarterly results under SEBI LODR are limited-reviewed, not audited, and **Q4 is a balancing figure** (audited full year minus the three reviewed quarters). True-ups cluster there, so a TTM built through a Q4 inherits them. See `03-earnings-quality.md`. + +**Why.** A one-quarter offset is enough to place two companies on opposite sides of a commodity move, a rate cycle or a demand shock — making one look like a share-gainer when it is merely earlier in the calendar. + +--- + +## 15. Currency — presentation, functional and translation + +**What to identify:** the presentation currency, the functional currency of the major operating subsidiaries, the translation method (current-rate: assets/liabilities at closing rate, P&L at average rate, difference to OCI as the cumulative translation adjustment), and whether any subsidiary sits in a hyperinflationary economy requiring IAS 29 / Ind-AS 29 restatement. Check whether the company **changed** its presentation currency in the period — this silently rebases the entire history. + +**Conversion rules when comparing across currencies (get these wrong and you inject percentage-point errors):** + +- Income statement and cash flow items → **average rate** for the period. +- Balance sheet items → **closing rate** at the period end. +- Never apply today's spot rate to historical years — it destroys the growth series by re-denominating each year at a rate it never traded at. +- Ratios that are currency-on-currency (margins, turnover, leverage, ROCE) need **no** conversion. Convert only when comparing absolute size, EV, or per-share values. +- **India:** figures are in **₹ crore** (1 crore = 10 million) or **₹ lakh** (1 lakh = 0.1 million). Unit errors between crore, lakh, million and billion are the single most common arithmetic failure in cross-market work. Restate everything to one unit at the point of extraction and label the column. + +**Where the FX distortion shows up:** read the CTA balance in equity (a large and growing CTA means a big translation exposure) and the FX gain/loss line in the P&L (transaction exposure, often on foreign-currency debt — this is a financing item, not operating performance, and must be normalised out under §19). + +--- + +## 16. Constant-currency and organic-growth reconciliation + +Find management's bridge from reported growth to organic/constant-currency growth: **FX · acquisitions · divestments · scope and accounting changes · extra trading week**. If it is not disclosed, rebuild it yourself from segment and acquisition disclosures. + +**Verify, do not accept:** + +- Acquisitions are excluded from "organic" for the full **12-month anniversary**, not just the stub period. +- Divestments are removed from the **base year** too, not only the current one. +- Constant currency uses prior-year average rates applied to current-year local results — not closing rates. +- The definition did not change between years (it often does, always in a flattering direction). + +**Why.** "Organic" is an unaudited, company-defined term. Without a like-for-like bridge you cannot distinguish execution from a currency tailwind or from debt-funded bolt-on M&A — and those three deserve completely different multiples. A company whose entire growth premium is FX will de-rate the moment the currency turns, and one whose growth is acquisition-funded is buying its growth with the balance sheet you are also valuing. + +--- + +## 17. Deferred tax, effective tax rate and tax-regime differences + +**What to do.** Reconcile the effective tax rate to the statutory rate using the tax note, and identify the drivers: tax holidays and incentive regimes, geographic mix, unrecognised deferred tax assets, prior-year settlements, and one-off remeasurements. Then form a view on the **sustainable** rate and use it in normalised earnings. + +| Check | How | Why it matters | +|---|---|---| +| ETR vs statutory rate | Tax note reconciliation, 5 years | A persistent gap must have a named, dated cause — holidays expire | +| Cash tax vs P&L tax | Tax paid in the cash flow statement ÷ PBT | A large persistent gap points to capitalisation, accelerated depreciation, or aggressive positions | +| Deferred tax asset recognition | DTA note; unrecognised losses | Recognising a DTA on carried-forward losses creates non-cash profit; US GAAP uses valuation allowances, IFRS a single probability model | +| Rate-change remeasurement | One-off tax line in the year of a statutory change | Non-repeatable; strip from normalised earnings both ways | + +**Why it matters for comparability.** Cross-border comparisons on net margin, ROE and P/E are dominated by tax regime, not operating performance. Compare at **EBIT/EBITDA**, or normalise every peer to a sustainable tax rate, before drawing a bottom-line conclusion. Presentation also differs: IFRS/Ind-AS classify all deferred tax as non-current, and IFRS has no valuation-allowance mechanic. + +**India:** the concessional regime under section 115BAA (from FY2020) produced both a permanent step down in the statutory rate and a **one-off deferred-tax and MAT-credit remeasurement** in the year of election. Any margin or EPS series crossing that point contains a policy step and a one-off; separate them. Also check SEZ / export-incentive holidays with known expiry dates — an IT or pharma peer enjoying a holiday that lapses next year has a structurally rising tax rate that the trailing P/E does not show. + +--- + +## 18. Non-GAAP figures and the quality of the adjustments + +**Reconcile every "adjusted" number back to the statutory number**, then tabulate the add-backs by type and by year. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Adjusted-to-statutory gap | (Adjusted PAT − reported PAT) ÷ reported PAT | Small and non-recurring | A persistent gap is a measurable governance signal | +| Cumulative add-backs ÷ cumulative reported profit | Sum over 5–10 years | Well under a fifth of profit | Sizes how much of "earnings power" is a management assertion | +| Recurrence count | Consecutive years each "one-off" item appears | 1, occasionally 2 | Restructuring in five straight years is an operating cost with a euphemism | +| SBC ÷ revenue and SBC ÷ EBITDA | From the cash flow statement or the SBC note | Compare to sector, not absolute | SBC is a real cost of labour; adding it back overstates margin and, with buybacks, hides dilution | + +*Indicative ranges vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**Rules of thumb worth defending:** never accept an add-back for share-based compensation; treat recurring restructuring as operating cost; treat acquired-intangible amortisation as an adjustment you report **both ways** (§11); treat "one-off" litigation as recurring if the company is structurally litigious. + +**India:** the equivalent is the **exceptional items** line under Schedule III (which sits between "profit before exceptional items and tax" and PBT) — there is no direct US analogue. Read the note behind it every year and track how often it is populated. Companies also present "adjusted EBITDA" in investor presentations that reconciles to nothing in the audited statements; use the statutory figures and rebuild adjustments yourself. + +--- + +## 19. Symmetric normalisation of one-offs and cycle + +Build a normalised earnings series by removing, **with identical rigour in both directions**: + +- Gains: asset and stake sale gains, insurance recoveries, tax settlements in the company's favour, write-backs of provisions, bargain purchase gains, fair-value gains on investments, LIFO liquidation benefits. +- Losses: impairments, restructuring, litigation charges, forex losses on debt, business-interruption effects, one-time regulatory penalties. + +Then, for cyclical sectors, use **mid-cycle margins over a full cycle** rather than the trailing year — commodities, autos, shipping, chemicals, cement and lenders are almost never representative in any single year. + +**Why.** The habitual bias is to strip losses and keep gains, which mechanically inflates normalised earnings and makes a "normalised P/E" a marketing number. Symmetric normalisation is what makes mid-cycle P/E and EV/EBIT usable. **Document every adjustment with its note reference** — an undocumented normalisation cannot be audited by the next reader (including you, next quarter). + +--- + +## 20. Share count, dilution and per-share integrity + +**What to use.** **Diluted weighted-average shares from the EPS note**, not the current outstanding count from a data feed. Then: + +- Adjust the entire historical per-share series for splits, bonus issues, share consolidations, and rights issues (via the **theoretical ex-rights price factor** — a rights issue is part capital raise, part bonus, and ignoring the factor creates a fake per-share drop). +- Add outstanding options, RSUs, warrants and convertibles — and check the anti-dilution mechanics of convertibles and any reset clauses. +- Include **all** share classes in market cap: dual-class, DVR lines (India), preference shares that are economically equity, and unlisted classes. Providers routinely capitalise only the primary listed line. +- Check shares held by an **ESOP/ESOS trust** and treasury shares — conventions differ on whether they are netted out. +- **India:** confirm the count against the shareholding pattern filed with the exchanges (promoter, public, DII/FII), and check for warrants issued to promoters on a preferential basis, which convert at a pre-set price and dilute on a known schedule. + +**Why.** Unadjusted or partially adjusted per-share history creates fake growth and fake collapses. Multi-class and multi-line issuers — common in India, Brazil, Korea and Europe — are systematically mis-capitalised, which understates EV and makes the stock look far cheaper than it is. This is the most frequent single cause of a screener showing an implausibly low P/E. + +--- + +## 21. Data-provider field definitions and error patterns + +**Before you screen on a field, read its definition.** For every metric, answer: + +- Does "**debt**" include lease liabilities, preference shares, acceptances/bill discounting, and perpetual instruments? +- Is "**EBITDA**" EBIT + D&A from the filing, or a vendor-standardised model? Does it include other income? +- Is "**EPS**" basic or diluted, reported or adjusted, continuing operations or total? +- Is the multiple on **trailing, forward-consensus, or last-fiscal-year** data — and if forward, how many contributors? +- Is the series **consolidated or standalone**? (India — providers sometimes splice.) +- Is the currency tag correct, and are units crore/lakh/million consistent? + +**Then hand-verify the top three and bottom three hits of any screen against the primary filings before acting on it.** This is not optional diligence; it is the highest-yield twenty minutes in the whole process. + +**Why.** Provider errors cluster precisely where screens are most extreme: misparsed exceptional items, a missing quarter in a TTM, a stale or unsplit share count, a mis-tagged currency, standalone spliced onto consolidated. The outliers a screen surfaces are disproportionately data artefacts rather than opportunities — which is exactly why the screen surfaced them. Source hierarchy and provider-specific quirks are in `01-data-sourcing.md`; the primary sources to fall back to are EDGAR (10-K/20-F/8-K, XBRL company facts) and, in India, the BSE/NSE announcement filings, the annual report PDF and MCA filings. + +--- + +## 22. The cash-flow reconciliation integrity check + +Run this on every company before you trust any income-statement-derived ratio. + +| Check | How to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Cumulative CFO ÷ cumulative PAT | Sum both over 5–10 years | Around 1.0 or above for most non-financials | Persistent divergence is the single most reliable flag for revenue-recognition or capitalisation aggression | +| CFO − capex vs reported FCF | Rebuild from the statement | Should tie exactly | If it does not, the company's FCF definition excludes something — find out what | +| Cumulative FCF vs cumulative reported profit | Sum over a full cycle | Directionally consistent | Profit that never becomes cash over a decade is not profit | +| Interest/dividend classification | Read the cash flow statement sections | Restate to one convention across peers | IFRS permits choices; US GAAP largely fixes them | + +*Indicative ranges vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**The classification trap in detail.** Under IFRS/Ind-AS, interest paid may sit in operating **or** financing, and dividends received in operating **or** investing. Common IFRS practice puts interest paid in financing; US GAAP puts it in operating. For a levered company this means the IFRS filer's CFO is **higher** than an identical US filer's by the entire interest bill — and so is its FCF and FCF yield. Restate every peer to one convention (put interest paid in operating for all, or below CFO for all) and say which. + +**Also watch:** supply-chain finance / reverse factoring (a borrowing that presents as trade payables and flatters CFO — disclosure is now required under both frameworks, so its absence is itself informative), receivables securitisation and factoring, capitalised interest, and capex reclassified between operating and investing. Cross-reference `04-balance-sheet-and-cashflow.md` and `07-forensic-red-flags.md`. + +--- + +## 23. Sector gate — where comparability is a different language + +Before applying any generic template, confirm the metric set is even defined for the industry. Establish comparability **inside the sector's own accounting language** first. + +| Sector | The accounting fault line | Consequence | +|---|---|---| +| Banks / NBFCs | IFRS 9 / Ind-AS 109 expected credit loss vs US CECL vs legacy incurred-loss; IRAC norms in India | EBITDA and EV are meaningless; compare NII, NIM, provisioning coverage, GNPA/NNPA, capital adequacy | +| Insurers | IFRS 17 vs prior embedded-value regimes; Indian insurers on Ind-AS 104-era practice | The historical series is broken at the IFRS 17 boundary; use VNB, EV, combined ratio | +| Real estate / REITs | IAS 40 fair-value gains flow through the IFRS P&L (**Ind-AS: cost model only**); US GAAP cost | An IFRS developer's "profit" may be unrealised revaluation; use NAV, FFO/AFFO | +| Utilities / regulated | Regulatory deferral accounts and regulatory assets | Reported earnings reflect a regulatory compact, not free-market margin | +| Oil & gas E&P | Successful-efforts vs full-cost capitalisation | Asset base, DD&A and EBIT differ materially between identical wells | +| Miners | Stripping-cost capitalisation, reserve-based depreciation, rehabilitation provisions | Unit-cost and ROCE comparisons need identical policies | +| Shipping / airlines | Charter/lease structures, residual value and useful-life assumptions | Lease convention (§5-6) dominates every leverage metric | + +Route to `references/sectors/_index.md` for the sector-specific metric set. The governing principle applies with full force here: for banks, insurers, REITs and miners the standard ratios are undefined or inverted, and forcing them produces confident nonsense. + +**Audit reliability is a precondition, not a section.** If the auditor resigned mid-cycle, a material subsidiary is audited by a different small firm, there is a going-concern emphasis, an adverse ICFR opinion, or a recurring key audit matter on revenue recognition, then none of the above matters — the inputs are unreliable. Handle this before comparability work; see `08-governance.md` and `15-document-diligence.md`. + +--- + +## 24. The comparability worksheet you must produce + +Keep one row per company and carry it into the report. This is the artefact that makes a comp table auditable and stops someone (including you) from silently sorting a column and reintroducing the single-metric ranking error. + +| Column | What it records | +|---|---| +| Framework | IFRS / US GAAP / Ind-AS / local GAAP; ADR reconciliation yes/no | +| Fiscal year-end and period used | e.g. "31 Mar; TTM to Jun-2026" | +| Currency and unit | Reporting currency; conversion rate convention used (avg for P&L, closing for BS) | +| Basis | Consolidated / standalone; minority share of PAT | +| Lease convention | A (pre-IFRS 16) or B (fully capitalised); lease liability added to net debt (yes/no) | +| Revenue basis | Gross or net; take rate if applicable | +| Inventory | LIFO restated to FIFO? LIFO reserve value | +| R&D | Expensed / capitalised; capitalisation rate; adjustment applied | +| Normalisations | List of items removed, with note references and sign | +| Breaks | Transition years, restatements, currency changes, stub periods flagged | +| Data source | Filing vs provider, and which fields were hand-verified | + +Also record the peers you **excluded** and why. Peer-set construction itself is in `10-peer-set.md`; this worksheet is the comparability layer that sits under it. + +State in the report, in one sentence: *"Peers are compared on [lease convention], [currency convention], [period], with [named adjustments] applied identically to all members; residual non-comparability is [X]."* If you cannot write that sentence, the comparison is not ready. + +--- + +## Checklist + +- [ ] Record the exact reporting framework for every company in a column; note Ind-AS carve-outs and whether an ADR has a GAAP reconciliation. +- [ ] India: use consolidated statements throughout; never splice standalone and consolidated across years. +- [ ] Identify the two or three GAAP differences that are actually live for this peer set; fix those, not all of them. +- [ ] Restate US LIFO filers to FIFO (inventory, equity, COGS, deferred tax) before any margin or turnover comparison. +- [ ] Compute the R&D capitalisation rate; build a full-expensing baseline across the whole set and say you did. +- [ ] Pull ROU assets, lease liabilities, ROU depreciation, lease interest, maturity table and discount rate for every company. +- [ ] Build both lease conventions (A: pre-IFRS 16; B: fully capitalised); apply one to all peers, state which, and under B put lease liabilities in EV and ROU assets in capital employed. +- [ ] Confirm gross vs net revenue recognition and reconcile take rate to revenue; flag any presentation change between years. +- [ ] India: flag the FY2018 excise/GST revenue step-down before computing any revenue CAGR across it. +- [ ] Track unbilled revenue ÷ revenue and (receivables + unbilled) days for POC businesses. +- [ ] Rebuild margins at EBITDA/EBIT where classification differs; define gross margin identically for all peers or do not use it. +- [ ] Reconcile PAT attributable to owners vs total; gross EV up for minority interest; handle associates consistently on both sides. +- [ ] Pull the PPA for recent deals; report ROIC with and without goodwill and quantify PPA amortisation as a share of EBIT. +- [ ] Compare last year's comparatives to this year's line by line to detect unannounced restatements; classify what you find. +- [ ] Identify the transition method for every new standard; mark adoption years on every chart. +- [ ] India: flag the I-GAAP→Ind-AS break, Ind-AS 115 for real estate, Ind-AS 116, and the 115BAA tax election. +- [ ] Align fiscal periods; rebuild TTM from quarterly data where year-ends differ by more than a quarter; strip 53rd weeks and stub periods. +- [ ] Use average rates for P&L, closing rates for balance sheet; never re-denominate history at today's spot; standardise crore/lakh/million at extraction. +- [ ] Rebuild the reported-to-organic growth bridge (FX, M&A, divestments, extra week) and verify the 12-month anniversary rule. +- [ ] Reconcile ETR to the statutory rate and to cash tax; normalise to a sustainable rate; identify expiring holidays. +- [ ] Reconcile every adjusted figure to statutory; count how many years each "one-off" recurs; never add back share-based compensation. +- [ ] Normalise gains and losses symmetrically, with a note reference for each adjustment; use mid-cycle margins in cyclicals. +- [ ] Use diluted weighted-average shares from the EPS note; adjust history for splits, bonuses and rights (TERP); capitalise all share classes. +- [ ] Read the provider's definition of every field you screen on; hand-verify the top and bottom three hits against primary filings. +- [ ] Run cumulative CFO ÷ cumulative PAT over 5–10 years; restate interest/dividend classification to one convention; check for reverse factoring, securitisation and capex reclassification. +- [ ] Apply the sector gate — confirm the metric set exists for banks, insurers, REITs, utilities, E&P and miners before comparing. +- [ ] Confirm audit reliability first; unreliable inputs void every adjustment above. +- [ ] Produce the comparability worksheet, list excluded peers with reasons, and write the one-sentence comparability statement in the report. diff --git a/finance/skills/stock-analysis/references/15-document-diligence.md b/finance/skills/stock-analysis/references/15-document-diligence.md new file mode 100644 index 00000000..80c8638d --- /dev/null +++ b/finance/skills/stock-analysis/references/15-document-diligence.md @@ -0,0 +1,629 @@ +# Primary-Document Diligence + +Use this when: you have moved past screener data and need to work the actual filings — annual report, auditor's report, transcripts, rating rationales, exchange disclosures — either as the Stage 3 red-flag pass, the Stage 4 deep dive, or any time a number from an aggregator needs to be believed rather than merely quoted. + +Everything else in this skill assumes the inputs are real. This file is where you establish that. A ratio computed from a figure you never traced to a primary document is a guess with decimal places, and the documents below are also the only place where the *non-quantitative* evidence lives — the auditor's own map of where the balance sheet is fragile, the promises management made three years ago, the guarantee issued to a promoter entity, the clause in CARO that says statutory dues went unpaid for six months. The governing principle applies throughout: a disclosure is meaningless until you know the sector and the company's own history. A large contingent liability is routine for an EPC contractor and alarming for a branded consumer company; a KAM on loan-loss provisioning is expected at every bank and would be extraordinary at a software firm. + +## Contents + +- [0. The annual report contains all of this — a complete contents map](#0-the-annual-report-contains-all-of-this--a-complete-contents-map) +- [1. Reading order when time is limited](#1-reading-order-when-time-is-limited) +- [2. The liability gradient: how much each document is worth](#2-the-liability-gradient-how-much-each-document-is-worth) +- [3. MD&A / Management Discussion and Analysis](#3-mda--management-discussion-and-analysis) +- [4. Notes to accounts: policies, estimates and changes therein](#4-notes-to-accounts-policies-estimates-and-changes-therein) +- [5. Contingent liabilities and commitments](#5-contingent-liabilities-and-commitments) +- [6. Related-party transactions note](#6-related-party-transactions-note) +- [7. Segment note](#7-segment-note) +- [8. The auditor's report — read this in full, every year](#8-the-auditors-report--read-this-in-full-every-year) +- [9. Consolidated vs standalone, AOC-1 and the subsidiary map](#9-consolidated-vs-standalone-aoc-1-and-the-subsidiary-map) +- [10. Earnings-call transcripts and Q&A behaviour](#10-earnings-call-transcripts-and-qa-behaviour) +- [11. Investor presentations vs audited filings](#11-investor-presentations-vs-audited-filings) +- [12. DRHP / RHP / S-1 and offer documents](#12-drhp--rhp--s-1-and-offer-documents) +- [13. Credit rating rationales and rating actions](#13-credit-rating-rationales-and-rating-actions) +- [14. Exchange filings and continuous disclosure](#14-exchange-filings-and-continuous-disclosure) +- [15. Shareholding pattern and promoter pledge](#15-shareholding-pattern-and-promoter-pledge) +- [16. Proxy / AGM materials and voting results](#16-proxy--agm-materials-and-voting-results) +- [17. Short-seller reports, forensic notes and adverse media](#17-short-seller-reports-forensic-notes-and-adverse-media) +- [18. Secretarial audit and Directors' Report annexures](#18-secretarial-audit-and-directors-report-annexures) +- [19. Sector translation: which documents replace the standard set](#19-sector-translation-which-documents-replace-the-standard-set) +- [20. Archive and data-provenance hygiene](#20-archive-and-data-provenance-hygiene) +- [Checklist](#checklist) + +--- + +## 0. The annual report contains all of this — a complete contents map + +The annual report is the single most complete document a company publishes about itself, and **almost every section carries something an investor should weigh** — the strategy in the chairman's letter, the pay ratio in an obscure annexure, the covenant in a borrowings note, the one live case in a litigation schedule that is otherwise routine. The discipline is therefore: **read and consider all of it, then report selectively.** Coverage in the reading is comprehensive; the write-up stays focused on what proved material. Skipping a section because it "looks like boilerplate" is exactly how the single live disclosure inside it gets missed — the boilerplate-versus-substance judgement is made *after* reading the section, never by not reading it. + +Use the map below as a **coverage checklist**: walk every section, extract what matters, and for a section that is genuinely empty this year, record "read — nothing material" rather than leaving it unopened (next year it may not be empty). §1 below then tells you the *order* to read the high-yield sections under time pressure, and §§3–18 tell you *how* to read each one. This map exists so that nothing is skipped. + +### Indian annual report (Companies Act 2013 + SEBI LODR) — section by section + +| Section | What lives here | What to pull | +|---|---|---| +| Financial highlights / 5–10-year record | The company's own multi-year summary | The long-run trend, and any year quietly restated or omitted from the series | +| Chairman's / MD's letter | Strategy, capital-allocation intent, tone | Stated priorities and promises — checked next year against delivery | +| Corporate overview / business model | Products, brands, plants, geographies, operating KPIs | The revenue-model map and operational scale, before the numbers frame it | +| **MD&A** | Industry structure, segment performance, outlook, risks & concerns, internal-control adequacy, **key financial ratios with explanation of any change >25%** | Volume/price/mix decomposition, guidance, and the ratio-change explanations (§3) | +| **Board's / Directors' Report** | State of affairs, dividend, share-capital/ESOP changes, deposits, **s.186 loans/guarantees/investments**, **AOC-2 related-party contracts**, risk-management policy, board evaluation | The statutory narrative plus its annexures (below) | +| — Annexure **AOC-1** | Salient financials of every subsidiary / associate / JV | Loss-making, negative-net-worth, newly acquired and newly deconsolidated entities (§9) | +| — Annexure **CSR report** | Spend vs 2% obligation, projects, unspent transfers | A clean compliance signal; repeatedly deferred/unspent amounts (§18) | +| — Annexure **particulars of employees (s.197)** | Median remuneration, MD/WTD pay, pay ratio, top earners | Promoter/KMP pay vs PAT and its trajectory (§16) | +| — Annexure energy / tech absorption / **forex** | R&D and technology, **forex earnings and outgo** | Net forex exposure and any large unexplained outflow | +| **Corporate Governance Report** | Board composition & independence, committee membership and **attendance**, remuneration policy, RPT policy, **general shareholder information** (AGM, dividend, listing, stock data, shareholding distribution, plant locations), dividend distribution policy | Governance quality and the full shareholder-information block (§8, §16, §18) | +| **BRSR** (top listed cos) | ESG across 9 principles; BRSR-Core assured metrics | Regulatory, environmental and litigation exposure; treat unassured parts as narrative (§18) | +| Secretarial audit (MR-3) + LODR 24A | Statutory-compliance qualifications | Any qualification — late filings, invalid appointments, RPT/committee failures (§18) | +| **Independent Auditor's Report** (standalone *and* consolidated) | Opinion, basis, **KAMs**, EOM, Other Matter, **CARO** annexure, **IFC** opinion | The highest-yield section per minute — read in full, both bases (§8) | +| Balance sheet, P&L (+OCI), cash flow, changes in equity | The four primary statements | The numbers — reconcile all four and tie them together (§4; 01-data-sourcing §4) | +| Significant accounting policies + critical estimates | What "profit" means for this company | Revenue recognition, depreciation lives, capitalisation, ECL, impairment, DTA (§4) | +| **Notes to accounts — every one** | PPE/CWIP ageing, intangibles, **receivables & payables ageing**, borrowings with terms & covenants, revenue disaggregation, employee-benefit/actuarial, tax & deferred tax, **segment**, **related party (incl. year-end balances)**, **contingent liabilities & commitments**, financial-instrument risk (credit/liquidity/market), leases, **ratios**, **subsequent events** | This is where the analysis actually is — not one note is safe to skip (§4–§7) | + +### US 10-K (SEC) — item by item + +| Item | Contains | What to pull | +|---|---|---| +| 1 Business | Model, products, customers, competition, seasonality, regulation | The business map and moat evidence | +| 1A Risk Factors | Legally-obliged risk admissions | Diff across years; a dropped risk is a disclosure choice (§3) | +| 1C Cybersecurity | Cyber-risk governance and material incidents | Incident history and board oversight | +| 2 Properties / 3 Legal Proceedings | Facilities; litigation | Owned-vs-leased footprint; material litigation (§5) | +| 5 Market / dividends / repurchases | Buybacks, dividends, equity-plan info | Capital returned, and at what prices | +| 7 MD&A / 7A Market risk | Management narrative; FX/rate/commodity exposure | Growth decomposition, guidance, hedging (§3) | +| 8 Financial statements & notes | Statements + full notes + segment | Same depth as the Indian notes above (§4–§7) | +| 9A Controls & Procedures | ICFR assessment | Material weakness — and whether a 404(b) auditor attestation exists at all (§8.6) | +| 10–14 (often via DEF 14A) | Directors/governance, **executive comp**, **security ownership**, **related transactions**, accountant fees | Governance, pay-for-performance, RPTs, auditor independence (§16) | +| 15 Exhibits | **Ex-21 subsidiaries**, material contracts, debt indentures | Group map and covenant packages | + +For sectors where the standard set is replaced (banks, insurers, REITs, miners, pharma), the additional documents in §19 sit **alongside** this map, not instead of it. + +### Where abnormalities concentrate — the anomaly scan + +Reading every section is *coverage*; this is the *detection* lens laid over it. A handful of sections are where genuine abnormalities almost always surface first — legal disputes, related-party dealings, and the shareholding-and-pledge pattern chief among them — and a serious one here can outweigh every positive on the scorecard, so it escalates to the Stage 3 kill-criteria screen rather than sitting in a footnote. For each, the question is never "is there a number?" but "does the pattern deviate from this company's own history and its peers?" + +| Annual-report section | Normal | Abnormal — the tell | Go deep | +|---|---|---|---| +| **Litigation / legal proceedings & contingent-liability note** | Routine tax disputes, small vs net worth, stable | Contingent liabilities approaching or exceeding net worth; a demand growing every year with no provision; guarantees to entities that are *not* consolidated subsidiaries; the largest item also flagged as a KAM | §5; `07` §10 | +| **Related-party transactions note** | Small, stable, arm's-length, board-approved | RPT sales/purchases a rising share of the total; interest-free or perpetually-rolled advances to promoter entities; a new related party with a large first-year transaction; year-end balances growing regardless of performance; transactions sized just under approval thresholds | §6; `07` §10 | +| **Shareholding pattern & pledge** | Promoter stake stable, zero pledge, ≥25% public float | Promoter stake sliding over consecutive quarters; pledge rising or >25% of promoter holding; pledge against *promoter-entity* borrowing; quiet exits by long-standing domestic funds; a retail surge alongside an institutional exit | §15; `07` §10 | +| **Auditor's report & CARO** | Clean opinion; procedural CARO answers | Any qualification / emphasis-of-matter / going-concern; CARO positives on fraud, unpaid statutory dues, loan default, evergreening, short-term-funds-for-long-term-use, or bank-returns-vs-books divergence; mid-term auditor resignation | §8; `07` §8, §12 | +| **Accounting policies & estimates** | Stable year to year | A useful-life extension, capitalisation loosening, or estimate change that lifts profit with no cash effect — especially a policy changed the year the number it flatters turned down | §4; `07` §5, §7 | +| **Year-over-year disclosure** | Consistent detail | A disclosure that *disappears* — a segment folded into "others", a named large customer dropped from the concentration note, a KPI or volume figure that stops being reported | `07` §7 | + +The calibration discipline from `references/07-forensic-red-flags.md` §16 governs every row: state the innocent explanation alongside the flag, require a *cluster* pointing at the same line item before calling it a finding, and never assert fraud — describe what the disclosure shows and what evidence would resolve it. + +--- + +## 1. Reading order when time is limited + +Documents are not equally informative per minute spent. Work down this list and stop when the time budget runs out; the order is deliberately front-loaded with the disclosures that most often end an analysis outright. + +| # | Read | Time | Why it is this early | +|---|---|---|---| +| 1 | **Auditor's report** — opinion paragraph first, then KAMs, EOM, Other Matter | 15 min | A qualified or adverse opinion invalidates the numbers you were about to analyse. Free of charge, the auditor tells you which line items are most fragile. | +| 2 | **CARO annexure** (India) / **Item 9A controls + 8-K Item 4.01/4.02 history** (US) | 15 min | Factual yes/no answers the narrative cannot smooth over: defaults, unpaid statutory dues, fraud reported, auditor resignation, non-reliance on prior financials. | +| 3 | **Related-party note + contingent-liability note** | 20 min | The two commonest routes for value to leave a minority shareholder, and both are quantifiable in one sitting. | +| 4 | **Cash flow statement + segment note** | 20 min | Where the profit actually is and whether it became cash. Segment ROCE is usually the most surprising number in the report. | +| 5 | **Shareholding pattern, last 12 quarters, incl. pledge** | 10 min | Promoter stress and institutional exits show up here before anywhere else. | +| 6 | **Latest 2 earnings-call transcripts, Q&A only** | 30 min | Fastest read on management credibility and on which questions are being refused. | +| 7 | **MD&A for the last 3 years, side by side** | 30 min | Promise-versus-delivery drift; the cheapest credibility test available. | +| 8 | **Latest credit rating rationale** | 15 min | Liquidity and covenant detail equity filings never show. | +| 9 | **Significant accounting policies + critical estimates note** | 30 min | Determines whether the earnings you are valuing are policy-driven. | +| 10 | **AGM voting results + remuneration resolutions** | 15 min | A quantified governance verdict from investors who have met management. | +| 11 | **Investor deck reconciled to audited numbers** | 30 min | Measures management's willingness to flatter. | +| 12 | **DRHP / S-1, exchange filing history, short-seller material, secretarial audit** | 2 hr+ | Deep-dive mode only, or when steps 1–11 raised a specific question. | + +**Screen mode** stops after step 5. **Standard mode** covers 1–9. **Deep dive** does all of it. If a document is unavailable, say so in the data-quality note rather than substituting inference — "FY23 annual report not retrievable; policy note not verified" is a legitimate output. + +--- + +## 2. The liability gradient: how much each document is worth + +Weight evidence by the legal consequence of it being wrong. This single heuristic resolves most conflicts between sources. + +| Tier | Documents | Assurance | +|---|---|---| +| **Highest** | Offer documents (DRHP/RHP, S-1, prospectus); audited financial statements and auditor's report | Signed by directors and auditors with civil and criminal liability; restatement adjustments disclosed | +| **High** | Notes to accounts, CARO, secretarial audit, statutory annexures; exchange material-event filings; scrutiniser's voting results | Statutory format, prescribed content, auditable | +| **Medium** | MD&A, Directors' Report, quarterly results (limited review, not full audit), credit rating rationales, proxy statements | Management-owned narrative or third-party opinion; not audited | +| **Low** | Investor presentations, press releases, earnings-call scripted remarks, guidance | Marketing documents, usually carrying an explicit safe-harbour disclaimer | +| **Contextual** | Media, short-seller reports, forums, sell-side notes | Hypothesis generators; every checkable claim must be verified against a higher tier | + +**Rule:** when two sources disagree, the higher tier wins and the discrepancy itself becomes a finding. A deck showing "net debt" materially below the balance sheet's borrowings is not a rounding issue — it is a definitional choice you must decompose (see §11). + +**Triangulation.** The most valuable technique in this file is checking the same fact across tiers. A large receivable should appear consistently in the balance sheet, the KAM, the MD&A explanation, the concall answer, and the rating agency's liquidity comment. Where those four disagree, you have found something. + +--- + +## 3. MD&A / Management Discussion and Analysis + +India: a standalone MD&A section in the annual report, mandated by SEBI LODR Schedule V. US: Item 7 of the 10-K, plus Item 1A Risk Factors and Item 3 Legal Proceedings. Foreign private issuers: Item 5 of the 20-F. + +**Read 3–5 consecutive years side by side, not one year alone.** A single MD&A is a press release. Five stacked MD&As are a track record. + +**Extract:** +- Management's own decomposition of growth into **volume versus realisation/price versus mix** — and check it against the segment note and any volume data disclosed elsewhere. +- Capacity, capacity utilisation, and planned capex with timing and funding source. +- Order book / backlog, book-to-bill, and stated execution period. +- Segment-wise outlook statements, verbatim, with the year attached. +- The risk-factor list, verbatim, year by year. +- Ratio disclosures (India requires key financial ratios with explanation of any change over 25%). + +**What a problem looks like:** +- **Recycled promises.** "Demand recovery expected in H2" appearing three years running. Build a two-column table: *what was promised in year N* | *what was delivered in year N+1*. Management that never acknowledges a miss is telling you how it will handle the next one. +- **Narrative-to-numbers divergence.** MD&A attributes growth to a premium segment; the segment note shows that segment shrinking. The segment note is the higher tier. +- **A risk silently dropped.** Compare risk lists year to year. A customer-concentration risk that disappears without the concentration disappearing is a disclosure decision, not a business change. +- **Boilerplate expansion.** MD&A that grows in length while shedding specifics (numbers replaced by adjectives) is a deliberate reduction in falsifiability. +- **US-specific:** watch for new risk factors added quietly (10-K Item 1A must flag material changes; 10-Q Item 1A carries updates), and for legal proceedings moving from Item 3 into a note or vice versa. + +**Why:** MD&A is the only management-owned, management-signed narrative sitting inside an audited document. It is unaudited, so it is where optimism lives — which makes the drift between it and the audited statements a direct measurement of that optimism. + +--- + +## 4. Notes to accounts: policies, estimates and changes therein + +Read the **significant accounting policies** note and the **critical estimates and judgements** note in full. These two notes determine what "profit" means for this company. Cross-read with `references/14-accounting-comparability.md` for Ind-AS/IFRS/GAAP differences. + +**Extract, and compare against 2–3 sector peers — never against an absolute standard:** + +| Policy area | What to extract | What a problem looks like | +|---|---|---| +| Revenue recognition | Point-in-time vs over-time; percentage-of-completion inputs; principal vs agent (gross vs net); variable consideration and rebate estimates | Over-time recognition with milestone estimates management controls; a switch from net to gross that inflates revenue with zero profit impact | +| Inventory | Valuation basis (FIFO/weighted average), overhead absorption, obsolescence provisioning policy | Provisioning rate falling while inventory days rise | +| Depreciation | Method and **useful lives per asset class**, residual values | Useful life extended (e.g. plant from 15 to 25 years) — flows straight to profit with no cash effect. Quantify the disclosed P&L impact. | +| Capitalisation | Borrowing costs capitalised, development costs capitalised, CWIP ageing | Capitalised development cost rising as a share of R&D; CWIP sitting >2–3 years without transfer to fixed assets | +| Expected credit loss (ECL) | Staging methodology, loss rates by bucket, forward-looking overlays | ECL coverage falling while receivable ageing worsens | +| Impairment | Goodwill/CGU allocation, discount rate, terminal growth, headroom and sensitivity disclosure | Terminal growth near or above the discount rate; headroom disclosed as "sufficient" without numbers; the same CGU tested with a friendlier rate each year | +| Leases | Discount rate on Ind-AS 116/IFRS 16 liabilities; short-term and low-value exemptions used | A high incremental borrowing rate that shrinks the recognised liability | +| Deferred tax | Recognition of DTA on carried-forward losses and the profitability forecast supporting it | A large DTA recognised by a loss-making entity — an assertion about future profits, booked as an asset today | + +*Indicative comparisons vary by market, cycle and period; peer and own-history comparison overrides any absolute band.* + +**Always do this:** list every change in policy, estimate or useful life, quantify the disclosed P&L impact, and **restate the affected years yourself** so the trend you analyse is on a consistent basis. If the impact is not quantified, say the trend is not comparable. + +**Why:** policy and estimate changes are the most common *legal* way to manufacture earnings. Because acceptable ranges are entirely sector-specific — a 25-year life is normal for a cement kiln and absurd for a server — only a peer-relative reading tells you whether the company sits at the aggressive end. + +--- + +## 5. Contingent liabilities and commitments + +Tabulate by category for five years: disputed direct tax, disputed indirect tax (GST/excise/service tax/customs), guarantees given (split: to subsidiaries, JVs, promoter/group entities, third parties), claims not acknowledged as debts, letters of credit and bills discounted, and pending litigation. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Contingent liabilities / net worth | Total contingent liabilities ÷ shareholders' equity | Typically <25–30% for a consumer or services business; 50%+ is normal for EPC/infra where performance guarantees are the business | Sizes the claim against equity if matters go against the company | +| Contingent liabilities / market cap | Same numerator ÷ market cap | Small enough that full crystallisation is survivable | Converts a footnote into a valuation input | +| Growth rate vs net worth growth | 5y CAGR of contingent liabilities vs 5y CAGR of net worth | Contingent growth ≤ net-worth growth | Faster growth means the off-balance-sheet claim is compounding against a shrinking cushion | +| Guarantees to group entities / net worth | Guarantees issued for subsidiaries, JVs and promoter entities ÷ net worth | As low as possible; any material figure needs an explanation | The classic channel for pushing leverage off the listed entity while keeping the risk | +| Capital commitments not provided for | "Estimated amount of contracts remaining to be executed on capital account" | Consistent with stated capex plans and funding capacity | Committed future cash outflow the balance sheet does not show | + +*Ranges are indicative only and vary by sector, market and cycle; the company's own history and its closest peers override any absolute band.* + +**What a problem looks like:** contingent liabilities exceeding net worth; a disputed tax demand that keeps growing with no resolution and no provision; guarantees to entities that are not consolidated subsidiaries; management's non-provisioning rationale being a single boilerplate line ("the company expects a favourable outcome") with no legal basis stated; the largest item also appearing as a KAM (that is the auditor agreeing with your concern). + +**Cross-check** the biggest items against the KAM section, the litigation schedule in any DRHP, and exchange filings on adverse orders. In India also check whether disputed amounts are at the Commissioner (Appeals), ITAT, High Court or Supreme Court stage — later stages mean longer duration but usually more crystallised risk. + +**Why:** these are off-balance-sheet claims that convert into real cash. A number that dwarfs net worth is a solvency question, not a footnote. + +--- + +## 6. Related-party transactions note + +List every related party and every transaction type: sales, purchases, job work, loans and advances given and taken, guarantees, rent, royalty and brand fees, technical/management fees, managerial remuneration, and **year-end outstanding balances** (which the transaction table alone will not show). + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| RPT sales share | Sales to related parties ÷ total revenue | Low and stable unless the group structure genuinely requires it | High or rising share means reported revenue is not arm's-length-validated | +| RPT purchase share | Purchases from related parties ÷ total purchases/COGS | Low and stable | The main route for margin to be routed out of the listed entity | +| Royalty / brand fee intensity | Royalty paid to promoter entity ÷ revenue, and its growth vs revenue growth | Flat as % of revenue if genuinely usage-based | A royalty growing faster than revenue is a rising tax on minority shareholders | +| Promoter remuneration | Total promoter-family pay ÷ PAT (India: statutory ceiling 11% of net profits, 5%/10% for individual MD/WTD under s.197) | Small share of PAT; falls when profits fall | Pay that rises while profit falls is the cleanest evidence of a board that does not constrain the promoter | +| Related-party receivables | Loans/advances/receivables due from related parties ÷ net worth, and ageing | Minimal, and recovered on stated terms | Interest-free advances that never return are, economically, a dividend paid only to the promoter | + +*Indicative only; sector and group structure change what is normal — peer and own-history comparison governs.* + +**What a problem looks like:** interest-free or below-market loans to related parties; advances perpetually rolled over rather than repaid; a related-party balance that grows every year regardless of business performance; sales to a related party at a margin implausibly different from third-party sales; a new related party appearing with a large transaction in its first year; "loans to bodies corporate" in the balance sheet that exceed the amounts disclosed as related-party in the note (check the s.186 disclosure in the Directors' Report against the RPT note). + +**Governance trail — verify each step, don't assume it:** audit-committee approval; where material, a shareholder special resolution with **related parties abstaining** (India: SEBI LODR Reg 23, materiality threshold ₹1,000 crore or 10% of consolidated turnover, whichever lower; half-yearly RPT disclosures to exchanges); then read the AGM voting results for institutional dissent on that specific resolution. US: related-party transactions appear in the DEF 14A under Item 404 of Reg S-K, and the audit committee charter governs approval. + +**Why:** RPTs are the primary mechanism of minority-value leakage in promoter- or founder-controlled companies. No accounting rule needs to be broken for profit to be routed out. + +--- + +## 7. Segment note + +Extract, for each reported segment across five years: segment revenue, inter-segment revenue, segment result/EBIT, segment assets, segment liabilities, capital employed, and capex. Then compute **segment margin and segment ROCE** yourself. + +**What to look for:** +- **One segment subsidising another.** A high-return cash cow funding a structurally loss-making segment that absorbs most of the capex. Consolidated margin hides this completely; segment ROCE reveals it. This is the single most common surprise in the entire annual report. +- **Segment redefinition.** Segments merged, renamed, split, or re-mapped between years. Ask what became invisible. A deteriorating business folded into a healthy one is the standard way it stops being discussed. When it happens, request or reconstruct the restated prior-year segment data; if it is not available, state that the segment trend is broken. +- **A swelling "unallocated" or "others" bucket.** Unallocated corporate expense and unallocable assets growing faster than the business are where inconvenient items go to be un-analysed. +- **Segment set versus management's own language.** If the concall discusses five businesses and the note reports two, management has chosen to report at a level that prevents you from checking the story. +- **Geography split** alongside the business split — matters for FX, tax rate and political risk. + +**Standards note:** Ind-AS 108 and IFRS 8 / ASC 280 all use the "management approach" — segments are what the chief operating decision maker reviews. That makes the segment note a *disclosure choice*, which is exactly why changes to it are informative. Also check the major-customer disclosure (required where a customer exceeds 10% of revenue). + +**Why:** consolidated economics are an average. Capital allocation happens at segment level, and so does destruction of value. + +--- + +## 8. The auditor's report — read this in full, every year + +This is the highest-yield section of the annual report per minute spent, and the one most often skipped. Read the **standalone and the consolidated audit reports separately — they can and do differ.** + +### 8.1 Opinion type + +Find it on the first page, in the paragraph headed "Opinion". + +| Opinion | Meaning | What you do | +|---|---|---| +| **Unmodified / unqualified ("clean")** | Statements give a true and fair view | Proceed — but a clean opinion is a floor, not a positive | +| **Qualified** ("except for…") | A specific, named item is wrong or unverifiable; the rest is fine | Stop and quantify. Read "Basis for Qualified Opinion", extract exactly what the auditor could not verify or disagreed with, take the quantified impact if given, and **restate the financials yourself** before computing any ratio | +| **Adverse** | The statements as a whole do not give a true and fair view | The accounts are not usable. Do not produce a valuation from them | +| **Disclaimer of opinion** | The auditor could not obtain sufficient evidence to form any opinion | Effectively no audit happened. Treat the financials as unaudited management assertions | + +Track opinion type across five years and flag **any new modification**. In India, SEBI additionally requires a **Statement on Impact of Audit Qualifications** filed with annual audited results — it forces management to quantify the qualification or explain why it cannot; read management's number and the auditor's comment on it side by side. + +### 8.2 Basis for opinion and going concern + +Beyond the modification paragraph, look for a **"Material Uncertainty Related to Going Concern"** section. This is not a qualification and is easy to miss, but it is the auditor stating that the entity's ability to continue operating depends on events outside its control (refinancing, a court outcome, promoter support). Extract the specific dependency and its date. In the US, going-concern doubt also drives disclosure under ASC 205-40 and is usually echoed in the risk factors. + +### 8.3 Key Audit Matters (KAM) / Critical Audit Matters (CAM) + +India and IFRS jurisdictions: KAMs under SA 701 / ISA 701, required for listed entities, typically 2–6 per report. US: **Critical Audit Matters** under PCAOB AS 3101, generally fewer (often 1–2) and narrower. + +For each KAM extract three things: **(a)** the balance or judgement involved, **(b)** why the auditor considered it high risk, **(c)** the specific procedures performed — and whether those procedures actually address the risk (a KAM on inventory existence "addressed" only by reviewing management's reconciliation is weaker assurance than physical attendance). + +Then **track KAMs across years.** A newly added or persistently repeated KAM is the auditor pointing at the line item most likely to be restated or impaired later. The highest-signal recurring KAMs: +- Recoverability of trade receivables / expected credit loss +- Revenue recognition on long-term or over-time contracts +- Impairment of goodwill or of investment in a named subsidiary +- Recoverability of loans and advances to related parties +- Capitalisation of development costs or CWIP +- Litigation and tax provisions +- Inventory existence and valuation, especially at third-party locations + +Map each KAM to the corresponding note and check the disclosed sensitivity of the assumptions. Compare the KAM list with the company's peers audited by the same firm — a KAM that everyone in the sector carries is a sector characteristic, not a company flag. This is the governing principle applied to auditor language. + +### 8.4 Emphasis of Matter (EOM) and Other Matter + +**Emphasis of Matter** is not a qualification — the auditor is drawing attention to something already disclosed. That framing makes it easy to skip, which is precisely why serious things live there: going-concern uncertainty, a court-approved **scheme of arrangement** whose accounting overrides normal standards (a recurring device for routing write-offs through reserves instead of the P&L), regulatory forbearance, a pending investigation, or the effects of a material subsequent event. Read every EOM and follow it to the underlying note. + +**Other Matter** is where the auditor discloses what they did *not* audit. In a consolidated report, quantify from this paragraph: +- % of consolidated **total assets, revenue and profit** audited by **other (component) auditors** +- % based on **unaudited, management-certified** subsidiary accounts + +If 40% of consolidated profit comes from components the principal auditor never touched — or from entities that are unaudited — the word "audited" on the consolidated statements carries far less assurance than it appears to. State this percentage explicitly in your data-quality note. + +### 8.5 CARO annexure — India-specific, read clause by clause + +The Companies (Auditor's Report) Order 2020 forces the auditor to answer specific factual questions. Read the annexure itself, not the summary; a "no exceptions noted" clause takes seconds, and the exceptions are where the information is. Highest-signal clauses: + +| Clause | What it answers | What a problem looks like | +|---|---|---| +| 3(i)(c) | Title deeds of immovable property held in the company's name | Properties on the balance sheet whose title is not with the company | +| 3(i)(d)–(e) | Revaluation of PPE; benami property proceedings | A revaluation gain propping up net worth; any benami proceeding at all | +| 3(ii)(a) | Physical verification of inventory and discrepancies | Discrepancies >10% in any class — the auditor must report them | +| **3(ii)(b)** | Where working-capital limits exceed ₹5 crore: whether **quarterly returns filed with banks agree with the books** | Divergence between what the banks were told and what was booked. Extremely high signal; banks see stock statements monthly | +| 3(iii) | Loans/advances/guarantees given: overdue amounts, terms, **renewals or fresh loans used to settle existing overdues (evergreening)**, loans repayable on demand with no stated terms | Evergreening; interest-free demand loans to group entities | +| 3(iv) | Compliance with s.185/186 on loans and investments | Non-compliance means the transaction itself was unlawful | +| 3(vii) | Statutory dues (GST, PF, ESI, TDS, income tax, customs) — undisputed dues **unpaid beyond six months**; and a list of disputed dues with forum | Unpaid statutory dues are hard evidence of a liquidity squeeze months before ratios show it — companies pay taxes last | +| **3(viii)** | Transactions **not recorded in the books but surrendered/disclosed as income in income-tax assessments** | Direct evidence of unrecorded transactions. Treat any positive answer as a full stop | +| 3(ix)(a)–(f) | Default in repayment to lenders (with amounts and dates); declared **wilful defaulter**; term loans applied for the stated purpose; **short-term funds used for long-term purposes**; funds raised on pledge of subsidiary shares; obligations of subsidiaries/JVs met from group funds | Short-term funds funding long-term assets is a classic pre-crisis asset-liability mismatch. Wilful-defaulter status is disqualifying | +| 3(x) | End-use of IPO/FPO/preferential allotment/private placement proceeds | Money raised for capex deployed into loans to group entities | +| **3(xi)** | Any **fraud** on or by the company; auditor's ADT-4 report to the Central Government; **whistle-blower complaints** considered | The single highest-signal paragraph in the annual report | +| 3(xiii) | Compliance with s.177/188 on related-party transactions and their disclosure | Procedural failure on RPTs, which is usually where substantive failure begins | +| 3(xiv) | Existence and adequacy of internal audit, and whether the auditor considered its reports | No internal audit function in a company of scale | +| 3(xv) | Non-cash transactions with directors (s.192) | Directors acquiring assets from the company without cash | +| 3(xvi) | NBFC/CIC registration where required; unregistered lending activity; number of CICs in the group | A group operating a finance business without registration, or an unexpectedly large CIC count signalling structural complexity | +| 3(xvii) | **Cash losses** in the current and immediately preceding financial year | Cash losses two years running | +| **3(xviii)** | **Resignation of the statutory auditors during the year** and whether the auditor considered the issues raised by the outgoing firm | See §8.7 — this is the strongest routinely available negative signal | +| 3(xix) | Whether, based on ratios, ageing and expected dates of realisation, any **material uncertainty exists about meeting liabilities falling due within one year** | An auditor-endorsed liquidity warning, stated in plain language | +| 3(xx) | Transfer of unspent CSR amounts | Small money, but non-compliance with an easy statutory obligation predicts non-compliance elsewhere | +| 3(xxi) | Qualifications or adverse remarks in the CARO reports of **companies included in the consolidation** | Problems at subsidiaries that the parent's own CARO would not show | + +**US analogue:** there is no CARO. The nearest equivalents are Item 9A (Controls and Procedures), Item 3 (Legal Proceedings), Item 4 (Mine Safety, where relevant), the ICFR attestation, and 8-K Items 4.01/4.02. The factual granularity of CARO simply does not exist in the US regime — which means for a US issuer you compensate with more weight on Item 9A, the auditor-change 8-Ks and the PCAOB inspection record. + +### 8.6 Internal financial controls (IFC/ICFR) + +**India:** a separate opinion under s.143(3)(i) on the adequacy and **operating effectiveness** of internal financial controls over financial reporting, appearing as an annexure to the audit report. +**US:** management's assessment under SOX 404(a) in Item 9A, plus the **auditor's attestation under 404(b) — required only for accelerated and large accelerated filers.** Non-accelerated filers, smaller reporting companies and recent IPOs (which get a transition exemption) have *no* auditor opinion on controls. Note that gap explicitly; it is common in small caps and in newly listed companies. Also read the SOX 302 certifications signed by the CEO and CFO. + +Determine whether the opinion is clean or identifies a **material weakness**, and read its description: revenue cut-off, vendor master data, inventory at third-party locations, segregation of duties, IT general controls and access rights, period-end financial reporting process. Distinguish a *material weakness* (reasonable possibility that a material misstatement would not be prevented or detected) from a *significant deficiency* (less severe). Then check whether a weakness reported last year was **remediated or repeated**. + +**Why:** a material weakness means the machinery producing the numbers cannot be relied upon to catch a material error. It undermines every ratio you compute downstream. A repeated, unremediated weakness signals either management indifference or deliberate tolerance. + +### 8.7 Auditor identity, tenure, rotation, fees and resignation + +| What to extract | Where | What a problem looks like | +|---|---|---| +| Audit firm name, appointment year, engagement partner | Audit report signature block; India: firm registration no. and partner membership no.; US: PCAOB Form AP names the engagement partner | A firm with no other listed clients of comparable size; the same small firm auditing multiple group entities | +| Rotation status | India: s.139(2) — individual auditor 5 years, firm 10 years (two terms of five), 5-year cooling off, applicable to listed and prescribed companies | Rotation due but a "new" firm staffed by the same partners, or an affiliate/network firm of the outgoing one | +| **Audit fee vs non-audit fee** | Notes to accounts ("Payment to auditors"); US: DEF 14A audit fee table (audit / audit-related / tax / all other) | Non-audit fees approaching or exceeding audit fees — a direct independence problem. India: s.144 prohibits specified non-audit services outright | +| Fee level vs size | Audit fee vs revenue and vs peer fees | An implausibly low fee for a complex multi-subsidiary group means the work was not done | +| **Auditor change or resignation** | India: exchange filing plus the resignation letter, which must state reasons (SEBI requires detailed reasons and the auditor must comment on unresolved issues); US: **8-K Item 4.01**, which must disclose disagreements and reportable events, with a Letter from the former accountant as Exhibit 16 | Any mid-term resignation. Cited reasons of "pre-occupation" or "other commitments" in a company under stress should be treated as a euphemism | +| **Non-reliance on previously issued financials** | US: **8-K Item 4.02**; India: restatement or revision under s.130/131 | The company formally telling you its old numbers were wrong | +| Late filing | US: NT 10-K / NT 10-Q; India: delayed results filing and exchange penalties | An issuer that cannot close its books on time | +| Auditor quality signals | PCAOB inspection reports for the firm; regulatory bans (India: NFRA/ICAI orders, SEBI debarments) | An auditor under regulatory action, or one whose inspection reports show high deficiency rates | + +**Why:** auditors rarely walk away from fees without cause, which makes mid-term resignation arguably the strongest single negative signal in public disclosure. A downgrade in auditor quality, or heavy non-audit fees, weakens the assurance behind every number you are about to use. Read this section together with §9 of `references/07-forensic-red-flags.md` on CFO and audit-committee turnover — auditor and CFO exits often cluster. + +--- + +## 9. Consolidated vs standalone, AOC-1 and the subsidiary map + +**Analyse consolidated as the primary basis** for business economics and valuation, then reconcile against standalone. Never mix them within one ratio, and always label which basis each figure came from. Aggregators and screeners routinely show one and label it the other. + +| Reconciliation | How to compute | Why it matters | +|---|---|---| +| Revenue, EBITDA, PAT gap | Consolidated minus standalone, per year | Locates where the business actually is — parent or subsidiaries | +| **Debt location** | Borrowings: consolidated vs standalone | Debt sitting in subsidiaries with profit in the parent looks healthy on one basis and stressed on the other | +| **Cash location** | Cash and investments: consolidated vs standalone; then by entity from AOC-1 | Cash in a 51%-owned or overseas subsidiary may be **trapped** — unavailable for dividends, buybacks or parent debt service without tax leakage or minority consent | +| Dividend capacity | Standalone free reserves and standalone cash flow vs dividend paid | A dividend not funded by parent-level cash flow is being funded by borrowing or by upstreaming that may not repeat | +| **PAT attributable to owners vs NCI** | Consolidated PAT split into owners' share and non-controlling interest | Headline consolidated PAT includes profit that is not yours. **Always value on the owners' share**, and use owners' equity for ROE | + +**The AOC-1 statement (India)** — the "salient features of the financial statement of subsidiaries/associates/joint ventures", filed as an annexure to the Board's Report. This is the single most underused page in an Indian annual report. It lists **every** subsidiary, associate and JV with shareholding %, turnover, PAT, net worth and investments. US equivalents: **Exhibit 21.1** (list of subsidiaries, but no financials), Reg S-X **Rule 4-08(g)** summarised financial information, and **Rule 3-09** separate audited financial statements for significant equity investees. + +**From the AOC-1, extract:** +- Every loss-making subsidiary, **and how many consecutive years** it has been loss-making. +- Whether the parent keeps funding those entities through equity infusion, loans, or guarantees (cross-check the RPT note and CARO 3(iii)). +- Subsidiaries with negative net worth — these are contingent claims on the parent regardless of legal separation. +- Entities with large turnover and negligible profit (possible pass-through or round-tripping structures), and entities with negligible turnover and large assets. +- Newly incorporated, newly acquired, **newly deconsolidated** or struck-off entities. A subsidiary that disappears between two annual reports needs an explanation; deconsolidation is a legitimate route to removing losses and debt from view. +- Overseas subsidiaries in jurisdictions with no operational rationale. + +**Consolidation method matters enormously:** +- **Subsidiaries** — line-by-line; their debt and losses are visible. +- **Associates and JVs** — equity method; only the net share of profit appears, and **their debt is entirely invisible on your balance sheet**. A group can carry very large leverage inside 49%-owned entities while showing modest consolidated debt. Read the Ind-AS 112 / IFRS 12 disclosure of interests in other entities, which gives summarised financials for material associates and JVs, and add back your share of their debt when assessing group leverage. +- **Structured entities / SPVs** — check the control assessment. Off-balance-sheet vehicles are disclosed under Ind-AS 112 / IFRS 12; read that note in any infrastructure, real estate or financial company. + +**Why:** consolidated shows the economic group; standalone shows what the listed entity actually controls and can pay dividends from. Both are true, and the difference between them is often the whole story. + +--- + +## 10. Earnings-call transcripts and management Q&A behaviour + +**Read the transcripts; do not listen to the calls.** Reading is faster, searchable, and lets you compare quarters side by side. Cover the last 8–12 quarters. Sources: company investor-relations page, exchange filings (India: transcripts must be filed within five working days under LODR), and 8-K Item 2.02 furnishings in the US. + +**Split every transcript into scripted opening remarks and Q&A.** The opening remarks are a press release read aloud — tier "low". The Q&A is unscripted and is where the evidence is. + +**Track across quarters:** + +| Signal | How to observe it | What it means | +|---|---|---| +| **Guidance vs delivery** | Log every numeric commitment (revenue growth, margin, capex, debt reduction, capacity commissioning date) with the quarter it was made, then mark it met/missed/quietly dropped | Produces an objective management-credibility score no financial statement can give you | +| **Miss acknowledgement** | When a target is missed, is it named and explained, or reframed as if it never existed? | Acknowledgement is the cheapest possible honesty test | +| **Numeric question → numeric answer?** | Count questions asking for a specific number (segment margin, receivable days, subsidiary loss, capex phasing, one-off quantum) and how many get a number | "We don't disclose that", "directionally positive", "let's take this offline" clustering on the same line item quarter after quarter is a map of the problem | +| **Analyst access** | Which analysts are called on; whether known sceptics stop appearing; whether the call is cut short with questions in the queue | Curated Q&A is a governance signal, not a scheduling accident | +| **Attribution pattern** | Are misses always external (weather, elections, GST, freight, FX, "channel destocking") while beats are always management execution? | Consistent externalisation over many quarters is a stable trait, not a run of bad luck | +| **Who speaks** | Is the CFO on the call? Does a new CFO answer confidently on prior periods? | A CFO absent from calls, or unable to answer on their own numbers, is a real flag | +| **Format degradation** | Calls discontinued, moved to written-questions-only, pre-submitted questions, or transcripts stopped being filed | Reduction in accountability channels almost always precedes bad news | +| **Language recycling** | Diff the opening remarks across quarters | Identical paragraphs quarter after quarter mean nothing is being said | + +**Maintain a running list of unanswered questions** and check whether they are ever answered. Also note what analysts stop asking about — a question that gets refused three times stops being asked, and the silence looks like resolution. + +**India note:** many small- and mid-cap companies hold no calls at all. Absence of a concall is itself a data point about investor engagement, and it means you must lean harder on the filings. + +--- + +## 11. Investor presentations vs audited filings + +Take every headline metric in the deck — adjusted EBITDA, cash EBITDA, pre-exceptional PAT, "normalised" margin, net debt, order book, ARR, EBITDA pre-Ind-AS-116 — and reconcile it line by line to the audited statements. + +**Interrogate every add-back:** +- Is it genuinely non-recurring? An "exceptional item" that appears in four of five years is an operating cost. Sum five years of exceptionals and compare to five years of reported PAT — the ratio is often startling. +- Restructuring, impairment, legal settlements and inventory write-downs are the usual repeat offenders. +- Share-based compensation added back is a real cost to you as a shareholder; see `references/03-earnings-quality.md`. +- Pre-IFRS-16/Ind-AS-116 EBITDA is legitimate for comparability, but only if lease payments are then deducted somewhere. + +**Interrogate net debt specifically.** Check whether the deck's net debt excludes: acceptances / buyer's credit / channel financing, bills discounted with recourse, factoring, lease liabilities, preference shares and other compound instruments, deferred acquisition consideration, and cash that is restricted or held in subsidiaries. Reconcile to the balance sheet borrowings line and state the gap. See `references/06-valuation.md` for the full EV bridge. + +**Interrogate unaudited operating metrics.** Order book, capacity, "addressable market", store count, ARR, GMV, and customer counts appear nowhere in the audited statements and are never verified by anyone. Ask whether the metric definition has changed (an ARR definition that quietly starts including one-time revenue), and whether an order book converts into revenue at the rate implied. + +**What a problem looks like:** the gap between presented and audited figures widening year over year; a new adjusted metric introduced in the exact year the old one turned down; a metric definition changed without restating prior periods; charts with no y-axis; growth shown only in indexed form. + +**Why:** presentations carry far weaker liability than audited filings. The size and direction of the gap is a direct measure of management's willingness to flatter, and non-GAAP metrics drifting further from GAAP each year is among the most reliable governance warning signs available. + +--- + +## 12. DRHP / RHP / S-1 and offer documents + +The offer document is the most legally exhaustive disclosure a company ever makes. It remains valuable long after listing — for an already-listed company, the old DRHP is still the best single source of pre-listing history. + +**Extract:** +- **Litigation and regulatory-action history** of the company, subsidiaries, group companies, promoters and directors — criminal, tax, statutory and civil, with amounts. Nothing later in the company's life re-discloses this at the same granularity. +- **Objects of the issue**: how much is fresh capital going into the business versus **offer for sale** enriching selling shareholders. Also check whether stated objects include repayment of debt or "general corporate purposes" (which should be capped). +- **Pre-IPO placements and the price paid by earlier investors** versus the IPO price. A steep step-up in the months before listing tells you what sophisticated buyers thought the business was worth very recently. +- **Restated financials and the restatement adjustments**, with reasons. This shows how the pre-IPO accounts were originally kept — a long list of restatement adjustments is a statement about historical accounting discipline. +- **Risk factors**, written by lawyers under liability and far more candid than any subsequent annual report. Many risks disclosed in a DRHP are never mentioned again. +- **Promoter group entity list** — the definitive map for later RPT work. +- **Lock-in expiry dates** (India: promoter and anchor-investor lock-ins) or US lock-up expiry, which tell you about future supply and insider intent. +- Related-party transactions for the pre-IPO period, and any pre-IPO restructuring, transfer of assets or business between promoter entities and the issuer. + +**US equivalents:** S-1 (domestic IPO), F-1 (foreign issuer), 424B prospectus, and for SPAC de-listings the S-4/proxy. Note that projections appear in SPAC merger documents and essentially nowhere else in US filings — and are almost never met. + +**Why:** it is the one document written under maximum liability with maximum detail, and its restatement adjustments plus offer structure reveal both how the accounts were kept and what insiders intend to do with their shares. + +--- + +## 13. Credit rating rationales and rating actions + +Pull the **full rationale document**, not just the symbol, from **every** agency covering the company, plus the complete rating history. India: CRISIL, ICRA, CARE, India Ratings, Acuité, Brickwork — all publish detailed public rationales. US/global: Moody's, S&P, Fitch — press releases and credit opinions, less granular publicly but still valuable; supplement with bond indentures and covenant disclosures. + +**Extract:** +- **Key rating strengths and weaknesses** in the agency's own words. +- **Liquidity assessment** (India: agencies grade it explicitly — Superior / Strong / Adequate / Stretched / Poor). This is the single most useful line, because balance-sheet ratios do not show undrawn lines, cash-flow timing or repayment bunching. +- **Rating sensitivities** — the explicit metric thresholds that would trigger an upgrade or downgrade. These are effectively externally-set covenants on your thesis; check your own computed numbers against them. +- The **list of rated facilities** with amounts, which reveals the bank-debt structure (fund-based vs non-fund-based limits, working-capital limits, term loans) far better than the balance sheet. +- Utilisation of working-capital limits over the past 12 months — agencies frequently disclose average and peak utilisation, and sustained near-100% utilisation is a liquidity warning. + +**Rating actions to treat as events:** +- Outlook change (Stable → Negative) and placement on **Rating Watch**. +- Any downgrade, and especially a multi-notch downgrade. +- **Migration to "Issuer Not Cooperating" (INC)** — India-specific and widely ignored. The company has simply stopped supplying information to its own rating agency. Read it as a refusal to be examined. +- A rating withdrawal at the company's request. +- Any **default or "D" rating on any instrument of any group entity**, including unlisted ones. Contagion within promoter groups is real, and lenders act on group exposure. +- India: rating actions are themselves disclosable to exchanges under LODR Reg 30, so the exchange filing history gives you the timeline. + +**Why:** rating agencies see bank facility details, covenant terms, month-by-month utilisation and management interactions that equity investors never get. Their liquidity paragraph routinely identifies stress one to four quarters before the equity market notices. + +--- + +## 14. Exchange filings and continuous disclosure + +Scan the company's **entire filing history**, not just results. This is where governance events surface first. + +**India (NSE/BSE, SEBI LODR):** +- **Reg 30 material events** — board and KMP changes, plant shutdowns, contract wins/losses, litigation and regulatory orders, tax search/survey, acquisitions and disposals, fund-raising, default on payment obligations. Schedule III Para A events are automatically material; Para B events apply a quantitative threshold (broadly 2% of turnover, 2% of net worth, or 5% of average PAT of the last three years). +- **Reg 30(11) rumour verification** — top-listed companies must confirm or deny material market rumours; the response is informative. +- **Reg 31 pledge/encumbrance disclosures** and SAST Reg 29 acquisition/disposal disclosures. +- **PIT Reg 7 insider-trading disclosures** — promoter, director and KMP trades above ₹10 lakh in a quarter. +- **Reg 23 half-yearly RPT disclosures** in the prescribed format — often more granular than the annual note. +- **Reg 32 statement of deviation** in use of issue proceeds, and **Reg 33** quarterly results (limited review, not audited — check the review report for qualifications too). +- Scheme-of-arrangement filings, NCLT applications, IBC/insolvency petitions filed by or against the company or its subsidiaries, and any SEBI, RBI, CCI, NCLT, ED or tax-authority order. + +**US (EDGAR):** +- **8-K** by item number — 1.01 material agreement, 1.03 bankruptcy, 2.02 results, 2.04 triggering of a direct financial obligation (covenant breach/acceleration), **4.01 auditor change**, **4.02 non-reliance on prior financials**, 5.02 departure/appointment of officers and directors, 5.07 shareholder-vote results. +- 10-Q, 10-K, DEF 14A, S-8 (equity plan registrations — a dilution signal), Form 144 (proposed insider sales), NT 10-K/NT 10-Q (late filing), and comment-letter correspondence (UPLOAD/CORRESP), which shows exactly what the SEC challenged in the accounting and how the company responded. Comment letters are underused and often excellent. + +**Patterns that matter more than any single filing:** +- **Serial resignation of CFOs, company secretaries, or independent directors.** Read every resignation letter; independent directors resigning citing "personal reasons" shortly after a contentious board matter is a well-worn euphemism. This pattern reliably *precedes* trouble rather than following it. +- Insider transactions: what the people with full information do with their own money. +- **Filing timing.** Material bad news released late on a Friday, immediately before a long holiday, or minutes before/after market close is a deliberate attention-management choice. Log the timestamps. +- Repeated delays in filing results, or auditors' limited-review reports with qualifications. + +--- + +## 15. Shareholding pattern and promoter pledge + +**India:** quarterly shareholding pattern under LODR Reg 31. Track 12+ quarters. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Promoter holding trend | Promoter + promoter group % of total equity, quarter by quarter | Stable or rising; India requires ≥25% public float | A steady decline needs an explanation; "reclassification" of a promoter to public is a disclosed exit route worth checking | +| **Pledged shares** | Shares pledged/encumbered ÷ promoter holding, **and** ÷ total equity | Zero is the only comfortable level; >25% of promoter holding warrants a specific explanation; >50% is a live risk | A price fall triggers margin calls, forced sale and potentially loss of control — converting a valuation problem into a solvency and control crisis | +| Institutional holding | FII/FPI and DII/mutual-fund %, and the named funds | — | Quiet exits by long-standing institutional holders, especially domestic funds with local access, deserve investigation | +| Retail shareholder count | Number of small individual shareholders (disclosed in India) | — | A sudden surge in retail holders alongside institutional exit is a distribution pattern | +| Concentrated public holders | Non-institutional holders above 1%, named | — | Unknown FPIs or entities appearing across several promoter-linked companies suggest undisclosed concert | + +*Indicative only; norms vary by market and ownership structure — a widely held US company has no promoter concept at all.* + +**Also check:** invocation of pledged shares (disclosed separately); creeping acquisition under SAST; promoter share transfers to family trusts or holdcos; and whether the pledge is against borrowing by the *listed company* or by *promoter entities* — the latter means the listed company's shares are collateral for debt you cannot see and do not benefit from. + +**US/global equivalents:** no promoter concept. Instead: SC 13D/13G (5%+ holders, with 13D signalling activist intent), Form 4 (insider transactions within two business days), 13F (institutional holdings, quarterly, 45-day lag), the DEF 14A beneficial-ownership table, dual-class structures and the proxy's disclosure of **pledging of company stock by executives** (many boards prohibit it — check the policy). + +--- + +## 16. Proxy / AGM materials and voting results + +**India:** the AGM/EGM notice with explanatory statements under s.102, plus the **scrutiniser's report on voting results** filed with the exchanges within two working days. +**US:** the DEF 14A, plus **8-K Item 5.07** for the voting outcome. + +**Read each resolution and its explanatory statement for:** +- **Managerial remuneration** — total promoter/founder-family pay against PAT, against peer CEO pay, and against its own trajectory. Check the fixed/variable split and what the variable is actually linked to. India: s.197 caps (11% of net profits overall; 5% for one MD/WTD, 10% for all together) and the requirement for a special resolution to exceed them, or in the case of inadequate profits, Schedule V compliance. US: the Compensation Discussion and Analysis, CEO pay ratio, and the pay-versus-performance table (which does the comparison for you). +- **Director appointments and re-appointments** — genuine independence (prior employment, business relationships, tenure), number of other board seats (over-boarding), attendance record, and any regulatory disqualification. +- **Related-party approvals** — see §6; confirm interested parties abstained. +- **Share issuance, preferential allotment, warrants and ESOP authorisations** — size the potential dilution and the exercise price. Warrants issued to promoters at a price near a cyclical low are a value transfer. +- **Auditor appointment/re-appointment** and the proposed fee. + +**Then read the voting results themselves.** This is the part most analysts skip and it is quantified, public and unambiguous. + +- Compute, per resolution, the **% of institutional votes cast against** and the **% of non-promoter public votes cast against**. +- A resolution that passes only on promoter votes while 60–90% of institutional votes oppose it is an explicit no-confidence vote from investors who have met management. Treat it as a governance finding of the same weight as an accounting flag. +- Rising against-votes across successive years on the same theme (remuneration, a specific director, RPTs) shows a board that is not responding to shareholders. +- Read proxy advisory recommendations where available (India: IiAS, SES, InGovern; US: ISS, Glass Lewis) — and read the company's rebuttal if it issued one. +- US: say-on-pay support below ~70% is conventionally treated as a rebuke requiring board response. + +--- + +## 17. Short-seller reports, forensic notes and adverse media + +Search for any short-seller report, forensic accounting note, regulator order, or investigative journalism on the company **or any group entity**. + +**How to read one properly:** +1. **Read the report and the company's rebuttal side by side, allegation by allegation.** Build a three-column table: allegation | company's response | your verification. This is the whole method. +2. **Judge the rebuttal by what it engages with.** Specific allegations answered with documents, bank confirmations, registry records and named counterparties are genuine responses. Allegations answered with adjectives ("baseless", "malicious"), attacks on the author's motives, nationalist framing, or a defamation suit are non-responses — and a systematic pattern of non-response across allegations is itself high-grade evidence. +3. **Verify the checkable claims yourself** against primary sources: registry filings for the alleged shell counterparties (India: MCA21; UK: Companies House; equivalents elsewhere), subsidiary statutory accounts, customs and trade data, land and property records, litigation dockets, employee counts, satellite imagery for claimed facilities. A report's value is concentrated in the claims you can independently confirm. +4. **Note the author's disclosed position and incentive.** A short seller profits from the price falling and is selecting evidence accordingly. That does not make the evidence false; it means treat the report as a **hypothesis generator, never a conclusion**. +5. **Separate the allegations by type.** Accounting-manipulation claims can often be checked from filings. Claims about undisclosed related parties, circular revenue or shell counterparties require outside records. Claims about intent or future regulatory action cannot be verified at all — discount them. + +**Why:** these reports concentrate months of forensic work into one document and frequently surface structures — undisclosed related parties, circular transactions, shell counterparties, inflated asset claims — that filings alone would take years to find. See §13 of `references/07-forensic-red-flags.md` for the independent-verification techniques. + +--- + +## 18. Secretarial audit and Directors' Report annexures + +Largely India-specific, and consistently under-read. + +- **Secretarial audit report (Form MR-3)**, mandatory for listed and prescribed companies under s.204, plus the **Annual Secretarial Compliance Report** under LODR Reg 24A. Read the qualifications and observations. These reveal statutory non-compliance — late filings, invalid appointments, procedural failures on RPTs or on board/committee composition — that never touches the financial statements. Also check whether material unlisted subsidiaries got their own secretarial audit, which is required. +- **Corporate governance report**: board composition and independent-director count, whether the chair is independent or is the promoter, board and audit-committee meeting frequency and **individual attendance**, committee composition, and the number of board meetings held at short notice. An audit committee that meets four times a year for an hour is not overseeing anything. +- **Independent director resignations** — read the letter and the stated reasons (India requires the reason to be disclosed and requires the director to confirm there are no other material reasons). +- **ESOP disclosures** — grants, exercises, outstanding options, exercise prices and potential dilution. +- **s.186 loans, guarantees and investments** disclosure — cross-check against the RPT note. +- **CSR** spend vs obligation and unspent transfers (small money, but a clean compliance signal). +- **BRSR** (Business Responsibility and Sustainability Report) for the top listed companies, with BRSR Core assured — useful for regulatory, environmental and litigation exposure; treat unassured sections as management narrative. +- **Cost audit report** where applicable (regulated and manufacturing sectors) — segment-level cost data unavailable anywhere else. + +**US analogues:** corporate governance content sits in the DEF 14A (board independence, committee composition, attendance, related-party policy), governance guidelines and committee charters on the IR site, and NYSE/Nasdaq listing-standard compliance disclosures. + +--- + +## 19. Sector translation: which documents replace the standard set + +The governing principle applies to documents, not just ratios. For several sectors, the documents above are secondary and the real disclosure lives elsewhere. Read the sector playbook before deciding what to prioritise. + +| Sector | Read instead of / in addition to the standard set | What to extract | +|---|---|---| +| **Banks** | Basel **Pillar 3 disclosures**; notes on asset quality; RBI risk-assessment **divergence disclosure**; restructuring and resolution-framework notes; annual report "Notes on accounts" schedules | GNPA/NNPA reconciliation and slippages, provision coverage, sector and borrower concentration, restructured and SMA book, divergence between RBI-assessed and reported NPAs (an auditor-adjacent disclosure with no equivalent elsewhere), capital adequacy and its components | +| **NBFCs / HFCs** | ALM (asset-liability maturity) statement, borrowing mix disclosure, RBI scale-based-regulation disclosures, securitisation/direct-assignment notes, co-lending arrangements | Maturity mismatch by bucket, dependence on short-term funding, off-book AUM, credit-enhancement obligations retained on securitised pools | +| **Insurers** | Public disclosures forms (India: L-series for life, NL-series for general); **embedded value report and its actuarial assumptions**; appointed actuary's certificate; solvency statement | EV movement analysis, VNB margin and its assumption sensitivity, persistency, solvency ratio, reserving assumptions. Standard ratios like EBITDA and ROCE are undefined here | +| **REITs / InvITs** | Independent **valuation report** (half-yearly in India), distribution statement, manager fee structure, related-party leases | Valuer identity and independence, cap rate assumptions, NAV movement, NDCF computation, manager fees as % of AUM, sponsor-related leases | +| **Miners / E&P** | **Reserve and resource statements** under JORC / NI 43-101 / SEC S-K 1300 / SPE-PRMS; technical reports; independent qualified person's sign-off | Proven vs probable split, reserve life, grade trend, the commodity price deck used, who certified it and their independence. Reserves are the balance sheet for these companies and are *not* audited by the financial auditor | +| **Utilities / regulated** | Tariff orders, regulatory-asset notes, PPA terms, regulator filings | Regulated return allowed vs earned, regulatory assets/deferrals recoverable, true-up timing | +| **Pharma** | Regulatory inspection outcomes (US FDA Form 483s, warning letters, import alerts), ANDA/patent litigation dockets | Facility-level compliance status, remediation timelines, exclusivity expiries | + +For all of these, standard EBITDA/ROCE/working-capital analysis is either undefined or misleading. Read the matching `references/sectors/*.md` before computing anything. + +--- + +## 20. Archive and data-provenance hygiene + +**Build your own archive.** Companies remove old documents from their websites, and they do it most often when the old documents are inconvenient. Download and retain: 7–10 years of annual reports, all quarterly results and transcripts, the DRHP, credit rating rationales, investor decks and material exchange filings. India: BSE/NSE announcement archives and SEBI's filings retain much of it independently; US: EDGAR retains everything permanently and is the canonical source. + +**Compute key figures yourself from primary filings.** Aggregators are useful for screening and unreliable for conclusions. +- Verify at least the top five metrics (revenue, EBITDA, PAT, total debt, cash) against the source document before building any thesis on them. +- Establish whether the aggregator is showing **standalone or consolidated** — many silently mix the two across years or across companies within the same peer table. +- Establish how it treats **exceptional items, lease accounting (Ind-AS 116/IFRS 16), and minority interest**. Different treatments make peer comparisons meaningless. +- Check its **fiscal-year alignment** convention when comparing companies with different year ends. + +**Reconcile restated comparatives.** Take last year's annual report and this year's, and compare the prior-year column in each. Silent restatements — prior-period figures quietly changed with no note explaining why — are a specific, detectable form of manipulation, and only a self-maintained multi-year archive will reveal them. Legitimate restatements (a genuine error corrected under Ind-AS 8 / IAS 8, a discontinued operation reclassified, a segment redefinition) carry a note explaining the change; the absence of that note is the flag. + +**Record provenance for every number you use**: document, page or note number, period, consolidated/standalone, currency and units, and the date you retrieved it. This feeds directly into the data-quality note required by the output contract in `SKILL.md`. + +--- + +## Checklist + +- [ ] **Entire annual report walked section by section against the §0 contents map**; every section either mined for material content or recorded as "read — nothing material" — none left unopened. +- [ ] Auditor's report read in full for **both standalone and consolidated**; opinion type recorded for 5 years. +- [ ] Any modification quantified and the financials restated before any ratio was computed. +- [ ] Going-concern paragraph checked; every KAM/CAM extracted, mapped to its note, and tracked across years. +- [ ] Emphasis of Matter and Other Matter read; **% of consolidated assets/revenue/profit not audited by the principal auditor, or unaudited, quantified**. +- [ ] India: CARO annexure read clause by clause — statutory dues, defaults, short-term funds for long-term use, evergreening, bank-return divergence, fraud reporting, auditor resignation, one-year liquidity uncertainty. +- [ ] IFC/ICFR opinion checked for material weakness and for repeat weaknesses; US: noted whether a 404(b) auditor attestation exists at all. +- [ ] Auditor tenure, rotation, audit vs non-audit fees checked; any resignation letter or 8-K Item 4.01/4.02 read. +- [ ] MD&A read for 3–5 years side by side; promise-vs-delivery table built; risk-factor changes diffed. +- [ ] Accounting policies and critical estimates read; every change quantified and peer-compared; affected years restated. +- [ ] Contingent liabilities tabulated 5 years, expressed as % of net worth and market cap; group guarantees isolated; capital commitments sized. +- [ ] RPT note fully extracted, including **year-end balances**; RPT sales/purchase shares computed; approvals and voting dissent verified. +- [ ] Segment revenue, EBIT, capital employed and ROCE computed per segment for 5 years; any segment redefinition explained. +- [ ] Consolidated vs standalone reconciled for revenue, EBITDA, PAT, **debt and cash**; trapped cash identified; NCI stripped out before valuation. +- [ ] AOC-1 / Exhibit 21.1 read; loss-making, negative-net-worth, newly acquired and newly deconsolidated entities listed; equity-method associate debt added back to group leverage. +- [ ] 8–12 transcripts read; guidance-vs-delivery log built; refused questions and analyst-access patterns recorded. +- [ ] Investor-deck metrics reconciled to audited figures; every add-back tested for recurrence; net-debt definition decomposed. +- [ ] DRHP/S-1 checked for litigation history, OFS share, pre-IPO pricing, restatement adjustments and lock-in expiry. +- [ ] Full rating rationales pulled from all agencies; liquidity grade, rating sensitivities and any INC/watch/downgrade recorded. +- [ ] Exchange filing history scanned for KMP resignations, insider trades, pledge changes, regulatory orders and Friday-evening disclosures. +- [ ] Shareholding pattern tracked 12+ quarters; pledge as % of promoter holding **and** of total equity computed. +- [ ] AGM notice and **scrutiniser's voting results** read; institutional against-votes per resolution recorded. +- [ ] Short-seller/forensic material located; allegations, rebuttal and your own verification tabulated. +- [ ] Secretarial audit (MR-3) qualifications, board composition and attendance checked. +- [ ] Sector-specific primary documents (Pillar 3, EV report, valuation report, reserve statement) read where the standard set does not apply. +- [ ] Top five metrics verified against primary filings; prior-year comparatives reconciled across two annual reports for silent restatements; provenance recorded for every figure used. diff --git a/finance/skills/stock-analysis/references/16-market-mechanics-and-tax.md b/finance/skills/stock-analysis/references/16-market-mechanics-and-tax.md new file mode 100644 index 00000000..ed190cf8 --- /dev/null +++ b/finance/skills/stock-analysis/references/16-market-mechanics-and-tax.md @@ -0,0 +1,438 @@ +# Market Mechanics, Corporate Actions and Taxation + +Use this when: you have a thesis you like and need to know whether it can actually be owned, exited and kept after tax — run the tradeability gate early (before deep fundamental work on any smallcap), and the supply-calendar and tax layers before sizing or writing the recommendation. + +Everything upstream in this skill estimates *intrinsic* value. This file governs *realised* return, which differs from intrinsic value by three things the financials never show: whether the market lets you transact at the price on the screen, whether the share count you divided by is the share count you will end up with, and how much of the gain the tax authority and the transaction stack keep. A correct 30% IRR thesis on a stock in a weekly call auction with a 40% lock-in expiry due and a 20% short-term tax rate is not a 30% IRR. The governing rule applies here as everywhere: none of these numbers means anything absolutely — impact cost, delivery percentage, float and dilution are only interpretable against the stock's sector, size bucket and own history, and for banks, REITs/InvITs and PSUs the dilution and distribution logic is structurally different, not just quantitatively different (Section 23). + +**Standing warning on tax figures.** Every rate, threshold, holding period and form number in this file is *indicative and dated*. Tax law changes mid-year, differs by jurisdiction, and depends on the holder's residency, entity type and account wrapper. India changed capital-gains rates and buyback taxation within a single recent financial year. Never quote a rate from memory into a report. Verify against the current Finance Act / IRS publication / exchange circular, state the date of the rule you applied, and split any calculation that straddles a rule change by transaction date. Where you could not verify, say "rate to be confirmed" rather than filling in a plausible number. + +## Contents + +- [0. The method: gate, calendar, net-of-cost](#0-the-method-gate-calendar-net-of-cost) +- [1. Exchange surveillance status (India: ASM / GSM / ESM)](#1-exchange-surveillance-status-india-asm--gsm--esm) +- [2. Circuit limits, price bands and trade-to-trade](#2-circuit-limits-price-bands-and-trade-to-trade) +- [3. Delivery volume vs traded volume (India)](#3-delivery-volume-vs-traded-volume-india) +- [4. Liquidity, impact cost and realistic exit size](#4-liquidity-impact-cost-and-realistic-exit-size) +- [5. Halts, suspensions and market-wide circuit breakers](#5-halts-suspensions-and-market-wide-circuit-breakers) +- [6. Free float and float-adjusted supply](#6-free-float-and-float-adjusted-supply) +- [7. The dilution map: build it once, in shares](#7-the-dilution-map-build-it-once-in-shares) +- [8. QIP, preferential allotment and warrants](#8-qip-preferential-allotment-and-warrants) +- [9. Convertibles and the honest diluted share count](#9-convertibles-and-the-honest-diluted-share-count) +- [10. Rights issues](#10-rights-issues) +- [11. Bonus, splits and consolidations](#11-bonus-splits-and-consolidations) +- [12. Buybacks: tender vs open market](#12-buybacks-tender-vs-open-market) +- [13. Lock-in expiries and pre-IPO supply cliffs](#13-lock-in-expiries-and-pre-ipo-supply-cliffs) +- [14. Index inclusion, exclusion and rebalance flows](#14-index-inclusion-exclusion-and-rebalance-flows) +- [15. Open offers, delisting and schemes of arrangement](#15-open-offers-delisting-and-schemes-of-arrangement) +- [16. Capital gains: holding period is a position decision](#16-capital-gains-holding-period-is-a-position-decision) +- [17. Dividend taxation and withholding](#17-dividend-taxation-and-withholding) +- [18. The transaction cost stack: STT, stamp duty, round trip](#18-the-transaction-cost-stack-stt-stamp-duty-round-trip) +- [19. Cross-border: withholding, treaty relief, PFIC, estate tax](#19-cross-border-withholding-treaty-relief-pfic-estate-tax) +- [20. Loss set-off, carry-forward and harvesting](#20-loss-set-off-carry-forward-and-harvesting) +- [21. Custody, demat and account hygiene](#21-custody-demat-and-account-hygiene) +- [22. Settlement, record dates and response obligations](#22-settlement-record-dates-and-response-obligations) +- [23. Sector translation: where this lens inverts](#23-sector-translation-where-this-lens-inverts) +- [Checklist](#checklist) + +--- + +## 0. The method: gate, calendar, net-of-cost + +Three passes, in this order. The first is cheap and kills candidates before you waste analysis on them. + +**Pass 1 — Tradeability gate (10 minutes, do it first for any sub-largecap).** Surveillance status, price band, median daily traded value, impact cost, delivery percentage, free float. If the stock is in a punitive surveillance stage, or your intended position exceeds what the tape can absorb in a reasonable number of days, stop. No fundamental edge survives an inability to exit. Record the gate result even when it passes — it sets the maximum position size for everything downstream. + +**Pass 2 — Supply calendar.** One table, forward 24 months, in shares and in days of average daily traded value (ADV): every lock-in expiry, warrant exercise window, convertible conversion date, unused enabling resolution, ESOP vesting cliff, promoter/PSU divestment intent and index review date. Dilution and supply are the most *predictable* source of drawdown in the whole analysis and the most routinely ignored. + +**Pass 3 — Net-of-cost return.** Take your target return and subtract: round-trip transaction stack × expected turnover, dividend tax at the holder's marginal rate, and capital-gains tax at the rate implied by your stated holding period. Report gross and net. If the thesis only works gross, it does not work. + +Write the output of all three into the report as three lines, not three pages: *"Position capped at X on liquidity; Y% of shares released from lock-in in month Z equal to N days of ADV; gross 18% IRR becomes ~14% net at a 3-year hold."* + +--- + +## 1. Exchange surveillance status (India: ASM / GSM / ESM) + +**India-specific.** Before anything else on an Indian smallcap or microcap, pull the current NSE/BSE lists: **ASM** (Additional Surveillance Measure — short-term and long-term stages), **GSM** (Graded Surveillance Measure, Stages I–VI), and **ESM** (Enhanced Surveillance Measure, aimed at SME and microcap counters). These are published as exchange files and revised on a fixed review cycle. + +Record four things: the stage, the date applied, the consequences, and the next review date on which it can escalate or exit. + +Typical consequences by escalation (verify the current framework — stages and their exact effects have been revised repeatedly): + +| Escalation | Typical consequence | What it does to you | +|---|---|---| +| ASM short-term | 50–100% margin, sometimes reduced price band | Leverage gone; position cost rises | +| Trade-for-trade (T2T / BE series) | 100% delivery, no intraday netting | Cannot scale in and out; every trade settles | +| Price band cut to 5% or 2% | Daily move capped | A −50% repricing takes many sessions you cannot sell into | +| Periodic call auction | Trading collapses to one price-discovery window (weekly in the worst stages) | Effectively no continuous market; exit at whatever single price clears | +| No pledging, no derivatives | Collateral value zero; no hedge or short route | Cannot hedge the position you are stuck in | + +**Why it matters.** Surveillance placement is the single biggest silent liquidity killer, and almost no screener surfaces it — so a "cheap" screen hit can be untradeable. It is also an exchange-generated signal that price and volume behaviour looks abnormal relative to fundamentals, which historically precedes regulatory action or collapse more often than it precedes recovery. A GSM Stage IV name is not a cheap stock; it is a stock you may be unable to sell for months. + +**US/global analogue.** There is no direct equivalent, but check: SEC trading suspensions, "caveat emptor" flags on OTC Markets, exchange deficiency notices (Nasdaq/NYSE listing-standard non-compliance letters, minimum bid price and market-value tests), and Reg SHO threshold-list membership. For any OTC/pink-sheet name, treat absence of current information tier as an automatic fail. + +--- + +## 2. Circuit limits, price bands and trade-to-trade + +Identify the applicable band and the last 3–6 months of circuit history. + +- **India:** daily bands of 20% / 10% / 5% / 2% on cash-segment stocks. Stocks in the F&O segment have no fixed daily band but operate under a dynamic price band (commonly 10%) that flexes in steps after a cooling-off period. T2T/BE-series stocks prohibit intraday. +- **US:** Limit Up–Limit Down (LULD) bands trigger 5-minute trading pauses rather than day-long locks; the Short Sale Restriction (alternative uptick rule) engages after a 10% intraday decline and persists into the next session. + +Distinguish two very different events: a circuit **touched with volume** (genuine repricing, exit possible) versus a **locked circuit with no counterparty** (no exit at all). Count locked days separately. + +**Why it matters.** Circuit structure, not historical volatility, defines your realistic worst case. A 5% lower circuit with no bids means a −50% move takes roughly fourteen sessions during which you cannot sell a single share — the drawdown is not a paper drawdown, it is a trap. Conversely, repeated *locked upper* circuits on a small float usually indicate operator-driven price movement rather than demand, and should pull the stock toward the surveillance and delivery checks rather than into the portfolio. Size positions against the band, not the beta. + +--- + +## 3. Delivery volume vs traded volume (India) + +**India-specific**, and one of the most useful free datasets the Indian market provides. NSE and BSE publish security-wise delivery quantity alongside traded quantity in the daily bhavcopy. + +| Metric | Definition / how to compute | Indicative range | Why it matters | +|---|---|---|---| +| Delivery % | Delivery qty ÷ total traded qty, averaged over 30 / 90 / 250 days | Broadly 25–50% for liquid mid/large caps; higher for illiquid quality compounders; <20% signals churn | Separates ownership from speculation | +| Delivery-weighted volume trend | Delivery qty (not turnover) trend over 12 months | Rising with price = accumulation | Confirms whether a rally has real buyers | +| Divergence flag | Traded volume spiking while delivery % collapses | Any sharp fall below the stock's own 250-day norm | Classic churn / operator signature | + +Benchmark **against the sector and against the stock's own history**, never against an absolute number: an index-heavyweight with heavy derivative and algorithmic activity will structurally show lower delivery than an illiquid quality smallcap, and neither reading means what the raw figure suggests. + +**Why it matters.** A price move on huge volume at 15% delivery is rotation that typically reverses; the same move at 60–70% delivery suggests genuine accumulation that has to be sold before the price falls back. Persistently low delivery plus rising price plus a small free float is the standard fingerprint of price manipulation, and it pairs directly with Sections 1 and 6. **US analogue:** no delivery data exists; substitute short interest and days-to-cover, off-exchange (dark) volume share, and 13F/13D-G ownership changes. + +--- + +## 4. Liquidity, impact cost and realistic exit size + +Compute in **value, not shares** — share counts are meaningless across prices. + +| Metric | Definition / how to compute | Indicative healthy range | Why it matters | +|---|---|---|---| +| Median daily traded value (ADV) | Median (not mean — spikes distort) of daily turnover over 6 months | Depends entirely on your AUM; the ratio below is what matters | Base unit for every supply and sizing calculation | +| Days to exit | Position value ÷ (ADV × 10–20% participation) | ≤5 days for a core position; >20 days is a research-only name | The only honest definition of position capacity | +| Impact cost | Exchange-published cost of a standard order (India: NSE publishes impact cost for a Rs 1 lakh order); or model half-spread + depth | Low single-digit basis points for liquid names; >1% is a red flag | Also the exchange's own gating metric for index and F&O eligibility, so it forecasts inclusion | +| Bid–ask spread | Time-weighted spread ÷ mid | A few bps liquid, tens of bps smallcap | Direct round-trip cost, charged twice | +| Derivatives availability | Is the stock in NSE F&O / has listed US options? | — | Determines whether you have any hedge or short route at all | + +**Why it matters.** Position size is set by exit liquidity, not conviction. A stock trading Rs 2 crore a day cannot absorb a Rs 5 crore position without moving the price double digits — the exit cost eats the alpha you did the analysis to find. Liquidity is also reflexive: it evaporates precisely in the drawdown when you want to sell, so stress the calculation at 30–50% of normal ADV before deciding the position is exitable. + +--- + +## 5. Halts, suspensions and market-wide circuit breakers + +Check the stock's own history of exchange **suspensions** — non-compliance with listing regulations (India: SEBI LODR; US: exchange listing standards), delayed results, auditor resignation, scheme-of-arrangement freezes — and any compulsory-delisting watchlist entry. A suspension freezes capital for an indefinite period, and compulsory delisting can leave you holding an unlisted security with no realistic market. + +Separately understand **market-wide circuit breakers**: index moves of 10 / 15 / 20% trigger halts ranging from 45 minutes to the rest of the session, with the duration depending on the time of day the trigger is hit. Know your market's pre-open, post-close and any block/bulk-deal windows. + +**Why it matters.** Stop-losses do not execute during a halt, and the gap on resumption routinely prints through them. Anyone running leverage must size for a scenario in which they cannot act for a full session and then reopen 15% lower. This is a mechanical risk, independent of the company. + +--- + +## 6. Free float and float-adjusted supply + +From the quarterly shareholding pattern (India: mandatory under LODR, filed on the exchanges; US: proxy statement, 13F/13D/13G, and the cover page of the 10-K), compute **true free float**: + +> Shares outstanding − promoter/insider holding − locked-in shares − strategic, parent and government holdings − pledged/encumbered shares + +Track quarter-on-quarter movement in promoter, FII/DII (India), institutional (US), and small-retail buckets, plus the total number of shareholders. **India:** also check FPI sectoral and aggregate ceilings and the resulting "foreign room", because MSCI and FTSE apply a foreign-inclusion factor that can halve an index weight regardless of size. + +**Why it matters.** Float is the denominator for every supply event in Sections 7–14. A 12% float means an index inclusion or a 5% promoter sale is an enormous event; a 70% float absorbs the identical flow invisibly. Two composition signals to read directly: a **rising retail shareholder count against falling institutional holding** is usually distribution into weak hands, and a shrinking float with rising price and low delivery is a manipulation signature, not a scarcity story. + +--- + +## 7. The dilution map: build it once, in shares + +Before working through Sections 8–13 individually, build one table. Every row is a claim on your per-share economics. + +| Instrument | Where to find it | Key parameters to record | Effect on share count | +|---|---|---|---| +| Enabling resolution (unused) | AGM/EGM/postal-ballot notice; board outcome filings | Amount authorised, date passed, validity (typically 1 year) | Contingent — price it as an overhang | +| QIP / follow-on / shelf | Exchange filing; **US:** S-3 shelf, ATM programme in 10-Q | Size, floor formula, discount, allottees | Immediate | +| Preferential allotment | Postal ballot / EGM notice | Allottee identity, relationship, price vs floor, lock-in | Immediate | +| Warrants | Same notice; balance-sheet note | Exercise price, 25% upfront, 18-month window, lapse history | Deferred, holder-optional | +| Convertibles (FCCB/CCD/OCD/CCPS) | Balance-sheet notes, annual report | Conversion price, ratio, reset/ratchet, maturity | Deferred, sometimes automatic | +| ESOPs | ESOP note, cash flow statement | Outstanding, vested, weighted exercise price, annual grant run-rate | Continuous drip | +| Rights issue | Letter of offer | Ratio, price, RE trading window | Immediate, but pro-rata | +| Bonus / split | Corporate action circular | Ratio, record date | None economically | + +Then compute two numbers and use them consistently downstream: **fully diluted share count** (assume every in-the-money instrument converts) and **annual dilution rate** over the last 5–7 years (CAGR of diluted shares outstanding). Recompute EPS, P/E and market cap on the diluted base. If your valuation used basic shares while an in-the-money convertible sits in the notes, your valuation is simply wrong. + +--- + +## 8. QIP, preferential allotment and warrants + +**QIP (India).** Check for board/shareholder **enabling resolutions** — they frequently sit dormant for a year before use — the size sought, the SEBI floor-price formula (a two-week volume-weighted average of the relevant period), the actual discount to market, the allottee list, the stated use of proceeds, and resulting dilution. Note the 6-month lock-in on QIP shares and the minimum gap rule between successive QIPs. + +The real signal is **who was allotted**. Marquee long-only institutions validate the story and price. Allotment to unknown entities, or to parties with a visible relationship to the promoter, at or near the floor price, is a governance flag that belongs in `08-governance.md` as well as here. + +**Preferential allotment and warrants (India).** Read the postal-ballot/EGM notice: allottee identity and relationship to promoters, pricing versus the SEBI floor, lock-in (longer for promoter allottees; commonly 18 months for others, and up to three years for promoter minimum-contribution tranches — verify current SEBI ICDR provisions). Warrants carry 25% upfront with 18 months to pay the balance and exercise. + +Track the **history of earlier warrants**, which is unusually informative: +- Promoters exercising warrants at a price far below market = a wealth transfer from minority shareholders, plus a known deferred dilution overhang. +- Promoters letting warrants **lapse and forfeiting the 25%** = they judged the stock above fair value with their own money at stake. That is one of the cleanest negative signals available. + +**US analogue.** Shelf registrations (S-3) and at-the-market (ATM) programmes are the structural equivalent of an unused enabling resolution — an active ATM on a cash-burning company means continuous supply. PIPEs, and SPAC-era warrant overhangs with redemption triggers, are the equivalents of preferential allotments and warrants; read the warrant terms, not the headline share count. + +**Why it matters.** An unused authorisation is not nothing — it is a written option the company holds to sell shares to someone else at a discount, and it caps the stock near the floor price until resolved. Price the overhang; do not wait for the announcement. + +--- + +## 9. Convertibles and the honest diluted share count + +Search the balance-sheet notes and annual report for every convertible: FCCBs, compulsorily and optionally convertible debentures, convertible preference shares. Record conversion price, conversion ratio, reset clauses, maturity, coupon, and whether conversion is compulsory or at the holder's option. + +Three specific things to hunt for: + +1. **Anti-dilution / ratchet clauses** that reprice the conversion downward if the stock falls. These create a death-spiral: a falling price increases shares issued, which increases dilution, which pushes the price lower. Any structure with a floating conversion price tied to a trailing market price should be treated as a solvency issue, not a capital-structure detail. +2. **Unconverted instruments near maturity**, especially FCCBs. Out-of-the-money convertibles do not convert — they become a hard cash redemption liability, often in foreign currency, on a fixed date. That belongs in the debt-maturity ladder in `04-balance-sheet-and-cashflow.md`, not in the equity story. +3. **The EPS gap.** Reported basic EPS can overstate per-share earning power materially when convertibles are outstanding. Always restate. + +--- + +## 10. Rights issues + +Record the entitlement ratio, issue price versus market, record date, and — India-specific — the **Rights Entitlement (RE)** window: REs are credited to demat and trade on the exchange for a limited period, then **lapse worthless**. + +Compute the theoretical ex-rights price (TERP): + +> TERP = (existing shares × cum-price + new shares × issue price) ÷ total shares after issue + +**Why it matters.** A rights issue is not dilutive to a participant — it is dilutive only to someone who neither subscribes nor sells their REs. Retail holders let REs lapse routinely, which is a pure, avoidable, 100% loss on the entitlement value. Two analytical reads matter more than the arithmetic: **is the promoter taking up their full entitlement or renouncing** (non-participation is a strong statement about their view of the price, or about their own liquidity), and **what are the proceeds for** — growth capital versus repairing a balance sheet the last raise was also meant to repair. Deeply discounted rights also mechanically reset the price chart, so verify that price history and moving averages used anywhere in the analysis are adjusted. + +--- + +## 11. Bonus, splits and consolidations + +Confirm record date, ex-date and adjustment factor, and verify that **price history, moving averages, per-share metrics and any screen output have been adjusted**. Unadjusted data is a silent generator of false signals in every backtest and screener. + +Check how a bonus is funded (free reserves versus securities premium) and whether the company has a pattern of announcing bonuses into price strength. For a **reverse split / consolidation**, find the reason — it is very often cosmetic, undertaken to escape a minimum-price rule, a surveillance category or an exchange listing standard, on a business that is genuinely impaired. + +**Why it matters.** Bonuses and splits create exactly zero economic value; they change the share count and nothing else. Yet they reliably trigger retail buying, which makes them a convenient distribution window for insiders. Treat the announcement as an event to examine for *who is selling into it*, never as a positive fundamental datapoint. + +--- + +## 12. Buybacks: tender vs open market + +Determine the route first — the two are economically different instruments. + +| | Tender offer | Open market | +|---|---|---| +| Commitment | Binding for the stated size at the stated price | Non-binding authorisation; a ceiling, not a promise | +| Price | Fixed premium to market | Market price up to a maximum | +| Small-shareholder edge (**India**) | 15% of the buyback reserved for holders with ≤Rs 2 lakh at record date, often producing very high acceptance ratios | None | +| Analytical treatment | Estimate acceptance ratio from the shareholding pattern; a real, computable arbitrage | Assume partial completion; check actual spend versus authorised | + +Always check: is the buyback funded by surplus cash or by **debt**, or by cash the operating business actually needed? Are promoters/insiders tendering (participation changes the acceptance ratio and the signal)? And how does the buyback price compare to the company's own historical multiple range — buying back stock at a peak multiple destroys value exactly as reliably as issuing at a trough (see `08-governance.md` on capital allocation scoring). + +**Tax, and it inverts the conclusion.** **India:** for buybacks after the October 2024 change, proceeds are taxed **in the shareholder's hands as dividend income** at slab rate, with the cost of the tendered shares treated as a capital loss — this reversed the economics that made buybacks tax-efficient under the earlier company-level buyback-tax regime. **US:** a 1% corporate excise tax applies to net repurchases, and the shareholder's receipt is a capital-gains event, not dividend income. Verify current provisions before modelling any tender arbitrage; the after-tax answer, not the premium, is the answer. + +--- + +## 13. Lock-in expiries and pre-IPO supply cliffs + +Build an explicit calendar. **Size every tranche in shares, in percent of float, and in days of ADV** — the third number is the one that predicts the price impact. + +Typical Indian tranches (verify against the offer document and current SEBI ICDR rules): + +| Tranche | Typical lock-in | Seller behaviour | +|---|---|---| +| IPO anchor investors | 50% released at ~30 days, remainder at ~90 days | Mixed; the 90-day tranche is the larger event | +| Pre-IPO / PE-VC holders | ~6 months | Price-insensitive; 10x cost bases mean any price works | +| Promoter minimum contribution | 18 months to 3 years | Watch the date; often the last cliff | +| QIP shares | 6 months | Institutional, usually orderly | +| Preferential allotment | 6–18 months depending on allottee | Related-party allottees often sell immediately on release | +| ESOP vesting cliffs | Per scheme | Recurring, not a one-off | + +**US analogue:** IPO lock-ups (commonly 180 days, with early-release triggers tied to price or earnings dates), Rule 144 volume limits for affiliates, and Form 144 filings. + +**Why it matters.** This is the most predictable, calendar-driven source of downside in recently listed companies, and it is routinely ignored by fundamental analysis. A release of 40% of shares into a stock that trades a fraction of a percent of its float daily is an unavoidable supply shock, and the market typically front-runs the date rather than waiting for it. Early PE/VC investors are not valuation-sensitive sellers — they are return-crystallising sellers, and they will accept any price above their cost basis. + +--- + +## 14. Index inclusion, exclusion and rebalance flows + +Track eligibility and review calendars, not just current membership. + +- **India:** Nifty 50 / Next 50 / Midcap / Smallcap, Sensex, and the **AMFI semi-annual large/mid/small-cap reclassification**, which forces actively managed mid- and small-cap funds to adjust holdings, not just passive funds. Also watch F&O inclusion/exclusion, which changes hedgeability and margin. +- **Global:** MSCI quarterly/semi-annual reviews and FTSE reviews — pay attention to their float factors and **foreign-room adjustments**, which can produce a weight far below what market cap implies. **US:** S&P index committee additions (discretionary, announced with a short lead) and the annual Russell reconstitution (rules-based, heavily front-run). + +Estimate passive demand as **(index weight × tracking AUM) expressed in days of ADV**, and note the **announcement date versus the effective date** separately. + +**Why it matters.** Passive funds must trade at the close on the effective date regardless of price, so an inclusion creates mechanical buying and an exclusion mechanical selling that can be many multiples of daily volume. But the move mostly happens *between* announcement and effective date and then partially reverses — buying an inclusion after the announcement is usually buying the top. Treat index flow as a timing and execution consideration, never as a thesis. Impact cost (Section 4) is the exchange's own eligibility gate, so improving impact cost is a leading indicator of future inclusion. + +--- + +## 15. Open offers, delisting and schemes of arrangement + +These events override your thesis entirely — the exit price becomes a formula, not your valuation. + +- **India — SEBI Takeover Code (SAST):** an acquisition crossing the 25% threshold, or creeping acquisition beyond the permitted annual limit above it, mandates an open offer for a further 26%. Check the offer price formula and estimate the acceptance ratio. +- **Voluntary delisting (India):** reverse book building, the discovered price, the 90% threshold, and the limited post-delisting exit window. **US:** going-private transactions under Rule 13e-3 with a SC 13E-3 filing. +- **Demergers, mergers and schemes:** record the swap ratio, record date, when the resulting entity lists (there is often a gap during which you hold an untradeable entitlement), and — critically — the **cost-basis apportionment** between the original and resulting entities for tax. + +**Why it matters.** You can be forced to exit at a price you did not choose, or be left holding an unlisted share because you failed to tender by a deadline. Delisting arbitrage and open-offer acceptance ratios materially change expected return and should be modelled explicitly when live. Demerger cost-basis apportionment is a routine source of tax error because brokers frequently show the new entity at zero cost, overstating the gain by the entire sale value. + +--- + +## 16. Capital gains: holding period is a position decision + +Confirm the holding-period threshold and rate for the asset class, in the holder's jurisdiction, as of the transaction date. + +**India (indicative; verify against current Finance Act).** Listed equity and equity mutual funds: 12 months separates short from long term (24 months for most other assets). Post-23 July 2024, STCG on listed equity under section 111A is **20%**, and LTCG under 112A is **12.5%** with an annual exemption of **Rs 1.25 lakh** and no indexation. Pre-31 January 2018 purchases are grandfathered — cost is stepped up to the higher of actual cost and the 31-Jan-2018 fair market value. Broker tax reports use FIFO matching; reconcile against the AIS / Form 26AS. + +**US (indicative; verify).** Long-term treatment requires a holding period exceeding one year; long-term rates are tiered (0/15/20%) with a net investment income tax on top for higher incomes, while short-term gains are taxed as ordinary income. There is no annual capital-gains exemption equivalent to India's. + +**Why it matters, in decision terms:** +- A sale one day before the 12-month mark can cost several percentage points of tax **on the entire gain** — money no stock-picking edge recovers. Always check the holding-period clock before recommending an exit. +- Rates changed mid-year in India in 2024, so any multi-period calculation must be **split by transaction date**. Do not apply one rate across a straddling year. +- Deferred capital-gains tax is an interest-free loan from the state that compounds with the position. A strategy that turns over annually pays tax every year on a smaller and smaller base; a 10-year hold pays once. This is a real, quantifiable argument for lower turnover, and it belongs in the recommendation. +- Mismatches between broker P&L and the AIS are a common trigger for tax notices in India. + +--- + +## 17. Dividend taxation and withholding + +**India (indicative; verify).** Post-2020 there is no dividend distribution tax at the company level; dividends are taxed in the shareholder's hands at slab rate as income from other sources. TDS applies (commonly 10%) above an annual per-company threshold; Forms 15G/15H may apply for those eligible. Reconcile dividends received against the AIS and claim the TDS credit — unreconciled credits are simply money lost. + +**US (indicative; verify).** Qualified dividends receive long-term capital-gains rates but only if a minimum holding period around the ex-date is satisfied; non-qualified dividends are ordinary income. REIT distributions are largely non-qualified. + +Two mechanical points that change conclusions: + +1. **Compute after-tax yield at the holder's marginal rate before comparing.** A 6% headline yield is roughly 4.2% after tax at a 30% marginal rate — which can invert a ranking against a lower-yielding grower or a buyback-returning company. Comparing pre-tax dividend yield against post-tax total return is exactly the kind of like-for-unlike comparison this skill exists to prevent. +2. **The price drops by approximately the dividend on the ex-date.** "Buying for the dividend" converts capital into taxable income and nothing else. Note ex-date versus record date carefully (Section 22). + +--- + +## 18. The transaction cost stack: STT, stamp duty, round trip + +Model the **full stack for the actual strategy**, then express it as a round-trip percentage and multiply by expected annual turnover. + +**India components (rates change; verify each):** Securities Transaction Tax — different rates for delivery buy and sell, intraday sell, futures sell, options premium and options exercise; exchange transaction charges; SEBI turnover fee; stamp duty on the buy side; GST on brokerage and on charges; DP charges levied per sell instruction (a flat fee, so brutal on small sells); brokerage itself. + +**US components:** SEC Section 31 fee on sales, FINRA TAF, commissions (often zero at retail, but payment-for-order-flow shows up as worse execution), ADR custody/pass-through fees on foreign holdings, and currency conversion spreads on any cross-border trade. + +| Cost concept | How to compute | Indicative magnitude | Why it matters | +|---|---|---|---| +| Round-trip explicit cost | Sum of all statutory + broker charges, buy + sell | Tens of bps for Indian delivery equity | Charged on turnover regardless of profit | +| Round-trip implicit cost | Half-spread × 2 + market impact at your size | Often larger than explicit cost in smallcaps | The cost nobody invoices you for | +| Annual friction drag | Round-trip cost × portfolio turnover | A 4x-turnover strategy can lose 1.5–3% a year before tax | Frequently exceeds the alpha being chased | + +**Why it matters.** STT is levied on turnover, not profit — it is a guaranteed drag that scales linearly with churn and is paid in losing years too. The derivative structures deserve specific attention: options held to expiry have historically been charged STT on a basis far larger than the premium, which can make a strategy that looks profitable on the P&L unprofitable in reality. Any recommendation implying frequent rebalancing must state the friction cost explicitly. + +--- + +## 19. Cross-border: withholding, treaty relief, PFIC, estate tax + +This is where the largest avoidable losses occur, and none of it appears in any financial statement. + +**Dividend withholding and treaty relief.** Foreign dividends are withheld at source. Treaty relief is not automatic — it requires the right form filed *in advance* (a W-8BEN for a non-US person receiving US income, for example), and the foreign tax credit requires the right form filed with the home return (India: Form 67, filed within the prescribed deadline). Indian residents holding US equities are typically withheld at the treaty rate under the India–US DTAA rather than the statutory non-resident rate, and can claim credit — but only if the paperwork was done. **Verify current rates and deadlines.** People routinely surrender double-digit percentages of their dividend income to a missing form. + +**PFIC (US persons only, and it is punitive).** A non-US pooled investment — a foreign mutual fund, a UCITS ETF, many foreign holding and investment companies — is generally a Passive Foreign Investment Company for a US taxpayer. The default section 1291 regime taxes "excess distributions" at the highest ordinary rate with a compounding interest charge on deferred amounts, and requires annual Form 8621 filing. QEF and mark-to-market elections can mitigate this but require information the fund may not provide. Practical consequence for this skill: **a US-taxable holder should generally not be steered into non-US pooled vehicles**, and even foreign operating companies must be screened for the income and asset tests if they hold large passive/cash balances. Ordinary foreign operating businesses are usually not PFICs — cash-heavy shells and post-IPO companies sitting on large raises can be. + +**Situs-based estate tax (frequently overlooked and potentially catastrophic).** Estate tax can be levied by the country where the *asset* is situated, regardless of where the owner lives or whether their home country has an estate tax. US-situs assets — including directly held US shares — expose a non-resident non-citizen's estate to US estate tax above a very low exemption threshold (far below the domestic exemption), at rates rising to 40%, and India has no estate-tax treaty with the US to relieve it. UK-situs assets carry an analogous inheritance-tax exposure. **This is a structural reason a large direct US-stock holding may be better held through a non-US-situs wrapper** — but that is a legal and tax-planning decision for a qualified professional, and this file's job is to flag the exposure and its size, not to design the structure. Never present a large foreign-equity allocation without naming this. + +**India-specific outbound and NRI items.** Remittances abroad fall under the LRS annual limit with TCS on outward remittance above a threshold (verify current rate and threshold). Foreign assets and foreign income must be disclosed in **Schedule FA** of the Indian ITR — non-disclosure carries penalties under black-money legislation that can dwarf the investment itself, and applies even to loss-making or nil-income holdings. For NRIs investing in India: TDS is deducted on capital gains at source (often on gross gains, locking up capital until a refund a year later), PIS/non-PIS account rules apply, and NRE versus NRO determines repatriability. + +--- + +## 20. Loss set-off, carry-forward and harvesting + +Know the hierarchy before recommending any realisation. + +**India (indicative; verify).** +- Short-term capital loss sets off against **both** STCG and LTCG. +- Long-term capital loss sets off **only** against LTCG. +- Unabsorbed losses carry forward eight assessment years — **but only if the return is filed by the due date.** +- Speculative (intraday) losses set off only against speculative gains and carry forward four years. +- There is **no wash-sale rule**, so an immediate repurchase is permitted — but weigh it against GAAR and against the round-trip STT/brokerage cost of the manoeuvre. +- Harvest **gains** as well as losses: realise gains up to the annual LTCG exemption each year to step up cost basis for free. + +**US (indicative; verify).** The **wash-sale rule** disallows a loss if a substantially identical security is bought within 30 days before or after the sale — the opposite of India's position, and the single most common cross-jurisdiction mistake. Capital losses carry forward indefinitely, with a limited annual offset against ordinary income. + +**Why it matters.** Filing one day late in India permanently forfeits that year's loss carry-forward — a pure paperwork destruction of real value. Getting the set-off order wrong wastes short-term losses (which could have sheltered gains taxed at the higher short-term rate) against long-term gains taxed at the lower one. And harvesting gains up to an annual exemption is free basis step-up that most investors never claim. Plan before the tax-year end (31 March in India, 31 December in the US), not after. + +--- + +## 21. Custody, demat and account hygiene + +Custody failures, not stock selection, cause a large share of permanent retail losses. Check: + +- **Reconcile the depository, not the broker.** India: pull the Consolidated Account Statement from CDSL/NSDL and match it to the broker ledger. This is the only independent verification that the shares you think you own exist in your name. +- **Nomination** registered on every demat account, trading account and mutual fund folio. Estates regularly cannot claim holdings without it. +- **Account type:** confirm holdings are not in a pooled or margin-funded account where they can be re-pledged. +- **POA versus DDPI (India):** a broad Power of Attorney historically allowed brokers wide latitude over client securities; the Demat Debit and Pledge Instruction narrows it to specific purposes. Know which you signed. Confirm the margin-pledge flow is used rather than title transfer. +- **KYC, bank mandate and contact details current.** Lapsed KYC freezes accounts; a stale address breaks corporate-action notices. +- **IEPF (India):** dividends unclaimed for seven consecutive years — and **the underlying shares with them** — are transferred to the Investor Education and Protection Fund. Recovery is possible but slow. Check for any unclaimed-dividend history on inherited or long-dormant holdings. + +--- + +## 22. Settlement, record dates and response obligations + +**Settlement cycle (verify current):** India operates on T+1 with an optional same-day (T+0) segment for a specified set of stocks; the US moved to T+1; several other markets remain T+2 and are migrating. The cycle directly determines corporate-action eligibility. + +**Derive the cum-date rather than memorising it.** To receive an entitlement you must be on the register on the record date, which means your purchase must have *settled* by then. Under a T+1 cycle, a trade must therefore be executed no later than one trading day before the record date — so the ex-date falls on the record date itself, whereas under T+2 it fell a day earlier. Confirm against the specific corporate-action circular for every event, because this convention shifted when settlement cycles changed and stale guidance is everywhere. + +**The error to prevent:** buying *on* the record date gets you nothing except the ex-date price drop. This is one of the most common and most entirely avoidable retail mistakes, and it is expensive around rights entitlements and buyback record dates where the entitlement value is material. + +**Response obligations — corporate actions that require you to act, with deadlines:** + +| Event | Required action | Consequence of inaction | +|---|---|---| +| Rights issue | Subscribe, or sell the REs before the window closes | REs lapse worthless — total loss of entitlement value | +| Tender buyback | Submit the tender through the broker before close | Forgo the premium and the small-shareholder acceptance edge | +| Open offer | Tender by the deadline | May be left holding a stub in a controlled or delisting company | +| Voluntary delisting | Tender in reverse book building or in the exit window | Left holding an unlisted, largely unsaleable security | +| Scheme of arrangement | Usually automatic, but track listing of the resulting entity and apportion cost basis | Overstated capital gain when the broker shows zero cost | + +**Margin and settlement penalties.** Understand upfront/peak margin requirements, short-delivery auction mechanics and the auction settlement price. Short delivery pushes your sale into an auction where the settlement price can be far worse than your intended exit, and peak-margin shortfalls attract penalties that compound within a single day. + +--- + +## 23. Sector translation: where this lens inverts + +Apply this before drawing any conclusion from Sections 7–14. The standard reading of "dilution is bad" and "high payout is good" breaks in specific sectors. + +- **Banks and NBFCs.** Equity issuance is not a symptom of weakness — regulatory capital is the raw material of the business, and a growing lender *must* raise. The correct test is **issue price versus book value per share**: raising above 1x P/B is accretive to book value per share and enables growth; raising below book destroys per-share value even when the raise is necessary. Judge a QIP by that arithmetic, not by the dilution percentage. Watch also for regulator-mandated capital raises and promoter-dilution mandates (India: RBI shareholding norms), which are timing-forced, not opportunistic. +- **Insurers.** Similar capital logic on solvency ratio rather than book value; growth in new business consumes capital before it produces earnings. +- **REITs and InvITs (India) / REITs (US).** Distributions are not dividends and are **not taxed as a single stream**. An Indian REIT/InvIT distribution is split into interest, dividend, rental and return-of-capital components with different tax treatment for each, and the return-of-capital portion reduces the unit cost basis rather than being taxed currently. Computing an after-tax yield requires the distribution breakup from the trust, not the headline yield. These vehicles also distribute nearly all cash flow by regulation, so they fund growth by issuing units continuously — routine dilution that must be judged on NAV accretion, not avoided. +- **Miners and commodity producers.** Equity issuance to fund development is structurally normal and pre-production companies dilute relentlessly; model dilution per unit of reserve added, not the raw share-count increase. Commodity ETF and index flows can dominate the tape independently of company news. +- **PSUs (India).** Government shareholding is a standing supply overhang — OFS tranches, strategic disinvestment and buyback-for-treasury decisions are policy events with announced dates, not market events. Divestment intent should sit permanently on the supply calendar. +- **Smallcaps and SME-platform listings (India).** Every mechanic in this file binds hardest here: surveillance categories, tiny float, low delivery, wide bands, and lot-size constraints on the SME platform. The tradeability gate should be a genuine kill criterion at this size, not a caveat. +- **Recently listed companies anywhere.** The lock-in calendar (Section 13) frequently dominates fundamentals for the first 12–18 months. Do not compare a post-IPO chart to a seasoned peer's without it. + +--- + +## Checklist + +- [ ] Run the tradeability gate before deep work: surveillance status, band, ADV, impact cost, delivery %, free float. +- [ ] India: check current ASM / GSM / ESM lists, note stage, date applied, consequences and next review date. +- [ ] Identify the applicable price band; count locked-circuit days separately from circuits touched with volume. +- [ ] India: compute delivery % over 30/90/250 days against sector and own history; flag volume spikes with collapsing delivery. +- [ ] Compute median daily traded value and days-to-exit at 10–20% participation; stress it at 30–50% of normal ADV. +- [ ] Check suspension and delisting-watchlist history; know the market-wide circuit-breaker rules if using leverage or stops. +- [ ] Compute true free float (net of promoter, lock-in, strategic, pledged); track institutional vs retail composition shift. +- [ ] Build the dilution map: every enabling resolution, QIP, preferential issue, warrant, convertible and ESOP tranche. +- [ ] Restate EPS, P/E and market cap on the fully diluted share count; compute the 5–7 year dilution CAGR. +- [ ] Judge every QIP and preferential allotment by allottee identity and price versus floor, not by size. +- [ ] Check warrant exercise-versus-lapse history — promoter forfeiture of the 25% upfront is a strong negative signal. +- [ ] Hunt for reset/ratchet clauses and for out-of-the-money convertibles maturing as cash liabilities. +- [ ] For rights issues: compute TERP, note the RE window, and check whether promoters are subscribing or renouncing. +- [ ] Verify all price history and per-share metrics are adjusted for bonuses, splits and consolidations. +- [ ] Classify buybacks as tender or open market; estimate acceptance ratio; check funding source and after-tax treatment. +- [ ] Build the 24-month lock-in and supply calendar, sized in shares, % of float and days of ADV. +- [ ] Estimate index inclusion/exclusion flow in days of ADV; separate announcement date from effective date. +- [ ] Check for live open offers, delisting proposals or schemes; model the formula price, not your valuation. +- [ ] Verify capital-gains holding period, rates and thresholds against current law for the holder's jurisdiction and residency. +- [ ] Check the holding-period clock before recommending any exit; split calculations across mid-year rule changes. +- [ ] Compute after-tax dividend yield at the holder's marginal rate before comparing yield to any total-return alternative. +- [ ] Model the full round-trip cost stack and multiply by expected turnover; report the friction drag explicitly. +- [ ] For foreign holdings: confirm withholding rate, treaty form filed in advance, and foreign tax credit form and deadline. +- [ ] Screen US-taxable holders for PFIC exposure in any non-US pooled vehicle; flag Form 8621 obligations. +- [ ] Flag situs-based estate-tax exposure on large direct US or UK holdings; refer the structuring to a professional. +- [ ] India: confirm Schedule FA disclosure of all foreign assets, LRS limits and TCS on outward remittance. +- [ ] Apply the correct loss set-off order; note India has no wash-sale rule while the US does; file on time to preserve carry-forward. +- [ ] Harvest gains up to any annual exemption as well as losses, before the tax-year end. +- [ ] Reconcile depository statement against broker ledger; verify nomination, KYC, DDPI scope and any unclaimed-dividend/IEPF history. +- [ ] Derive the last cum-date from the current settlement cycle for every corporate action; never buy on the record date for the entitlement. +- [ ] List every corporate action requiring a shareholder response, with its deadline and the cost of inaction. +- [ ] Apply the sector translation: for banks judge raises on price versus book; for REITs/InvITs use the distribution breakup, not headline yield; for PSUs treat divestment as standing supply. +- [ ] State gross and net-of-cost, net-of-tax expected return in the report — and the date of the tax rules applied. diff --git a/finance/skills/stock-analysis/references/17-process-and-epistemics.md b/finance/skills/stock-analysis/references/17-process-and-epistemics.md new file mode 100644 index 00000000..73691ef7 --- /dev/null +++ b/finance/skills/stock-analysis/references/17-process-and-epistemics.md @@ -0,0 +1,517 @@ +# Research Process, Epistemics and the Price Layer + +Use this when: you are deciding *how* to run the analysis rather than what number to compute — at the start (scoping, competence, budget), at the point of judgement (Stage 8-10, forming a view), and before you write the verdict. + +Everything else in this skill tells you what to measure. This file tells you how to think while measuring, and how to know when you are fooling yourself. It matters because the dominant failure mode in equity research is not arithmetic error — it is a well-executed analysis of the wrong question, or a correct analysis whose conclusion was fixed before the work began. The governing rule of this skill (a metric is meaningless until you know its sector and the company's own history; never rank on a single number; for banks, insurers, REITs and miners the standard ratios are undefined or inverted) is itself an epistemic rule, not a formatting rule — it exists because context-free numbers produce confident, invertible conclusions. Part B adds the price layer, which is a genuine input to risk control and timing and a rationalisation engine if you let it lead. + +## Contents + +**Part A — Process, epistemics and decision hygiene** +- [1. Circle of competence and the "too hard" pile](#1-circle-of-competence-and-the-too-hard-pile) +- [2. Research budget and diminishing returns](#2-research-budget-and-diminishing-returns) +- [3. Falsification-first research design](#3-falsification-first-research-design) +- [4. Steelmanning the bear case; reading short reports](#4-steelmanning-the-bear-case-reading-short-reports) +- [5. Base rates and the outside view](#5-base-rates-and-the-outside-view) +- [6. Checklists that work; scores that must not decide](#6-checklists-that-work-scores-that-must-not-decide) +- [7. False precision: ranges, reverse DCF and decimals](#7-false-precision-ranges-reverse-dcf-and-decimals) +- [8. Conviction is not certainty: confidence tiers and sizing](#8-conviction-is-not-certainty-confidence-tiers-and-sizing) +- [9. The research file and the evidence trail](#9-the-research-file-and-the-evidence-trail) +- [10. The decision journal and calibration](#10-the-decision-journal-and-calibration) +- [11. Re-underwriting on a schedule](#11-re-underwriting-on-a-schedule) +- [12. Update discipline: signal vs noise](#12-update-discipline-signal-vs-noise) +- [13. Source quality, incentives and management assertions](#13-source-quality-incentives-and-management-assertions) +- [14. Knowing when to say no](#14-knowing-when-to-say-no) +- [15. Pre-mortems and post-mortems](#15-pre-mortems-and-post-mortems) +- [16. Anchoring, framing and order effects](#16-anchoring-framing-and-order-effects) +- [17. External challenge and echo chambers](#17-external-challenge-and-echo-chambers) +- [18. Auditing the process itself](#18-auditing-the-process-itself) +- [19. Epistemic rules specific to an AI analyst](#19-epistemic-rules-specific-to-an-ai-analyst) + +**Part B — Price action, technical and timing inputs** +- [20. What the price layer is for](#20-what-the-price-layer-is-for) +- [21. Chart data hygiene](#21-chart-data-hygiene) +- [22. Trend and moving-average structure](#22-trend-and-moving-average-structure) +- [23. Relative strength vs index and vs sector](#23-relative-strength-vs-index-and-vs-sector) +- [24. 52-week positioning and momentum](#24-52-week-positioning-and-momentum) +- [25. Volume, delivery and the institutional footprint](#25-volume-delivery-and-the-institutional-footprint) +- [26. Volatility, beta and capture](#26-volatility-beta-and-capture) +- [27. Drawdown history and regime behaviour](#27-drawdown-history-and-regime-behaviour) +- [28. Liquidity, float and tradability](#28-liquidity-float-and-tradability) +- [29. Short interest, crowding and positioning mechanics](#29-short-interest-crowding-and-positioning-mechanics) +- [30. Event behaviour and non-fundamental flow](#30-event-behaviour-and-non-fundamental-flow) +- [31. Staged accumulation and invalidation levels](#31-staged-accumulation-and-invalidation-levels) +- [32. Price-fundamental divergence: the tape as evidence](#32-price-fundamental-divergence-the-tape-as-evidence) +- [33. Where technicals add value and where they mislead](#33-where-technicals-add-value-and-where-they-mislead) +- [Checklist](#checklist) + +--- + +# Part A — Process, epistemics and decision hygiene + +## 1. Circle of competence and the "too hard" pile + +Before opening a spreadsheet, write one page in plain language: how does this company make money, who pays and why, what would have to be true for it to earn materially more in five years, and which three variables drive the outcome. No jargon, no sell-side deck, no "platform". If you cannot write that page from primary sources, the correct output is not a weak analysis — it is a documented pass. + +Keep a literal, dated **too-hard list** with the reason recorded, so the same name is not re-litigated every quarter. Recurring members: pre-revenue biotech; opaque cross-border holding structures (VIEs, layered offshore SPVs); banks and insurers where you cannot read the loan book, restructured-asset disclosure or reserve triangle; commodity trading houses; serial acquirers whose growth is unauditable roll-up accounting; crypto-adjacent balance sheets; companies where the majority of profit sits in unconsolidated or related-party entities. + +**India-specific too-hard triggers:** promoter groups with a history of related-party fund diversion; companies with high or rising promoter pledge and opaque end-use; frequent auditor changes with no CARO explanation; a listed holdco whose value is entirely unlisted subsidiaries with no published accounts; names under SEBI's GSM/ASM surveillance framework where price formation itself is impaired. + +Watch for **competence drift** — the slide from a real competence area (consumer staples) to an adjacent-sounding one (specialty pharma) whose value drivers are entirely different. The tell is that you start reasoning by analogy rather than from unit economics. + +*Why:* most permanent loss comes from owning what you could not assess, not from missing winners. Passing has zero cost; being wrong with capital committed does not. + +## 2. Research budget and diminishing returns + +Set the depth budget before you start and tie it to the stakes and reversibility of the decision, not to how interesting the company is. Track *which source actually changed your estimate* of the three key variables. When the last block of work produced no revision to those three, stop — that is the diminishing-returns signal, and the honest thing to do is write up. + +Prefer **breadth of source type** (filings, competitor filings, customer disclosures, regulator dockets, industry data, trade press) over depth in one type (the tenth broker note). Guard both errors: the over-researched name that must be bought because forty hours were spent on it, and the "obvious" idea presented with the same confidence as a researched one. + +*Why:* the payoff curve on research is strongly concave — the annual report, the competitor's annual report and the cash flow statement capture most of the edge. Later hours add confidence without accuracy, and sunk effort biases the conclusion toward action. + +## 3. Falsification-first research design + +Write the thesis as a **falsifiable statement with numbers and dates** before gathering supporting evidence: "segment revenue compounds above 12% through FY29 while gross margin holds above 45%". Then list the specific observations that would prove it false, and assign each disconfirmer a data source and a check frequency. + +Then spend the *first* research block hunting disconfirmation: the bear case, the losing competitor's commentary, the regulator's docket, customer complaint channels, the changed risk factors. No verdict is written until at least one serious attempt to kill the thesis has been documented and survived. + +*Why:* confirmation bias is the default state of research — once you like an idea, every subsequent fact reads as support. Reordering the process is one of the very few debiasing techniques that works, because it changes *what you look at* rather than asking you to feel less biased. It also converts narrative into a testable claim, which is a precondition for ever knowing you were wrong. + +## 4. Steelmanning the bear case; reading short reports + +Write the bear case yourself, in its strongest form, *before* reading anyone else's — then compare, and treat the gap as a measure of your blind spots. Then actively source the other side: short-seller reports, the most negative covering analyst, bearish threads that contain actual numbers, borrow cost and short-interest trends, and the year-over-year *diff* of the company's own risk factors (a newly added risk factor is a disclosure event). + +When reading a short report, separate three layers and treat them differently: + +| Layer | How to treat it | +|---|---| +| **(a) Verifiable facts** — filings, court records, customs/import data, permits, registry entries | Check each one yourself against the primary source. These are the only part that can change a thesis. | +| **(b) Interpretation** of those facts | Argue with it. Reasonable people read the same filing differently. | +| **(c) Rhetoric, price target, framing** | Discount entirely. It is marketing for a position. | + +Note the author's incentive and horizon, but never dismiss a report on incentive alone — everyone publishing has a position. Ask the decisive question: *if every checkable fact in this report is true, does my thesis survive?* Then watch the company's response — a specific, itemised, numbers-based rebuttal is informative; a defamation notice plus ad hominem is also informative. + +**India note:** dedicated short reports are rare and the borrow market (SLB) is thin, so adversarial work is under-supplied. Substitute: rating agency rationales and downgrade notes, CARO qualifications, auditor resignation letters filed with the exchanges, SEBI orders and adjudication notices, NCLT filings, and the MCA/ROC accounts of unlisted group entities. + +*Why:* shorts are the only participants paid to do adversarial forensic work on a company, and they have repeatedly surfaced accounting and related-party issues years ahead of the market. The failure is symmetric: dismissing them costs you fraud blow-ups, following them blindly costs you the many short reports that are simply wrong about well-run companies. + +## 5. Base rates and the outside view + +Before accepting any company-specific forecast, find the reference class and state its base rate. What share of companies sustain 20%+ revenue growth for a decade? What share of large acquisitions create value? How often do turnarounds actually turn? What is the historical distribution of margin expansion for firms already at this margin level? How many entrants in this category survived a full cycle? + +Then compare the company's own five-to-ten-year record and management's prior guidance-versus-delivery against the current promise, and state **explicitly why this company should beat the base rate** — a specific, durable mechanism. "Great management" and "large TAM" are not mechanisms. + +Always sanity-check the terminal implication: what share of the addressable market must the company hold in year 10 for the model to work, and has any company ever held that share in this industry structure? A model that implicitly requires 40% share of a fragmented, low-switching-cost market has already told you it is wrong. + +*Why:* the inside view — a bottom-up story built from company detail — is systematically overoptimistic because it ignores how rarely the story class succeeds. High growth mean-reverts, high margins attract entry, most M&A destroys value. Base rates are the cheapest available correction and they are usually devastating to the aggressive case. + +## 6. Checklists that work; scores that must not decide + +Tier the checklist. Run a short **kill-switch list** on every name — roughly ten to fifteen disqualifiers: auditor resignation or qualified opinion, going-concern language, unexplained related-party flows, chronic negative operating cash flow with rising debt, promoter pledge above a threshold with falling price, restatement, undisclosed encumbrances, a covenant cliff inside twelve months. Only names that survive get the long list. + +On scoring (see `references/11-scoring-rubric.md`), enforce four rules: + +1. **Normalise every factor within sector or against the company's own history.** Raw cross-sector numbers in a composite reproduce exactly the single-metric error this skill exists to prevent. +2. **Veto factors override any score.** Averaging converts a fatal binary flaw — fraud, a covenant cliff, an unfixable governance problem — into a small point deduction. +3. **Check for compensating errors.** A very strong score on one factor masking a fatal weakness on another is the composite's characteristic failure. +4. **Test weight sensitivity.** If a plausible reweighting reorders your top names, the score contains no information and must not be reported as if it does. + +Audit checklist use periodically: which items have never once changed a conclusion (delete them), and which post-mortems traced to an item that was skipped (promote them). + +*Why:* a 200-item list run without attention becomes a tick-box ritual that manufactures false confidence, and weights chosen without evidence are priors wearing a spreadsheet costume. Scoring exists to structure judgement, not to replace it. + +## 7. False precision: ranges, reverse DCF and decimals + +Force every valuation output into a **range with stated assumptions**, and check that the low case is genuinely bad — recession *plus* share loss *plus* margin reversion — not merely "slightly less good". Count decimals: if a DCF prints a fair value to the cent while terminal value is 75% of the total, delete the decimals and demote the model to a scenario-comparison tool. + +Make **reverse DCF the primary tool** (`references/06-valuation.md`): what growth, margin and reinvestment rate does today's price imply, and does that sit inside or outside the company's own historical distribution and the sector's? Judging whether an implied assumption is plausible is a far easier task than forecasting the future outright. + +Stress only the two or three assumptions that drive most of the variance — sensitising forty inputs is theatre. Reconcile the model's implied unit economics to something physical: stores, seats, tonnes, MW, beds, subscribers, capex per unit of capacity. And never inherit precision from a consensus number or third-party model you have not reproduced. + +*Why:* a model's precision is capped by its least reliable input. A five-year revenue estimate accurate to ±30% cannot produce a fair value accurate to the rupee — but the false precision is exactly what generates the confidence to overweight and to ignore contradicting evidence. + +## 8. Conviction is not certainty: confidence tiers and sizing + +Conviction is a feeling produced by familiarity and effort. Certainty is a property of the evidence. They diverge most dangerously after long research. Keep two things separate in the write-up: + +- **How likely the thesis is to be right** — and on what evidence. +- **The payoff spread** — how bad the downside is if wrong, how good the upside if right. + +A high-probability / low-upside case and a low-probability / high-upside case are not the same recommendation even if both are "positive". State both. + +Cap stated confidence by the **quality of the information**, not the strength of the narrative: what share of the thesis rests on verified primary data, versus management assertion, versus your own extrapolation? Any fraud or governance question, or any single-point-of-failure risk (one customer, one product, one regulator, one plant, one country), caps confidence regardless of how good the numbers look. + +Where the report discusses sizing or risk control, keep it **generic and principle-based** — volatility- and drawdown-aware sizing, hard caps for governance-questionable names, checking whether five holdings are really one factor bet. Do not write personalised allocation instructions; you are producing analysis, not advice, and the report should say so. + +*Why:* sizing is where epistemics become financial. An excellent process with reckless sizing still ends in ruin; modest sizing lets you be wrong often enough to keep compounding. If you cannot articulate why confidence is high rather than moderate, the analysis is not finished. + +## 9. The research file and the evidence trail + +Maintain one file per name containing: five to ten years of annual reports and proxies (India: annual report + notice of AGM + shareholding pattern; US: 10-K, 10-Q, DEF 14A via EDGAR), transcripts, the **page or paragraph citation behind every key claim**, the peer set with the reason for each inclusion and exclusion (`references/10-peer-set.md`), the model, and links to primary data — regulatory filings, trial and patent registries, customs/import-export data, court and NCLT dockets, environmental permits, job postings. + +Tag every input by epistemic status, and keep the tags visible in your working notes: + +| Tag | Meaning | Weight it carries | +|---|---|---| +| **F** | Audited or regulator-filed fact | Highest; can be relied on with a citation | +| **A** | Management assertion (concall, press release, investor deck) | Claim about the future or about unaudited detail — never restate as fact | +| **E** | Third-party estimate (broker, industry report, data vendor) | Usable as context; must be attributed and dated | +| **I** | Your own inference | Must be labelled; it is where most errors enter | + +Retain superseded versions rather than overwriting, so thesis drift is visible. Never let a screener or data vendor figure drive a conclusion without reconciling it to the filing — vendors routinely mis-map segments, mishandle leases (IFRS 16 / Ind-AS 116), treat preference shares and perpetual instruments inconsistently, mis-state net debt, use unadjusted share counts, and silently restate history. Adjusted earnings, net debt, share count and segment data are the four that must always be traced to source. + +*Why:* without a trail you cannot re-underwrite honestly, because you will not remember which numbers were verified and which were absorbed from a summary. The file is also what makes a post-mortem possible — you can only learn from an error if you can reconstruct what you actually believed and why. + +## 10. The decision journal and calibration + +At the moment of every conclusion — buy, add, trim, exit, or **pass** — record, before the outcome is known: the thesis in one paragraph; the three key variables and the forecast for each; the price and valuation at the time; what would trigger a reversal; a numeric probability; and what you expect to happen and by when. Include the state of the world (market regime, what else was happening), because that is what lets you spot mood-driven decisions later. + +Review on a fixed cadence and score **calibration**: of the calls made at 80%, how many happened? Then tag each closed decision on the two-by-two — good process/good outcome, good process/bad outcome, bad process/good outcome, bad process/bad outcome — and take the lesson only from the *process* column. + +Journal the passes too. A portfolio-only record cannot show whether the too-hard pile is protecting you or quietly costing you. + +*Why:* memory reconstructs the past to fit the outcome. Hindsight bias makes every loss look foreseeable and every win look deliberate, which destroys the feedback loop that learning depends on. A contemporaneous, pre-outcome, written record is the only defence. + +## 11. Re-underwriting on a schedule + +At least annually, and after any material event, re-underwrite from scratch. The test is: **would you initiate this position today, at today's price, with today's facts, at this size?** Write the fresh thesis *before* rereading the old one, then compare — the gap is where thesis drift lives. + +Classify explicitly: + +- **Thesis intact, price fell** → potentially add. +- **Thesis broke** → exit; the loss is already taken, the only question is whether more capital should stay. +- **Thesis was quietly replaced with a new one to justify continuing to hold** → exit. This is the growth story becoming a value story becoming a dividend story becoming a "cheap on book" story. It is a permanent loss wearing the costume of long-term conviction. + +Check the original key variables against actual delivery, and ask whether the original reason to own has already played out. Counter the endowment effect with a periodic clean-slate exercise: list holdings anonymously, with only their metrics and theses, and rank them against new candidates. + +*Why:* portfolios decay silently. The world moves, the reason for owning expires, and the position persists on inertia and familiarity. Re-underwriting converts every holding into an active decision, which is the only fair standard. + +## 12. Update discipline: signal vs noise + +Pre-specify, **at the time of the conclusion**, what counts as thesis-relevant. Write the list: "gross margin below 42% for two consecutive quarters matters; a single quarter's revenue miss on FX does not; loss of the top customer matters; a broker downgrade does not." + +When news arrives, ask one question: does this change one of the three key variables, or only the sentiment? A material adverse fact on a key variable triggers a full re-underwrite within a defined window — not a reflex trade, and not a silent explaining-away. + +Guard both errors. **Anchoring** — refusing to update after a genuine break, which is most acute when already losing money on the name. **Over-updating** — rewriting the thesis every earnings call, which produces turnover, costs and worse decisions. And check whether you are updating on the *price move* rather than on evidence: price is information about other participants' views, not about the business, though a persistent unexplained divergence deserves an explanation (Section 32). + +*Why:* most information flow is noise, but the rare genuinely thesis-breaking fact must be acted on immediately — and it is precisely the one you will most want to rationalise, because you are already down on it. Pre-specifying removes the judgement call from the moment when judgement is most compromised. + +## 13. Source quality, incentives and management assertions + +Grade every source by proximity to the fact and by incentive: + +| Tier | Sources | Caveat | +|---|---|---| +| 1 | Audited financials, regulator filings and orders (SEBI, RBI, IRDAI, SEC), court/NCLT records, customs data | Still read the notes and the auditor's opinion — Tier 1 is not "unread and trusted" | +| 2 | Concall transcripts, investor presentations, management commentary | **Assertion, not fact.** Tag as A (Section 9) | +| 3 | Rating agency rationales, exchange filings by peers, industry association data | Rating rationales are unusually high-value in India — they contain covenant, pledge and liquidity detail found nowhere else | +| 4 | Paid industry reports, sell-side research | Note who commissioned it; note the coverage incentive | +| 5 | Media, newsletters, social, forums, AI-generated summaries | Zero weight as evidence; useful only as a pointer to a primary source | + +For every critical claim, trace it to the original document rather than to a summary of it. Ask of every source: who paid for this, what is their horizon, what do they gain if I act on it? + +**Score guidance versus delivery.** Pull three to five years of transcripts and compare what management said would happen with what happened — capacity commissioning dates, margin targets, debt reduction promises, capex budgets, subsidiary turnaround timelines. Note whether the *language* changes when results deteriorate (rising abstraction, new adjusted metrics, more time on strategy and less on numbers). This is one of the highest-yield and least-performed checks in equity research, because it is a direct quantified measure of whether this management's forecasts are worth anything. + +**India note:** many Indian companies give no formal numeric guidance, so score qualitative commitments instead — commissioning schedules, capex plans, deleveraging targets, stated dividend policy, promises about monetising a subsidiary. Also weigh: the CARO annexure, the auditor's Key Audit Matters, and whether the concall Q&A allows non-scripted questions from institutions. + +**US/global note:** guidance is explicit and quantitative, so scoring is easier — but so is managing to it. Check whether delivery came from operations or from buybacks, one-time gains, acquisitions and definitional changes to "adjusted" measures. + +Treat expert-network calls and channel checks as **small, biased samples** and record the sample size. Ask whether investor-relations access is shaping the view, and whether the same conclusion survives without it. + +## 14. Knowing when to say no + +Adopt an explicit default of **no**. The idea must clear a written bar — understandable, verifiable from primary sources, adequate margin of safety, better than the weakest existing holding, executable at a sensible size — rather than needing a reason to be rejected. + +Watch for manufactured pressure to act: cash drag, benchmark envy, someone else's winner, a fresh model that "needs" to justify itself, a research budget already spent. Track the pass list and its subsequent performance, but judge each pass on whether it was correct *given what was knowable at the time*, not on the outcome. + +*Why:* there are no called strikes in investing. Inaction is a free option, and the largest source of avoidable underperformance for most investors is doing too much — too many names, too much turnover, too many positions bought because the work was already done. Missing a winner is not a loss; losing capital is. A well-defended "no" pile is a portfolio-level asset. + +For this skill specifically: **"insufficient basis for a verdict" is a legitimate, useful output.** Say it plainly, say exactly what is missing, and say what would change the answer. + +## 15. Pre-mortems and post-mortems + +**Pre-mortem, before concluding.** Assume it is three years later and the position has lost 60%. Write the most likely *story* of how that happened — a concrete causal chain, not a list of risk words. Then ask of each path: is it cheap to monitor? Is it hedgeable? Is it likely enough to change the size or kill the idea outright? + +**Post-mortem, after any position closes — winner or loser.** What was right, what was wrong, and was the error in the *facts*, the *interpretation*, the *sizing*, or the *timing*? Was it a recurring error type? + +Maintain a running tally of your recurring error types and convert each repeat offender into a checklist item. Common ones: overpaying for quality, catching falling knives in structurally declining industries, trusting promotional management, ignoring dilution and stock comp, mis-set peer groups, mistaking cyclical peak earnings for a trend, believing a turnaround before cash flow confirms it. + +*Why:* prospective hindsight — imagining the failure as already having happened — measurably improves risk identification versus asking "what could go wrong", because it forces a causal story instead of a vague list. Post-mortems on *winners* matter as much as on losers: a profitable outcome from a broken process is the most dangerous lesson you can teach yourself, and it is the one that gets repeated at larger size. + +## 16. Anchoring, framing and order effects + +Control the **sequence** of the work. Form a view of the business and its economics before looking at the price, the chart, the analyst target, or any entry cost. When the price is known first — which is often unavoidable — note it explicitly as an anchor in the working file. + +Rules that follow: + +- Purchase price is irrelevant to any hold/exit decision. The only question is whether you would buy at today's price. +- A 60% decline says nothing about cheapness. Refresh the anchor deliberately: re-derive value from current fundamentals, not from the old high. +- Examine absolute cash flows and per-share amounts, not only percentages and multiples; look at nominal debt in crore or millions, not only at ratios. Framing in ratios hides scale; framing in absolutes hides trend. Use both. +- Where practical, review the numbers with the company name and your prior view stripped out, and check whether the same conclusion arrives. + +*Why:* anchors operate below awareness and are not neutralised by knowing about them, so the only real defence is procedural — controlling what you see and in what order. Entry price is the most destructive anchor in practice: it produces both the refusal to sell losers and the reluctance to add to winners. + +## 17. External challenge and echo chambers + +Before any high-conviction conclusion, have the thesis attacked by someone whose job in that conversation is to kill it — and give them **the file, not the pitch**. Require the challenge to be specific and evidence-based, and write down the objections that survive. + +Cultivate at least one genuinely bearish source on the name and engage with them rather than around them. Avoid public commitment before the analysis is complete: once a view is stated to an audience, consistency pressure makes updating feel like a status loss, and investors routinely defend a broken thesis long past the evidence because they defended it in public first. + +Audit your information diet. If everyone you read owns the same names, treat that as a warning, not a confirmation. + +*Why:* self-generated criticism is systematically weaker than adversarial criticism, because you cannot see the assumptions you did not know you were making. + +## 18. Auditing the process itself + +Track process-level statistics, not just returns: + +| Process metric | How to compute | Indicative reading | Why it matters | +|---|---|---|---| +| Hit rate | Share of closed decisions that were profitable | 40-60% is normal and compatible with excellent results | On its own it means nothing; only meaningful alongside win/loss size | +| Win/loss ratio | Average gain on winners ÷ average loss on losers | >1.5x for a concentrated long-only process | A 40% hit rate with 3x asymmetry beats a 70% hit rate with 0.5x | +| Calibration | Predicted probability vs realised frequency, bucketed | 80% calls should happen ~80% of the time | The only direct measure of whether your confidence means anything | +| Contribution by idea source | Return attributed to screen / competitor filing / spin-off / referral | — | Tells you where to spend research time next year | +| Contribution by thesis type | Compounder / cyclical / turnaround / special situation / deep value | — | "I lose money on turnarounds" is far more actionable than an aggregate return | +| Holding period, actual vs intended | Median realised holding period vs stated horizon | Large gap = process not matching stated style | Style drift shows up here before it shows up in returns | +| Turnover cost | Commissions + spread + impact + tax, as % of average capital | India: add STT and short-term capital gains treatment | Activity has a measurable price; most investors never compute it | + +*Ranges are indicative only — they vary by market, strategy, cycle and sample size, and a short sample tells you almost nothing. Compare a metric to your own history before comparing it to any external norm.* + +Audit annually: which idea sources actually produced returns; which thesis types you are demonstrably bad at (candidates for the too-hard pile); whether losses cluster in a sector, a market-cap band, or a behavioural pattern. Then change exactly **one or two things** and record the change with a date, so a future audit can attribute the effect. + +*Why:* returns over any short horizon are dominated by luck and market beta, so judging a process by its P&L is a slow, low-signal and often misleading feedback loop. Process metrics are higher-frequency and attributable. And without a dated record of process changes, you cannot tell improvement from a regime change. + +## 19. Epistemic rules specific to an AI analyst + +These are non-negotiable and specific to how you fail, not how a human fails: + +1. **Never state a company-specific number you have not retrieved.** No estimated revenue, no "approximately" margins, no plausible-looking ratio reconstructed from memory. A fabricated figure that happens to be near-correct is worse than a gap, because it will be trusted and propagated. +2. **Date everything.** Every figure carries an as-of date and a period label (FY25 vs CY25 vs TTM to a specific quarter). Indian fiscal years end 31 March; US filers vary. Mixing periods silently is one of the most common quiet errors. +3. **Distinguish "not disclosed" from "zero" from "not retrieved".** These have entirely different implications. Non-disclosure of a segment, a related-party balance, or a contingent liability is itself evidence. +4. **Cite to the document, not to a summary.** If a number came from a screener, say so and mark it unverified until reconciled to the filing. +5. **Do not let fluency substitute for evidence.** A well-written paragraph and a well-evidenced one are indistinguishable in tone. Tag each claim F / A / E / I (Section 9) while working, and make sure the final verdict rests mostly on F. +6. **Do not resolve conflicts between sources by averaging.** Find out which one is right, or report the conflict as a finding — a discrepancy between the annual report and the vendor is often the most interesting thing on the page. +7. **State units and currency explicitly.** Crore vs lakh vs million vs billion; INR vs USD; and never mix reported and converted figures in one table without labelling the rate and date. +8. **Refuse gracefully.** Where the data is insufficient or the business is outside what can be assessed, say so and stop. Declining is an output, not a failure. +9. **Analysis, not advice.** Present findings, evidence and risks. Do not issue personalised buy/sell/allocation instructions; state clearly that the output is research, not investment advice. + +--- + +# Part B — Price action, technical and timing inputs + +## 20. What the price layer is for + +This layer is **supplementary**. It does not tell you whether a business is good, what it is worth, or whether the accounts are honest — those are settled by Parts 01-16 of this skill. What it legitimately provides is four things: (i) a risk-control frame (volatility, drawdown history, liquidity) that determines whether a correct thesis is survivable; (ii) a timing/staging frame that removes single-point entry guesses; (iii) a *challenge* signal — persistent relative weakness against peers is evidence that someone knows something; and (iv) pre-committed invalidation levels that stop a losing thesis from being rewritten indefinitely. + +The rule for the whole of Part B: **a technical signal never overrides a fundamental conclusion, and a fundamental conclusion never entitles you to ignore a persistent price divergence.** Price gets to force a re-examination. It does not get to make the decision. + +Report these items in a clearly labelled section, separate from the fundamental verdict, so a reader can discard the whole layer without disturbing the analysis. + +## 21. Chart data hygiene + +Before reading anything from a price series, verify it. Almost every wrong technical conclusion is downstream of a corrupted series, and the analyst never discovers the error. + +- Confirm the series is **split- and bonus-adjusted**, and know whether it is price-only or total-return — for a 6% yielder the two diverge enormously over a decade. +- Confirm you are on the **primary listing**, not a thin ADR/GDR or a secondary line, and that currency is consistent throughout. +- Use **log scale** for multi-year charts; linear only for short windows. A linear twenty-year chart makes early percentage moves invisible and late ones look parabolic. +- Check the vendor's handling of spin-offs, reverse splits, ticker changes, scheme-of-arrangement demergers and rights issues. Cross-check two historical points against the company's own filings or the exchange's own bhavcopy/historical data. +- **India:** NSE and BSE prices differ slightly; pick one and stay on it. Adjust for bonus issues, stock splits and rights entitlements; verify the adjustment around any demerger, where vendors frequently leave an artificial gap. + +## 22. Trend and moving-average structure + +Identify the dominant trend on both weekly and daily charts: is price above or below the 50-day and 200-day moving averages, and — more informative than the level — is the 200-day sloping up, flat, or down? Note the sequence of higher highs/higher lows versus lower highs/lower lows. Check whether short-, medium- and long-term timeframes agree; conflict between them is itself information (usually that a change of regime is in progress). + +Treat crossover signals (golden/death cross) as descriptive context, never as triggers. They lag by construction and whipsaw in range-bound markets. + +*Why:* trend is the single most robust thing a chart provides, and the slope of the long-term average is a rough proxy for whether the market's assessment of the business is improving or deteriorating. **The specific value to a fundamental analyst:** a statistically cheap stock in a confirmed downtrend is the classic value-trap setup — cheapness plus a falling 200-day usually means estimates have further to fall, and the multiple is low because the E is wrong. + +## 23. Relative strength vs index and vs sector + +Absolute price movement conflates the company with the market. Plot the **ratio line** — the stock divided by the relevant index — over one, three and five years, and note whether it is making new highs, new lows, or basing. + +Then decompose it in two steps, which answers the question "what do I actually own?": + +1. **Stock vs sector index** — is this a stock-specific story or a sector story? +2. **Sector vs broad index** — is the sector leading or lagging the market? + +Also compare the stock against three to six *named direct competitors* on one normalised chart, using the peer set you built in `references/10-peer-set.md` — not a GICS bucket. A stock breaking down while its peers hold up is a company-specific problem and demands an explanation before you conclude mispricing. The whole group breaking is a sector or macro problem, and the fundamental work should shift accordingly. + +**India:** use the appropriate Nifty sector or thematic index (Bank, IT, Auto, FMCG, Pharma, Metal, PSE, Realty) rather than Nifty 50 alone, and compare a mid- or small-cap against Nifty Midcap 150 / Smallcap 250, because the broad index is dominated by large caps and will misstate relative performance badly. + +*Why:* a stock up 10% in a market up 25% is quietly losing; a stock flat in a market down 20% is quietly winning. Persistent relative weakness ahead of bad news is one of the more reliable warning patterns in equity markets, and it is exactly the signal a fundamental analyst is temperamentally inclined to dismiss. + +## 24. 52-week positioning and momentum + +| Metric | Definition / how to compute | Indicative reading | Why it matters | +|---|---|---|---| +| Distance from 52-week high | (52wk high − price) ÷ 52wk high; note the date the high was set | Within ~10% in a rising trend = leadership; >50% off = repair job | Proximity to highs is a well-documented momentum anchor; investors under-react to good news | +| Distance above 52-week low | (price − 52wk low) ÷ 52wk low | Context only | Distinguishes "basing after a fall" from "still falling" | +| Distance from all-time high | Same, vs the all-time high and its date | A high set 8 years ago changes the story entirely | A multi-year lower high is a business-quality question, not a chart question | +| 1 / 3 / 6 / 12-month total return | Total return including dividends, absolute and relative to index and sector | — | The raw momentum inputs | +| 12-1 momentum | Trailing 12-month return excluding the most recent month | Top/bottom decile of the universe is the meaningful read | The standard cross-sectional momentum measure; skipping the last month avoids short-term reversal | +| Momentum quality | Is momentum backed by rising earnings estimates and delivered results, or by multiple expansion alone? | Earnings-backed is durable; multiple-only is fragile | Tells you what regime will hurt you | + +*All indicative readings vary by market, cycle and period, and mean nothing without comparison to the stock's own history and its sector cohort.* + +Two traps. First, **"down 60% so it must be cheap"** is pure anchoring: percentage decline says nothing about value, and a stock down 60% can fall another 60% (a further 60% decline from there leaves 16% of the original price). Second, momentum is prone to violent reversals at market inflection points — momentum crashes cluster at bear-market bottoms when beaten-down names rip hardest. Know whether your thesis is implicitly a momentum bet. + +## 25. Volume, delivery and the institutional footprint + +Compare volume on up days versus down days over the last four to thirteen weeks. Look for advances on volume above the 50-day average and pullbacks on declining volume; flag the opposite pattern — rallies on thinning volume, declines on expanding volume. Examine volume specifically around earnings, guidance and investor-day dates. + +Technical accumulation/distribution indicators (OBV, A/D line) are noisy proxies. **Ownership filings are the real evidence**, so cross-reference: + +- **US:** 13F quarter-over-quarter changes, number of institutional holders, active vs passive split, Form 4 insider transactions — separating genuine open-market purchases from option exercises and pre-scheduled 10b5-1 sales — and buyback execution disclosed in the 10-Q. +- **India:** the quarterly **shareholding pattern** (promoter, FII/FPI, DII, mutual fund, public — and critically, changes in promoter holding and pledge), **bulk and block deal** disclosures on NSE/BSE, SEBI insider-trading (PIT) disclosures by designated persons, and buyback/open-offer filings. Promoter pledge invocation is a distinctive Indian source of sustained mechanical selling. +- **India-specific volume quality:** the **delivery percentage** (deliverable quantity ÷ traded quantity), published daily by the exchanges. High volume with low delivery is intraday churn and says little; a rising delivery percentage on rising price is a genuinely different signal. There is no direct US equivalent. + +*Why:* volume is the closest thing a chart has to a conviction measure — it shows how much capital was willing to transact at those prices. A breakout on no volume is often a liquidity artifact that fails. Heavy-volume down days indicate a motivated seller, often an institution unwinding a full position, which can cap a stock for months regardless of fundamentals — and knowing that changes entry pacing entirely. + +## 26. Volatility, beta and capture + +| Metric | Definition / how to compute | Indicative range | Why it matters | +|---|---|---|---| +| Realised volatility | Annualised stdev of daily log returns over 30 / 90 / 250 days | Large-cap staples ~15-25%; broad market ~15-20%; small/mid caps and cyclicals 35-60%+ | The primary input to any sizing decision | +| ATR % | Average true range ÷ price | 1-3% daily for liquid large caps; much higher for small caps | Sets how wide any stop must be to avoid noise-triggered exits | +| Implied vol / IV percentile | Option-implied vol vs its own 1-year history | IV percentile >80 = options expensive | Tells you whether the market expects an event, and whether hedging is cheap | +| Beta | Regression of stock returns on index returns, 1 / 3 / 5-year windows | Stability across windows matters more than the level | An unstable beta means the single number is meaningless | +| Up-capture / down-capture | Average stock return in up-index months ÷ index; same for down months | Up-capture > down-capture is the desirable asymmetry | Many stocks capture 80% of downside and 60% of upside — structurally a bad deal that a single beta hides | +| Factor exposures | Sensitivity to market, size, value, quality, momentum; plus rates, oil, FX where relevant | — | Exposes hidden concentration: ten "different" long-duration rate-sensitive growth names are one position | + +*Indicative ranges vary enormously by market, market-cap band, cycle and measurement window; Indian small caps are structurally more volatile than developed-market large caps. Always compare against the stock's own history and its sector cohort first.* + +Sizing a 60%-volatility name like a 15%-volatility name is how a correct thesis still produces an unacceptable outcome. + +## 27. Drawdown history and regime behaviour + +Chart the full drawdown series: maximum peak-to-trough decline, the depth of a typical annual drawdown, and the time to recover each one. Look specifically at behaviour in 2008, 2011, 2013 (India: taper tantrum and the rupee), 2015-16, Q4 2018 (India: the NBFC/IL&FS credit event), March 2020, 2022, and any sector-specific shock. For each decline, ask **what fundamentally caused it and whether that vulnerability still exists** — that question is what converts a chart into analysis. + +Then test regime sensitivity: rising versus falling rates, steepening versus flattening curves, inflation up versus down, risk-on versus risk-off, dollar strength versus weakness, expansion versus recession. For India, add crude oil direction, USD/INR, monsoon and rural demand, and the government capex cycle. Note whether the sensitivity comes from the *business model* or only from the *multiple* — the distinction determines whether it is a permanent or a temporary problem. + +*Why:* the relevant question is not what the stock returns but what you must survive to collect it. A name with a history of 45% drawdowns will produce another one; if that would force a sale for psychological, mandate or leverage reasons, the expected return is not actually available. Correlations also converge in stress, so diversification measured in calm markets is largely illusory. + +## 28. Liquidity, float and tradability + +| Metric | Definition / how to compute | Indicative reading | Why it matters | +|---|---|---|---| +| Average daily traded value | Mean of (price × volume) over 20 and 60 days, in ₹ crore or $m | Judge against intended position size, not an absolute band | Liquidity is the constraint that turns a good idea into an unexecutable one | +| Bid-ask spread | Typical quoted spread as % of price | <0.1% liquid large cap; >1% is a warning | A wide spread is a permanent tax on every entry and exit | +| Free float | Shares outstanding less promoter/insider, government and strategic stakes | India: promoter holding is disclosed quarterly, so float is precisely knowable | Low float amplifies both squeezes and collapses and makes the chart less informative | +| Position as multiple of ADV | Intended position ÷ average daily value | Days-to-exit matters far more than days-to-build | If exiting takes 15 days at 20% of volume, the stop-loss does not exist | +| Passive / index ownership | Index membership and share held by index funds | — | Determines rebalance-driven flow and how the name behaves in an index event | + +**India-specific tradability constraints** — these have no US equivalent and can dominate everything above: + +- **Circuit filters / price bands** (2%, 5%, 10%, 20% depending on the scrip): a locked upper or lower circuit means no exit at any price that day. Serial lower circuits are a genuine liquidity failure, not a technical pattern. +- **Trade-to-trade (T2T) segment**: no intraday netting; every trade must be settled by delivery. Sharply reduces liquidity. +- **ASM / GSM surveillance** (Additional / Graded Surveillance Measure): additional margins, periodic call auctions and trading restrictions. A name under GSM has impaired price formation — treat its chart as uninformative and consider the name too hard. +- **F&O eligibility and ban periods**: when market-wide position limit utilisation exceeds the threshold, the stock enters an F&O ban where only position reduction is allowed, distorting cash-market price. + +## 29. Short interest, crowding and positioning mechanics + +**US/global:** track short interest as a percentage of float and of shares outstanding, its trend, days-to-cover (short interest ÷ ADV), borrow cost and availability, and hedge-fund crowding measures. Distinguish genuine directional shorts from convertible-arb, merger-arb and index-hedge shorting — the latter carry no view on the business. Cross-check against unusual option open interest and skew. + +**India:** there is no equivalent retail-visible short-interest disclosure and the SLB market is thin, so use substitutes — stock futures open interest and its direction relative to price (rising OI with falling price suggests short build-up; falling OI with rising price suggests short covering), the cost of carry / futures basis, options open interest concentration at strikes, FII derivative statistics, and the F&O ban list. Promoter pledge levels are the closest Indian analogue to a forced-selling overhang. + +*Why:* heavy short interest cuts both ways. It can be informed scepticism worth investigating — shorts do real forensic work and are often early — or it can set up violent squeezes that make price completely uninformative about fundamentals for weeks. Either way, crowding tells you the price on the screen may reflect positioning mechanics rather than any view of the business, which is exactly when a fundamental analyst should stop reading the tape as evidence. + +## 30. Event behaviour and non-fundamental flow + +Catalogue the stock's reaction to the last eight to twelve results: average absolute move, direction, whether gaps filled or held, and whether the stock continued to drift in the same direction for the following weeks (post-earnings-announcement drift). Note reactions to guidance changes, investor days and regulatory rulings, and how far ahead of results the stock typically moves. This is the empirical distribution for the single largest recurring risk event you will face while holding — and gaps that *hold* indicate genuine repricing, while gaps that consistently *fill* indicate an overreactive shareholder base. + +Then identify **non-fundamental flow drivers**, because a meaningful share of short-horizon price movement has nothing to do with value: + +- Index additions/deletions and rebalance dates (S&P/MSCI/FTSE; India: Nifty and Sensex reconstitution, MSCI free-float factor changes, which move Indian mid-caps hard). +- Lock-up expiries and offer supply. **India:** IPO anchor-investor lock-ins (staggered 30/90 days) and promoter lock-in, plus minimum-public-shareholding-driven promoter sell-downs and OFS. +- Follow-on offerings, shelf registrations, QIPs, convertible and FCCB issuance, preferential allotments to promoters. +- Buyback blackout windows; December tax-loss selling (US) and March fiscal-year-end effects (India); dividend and bonus record dates. +- Business seasonality — festive season and monsoon in India, holiday quarter in US retail — which must be compared year-on-year, never sequentially. + +Recognising mechanical flow prevents two errors: reading forced buying as validation, and reading forced selling as deterioration. Occasionally it creates the opportunity, when mechanical selling temporarily overwhelms fundamentals. + +## 31. Staged accumulation and invalidation levels + +Before any entry is contemplated, write down: the full intended position size, the number of tranches, and **what specifically triggers each subsequent tranche** — a price level, a time interval, a valuation threshold, or a fundamental milestone such as a confirmed inflection in the metric the thesis depends on. Also write down the conditions under which you will **not** add, and cap the maximum size regardless of how attractive the name looks after a decline. + +Then define **invalidation in fundamental terms first**: "gross margin fails to recover above X by FY27", "net debt/EBITDA exceeds Y", "the top customer is not renewed", "receivable days do not normalise within two quarters". Only after that, translate it into a price or drawdown level if you use one. Size so that hitting the invalidation level costs a pre-defined, acceptable share of capital, using volatility (ATR or realised vol) rather than a fixed percentage — an identical percentage stop is far tighter on a 15%-vol name than on a 55%-vol one. + +Decide in advance whether stops are hard, mental, or **time-based** (a thesis that has not progressed by a stated date is a failed thesis, even if the price has not moved). Be explicit that stops in gapping or illiquid names may fill far away, and in Indian names locked at a lower circuit may not fill at all. + +*Why:* staging converts entry timing from one high-stakes guess into a process, because nobody times bottoms. And a *pre-written* rule is the only thing that distinguishes disciplined averaging from averaging down into a broken thesis — the latter is the most common way a survivable loss becomes a portfolio-damaging one. Without a pre-committed invalidation level, sizing is arbitrary and losing positions get rationalised indefinitely, because the mind reliably rewrites the thesis to fit the price. + +## 32. Price-fundamental divergence: the tape as evidence + +When price disagrees sharply and persistently with the fundamental view — the stock falls steadily while your model and consensus estimates hold — do not resolve it by asserting that the market is wrong. Hunt for what the market might be discounting: + +- credit signals: bond prices, CDS, rating agency outlook changes, commercial paper rollover, and in India the rating rationale and any covenant breach disclosure; +- supplier, customer and competitor results and commentary — the read-across usually arrives before the company's own numbers; +- insider and promoter behaviour, including pledge changes and creeping sell-downs; +- channel checks, hiring/attrition data, app and web traffic, customs and import-export data; +- short reports and litigation dockets; +- whether the divergence is stock-specific or shared by the whole peer group (Section 23). + +Set an explicit rule for how much unexplained relative weakness triggers a formal thesis re-review, and record the outcome of that review either way. + +*Why:* price aggregates many participants' information, some of it better than yours. Dismissing persistent divergence as "the market being wrong" is comfortable and occasionally correct, but it is also the standard prelude to a large permanent loss. The discipline is not to obey the tape — it is to let it force a genuine re-examination with a documented conclusion. + +## 33. Where technicals add value and where they mislead + +Be explicit about the boundary, and state it in the report so no reader over-weights this layer. + +| Use | Verdict | Why | +|---|---|---| +| Trend direction and 200-day slope | **Useful** | Robust, simple, and the single best guard against value traps | +| Cross-sectional momentum (12-1) and relative strength | **Useful** | Among the most persistent documented empirical effects, though prone to crashes at inflections | +| Volatility and drawdown history for sizing | **Useful** | The honest input to how much risk a position actually carries | +| Liquidity, float, days-to-exit, circuit/surveillance status | **Useful** | Hard constraints; they determine whether the idea is executable at all | +| Pre-committed invalidation levels | **Useful** | Enforces a bounded loss and imposes a decision date | +| Volume confirmation and delivery percentage | **Moderately useful** | Directional evidence about conviction; noisy on any single day | +| Support/resistance and base structure | **Moderately useful, partly self-fulfilling** | Levels matter mainly because many holders sit near break-even there, and because many participants act on them | +| Named chart patterns, Fibonacci retracements, Elliott wave counts | **Not useful** | Pattern-matching on noise; the human eye finds structure in random walks | +| Multi-indicator "confluence", short-horizon oscillator signals | **Actively harmful** | Add enough indicators and one always confirms the view you already held | + +Two enforcement rules. **Pre-commit to a small, fixed indicator set before looking at the chart** — adding indicators until one agrees with you is the characteristic failure of this entire discipline. And **score your own technical calls** the same way you score fundamental ones (Section 10); if they show no calibration, delete the layer rather than keep it as decoration. + +--- + +## Checklist + +**Process and epistemics** +- [ ] Wrote the plain-language one-pager (how it makes money, who pays, what must be true, three key variables) before modelling. +- [ ] Confirmed the business is inside the circle of competence; if not, added it to the dated too-hard list with a reason and stopped. +- [ ] Set a depth budget up front and stopped when new work stopped revising the three key variables. +- [ ] Stated the thesis as a falsifiable claim with numbers and dates, and listed the specific disconfirmers with sources. +- [ ] Ran the disconfirming search *first*, and documented one serious attempt to kill the thesis. +- [ ] Wrote the bear case before reading anyone else's; separated verifiable facts from interpretation from rhetoric in any short report. +- [ ] Stated the reference-class base rate and the specific mechanism by which this company beats it. +- [ ] Sanity-checked the terminal implication (required market share in year 10) against industry history. +- [ ] Ran the kill-switch checklist on the name before the long checklist. +- [ ] Normalised every scored factor within sector or against own history; applied vetoes; tested weight sensitivity. +- [ ] Output a valuation range, not a point; used reverse DCF; stressed only the two or three dominant assumptions. +- [ ] Reconciled implied unit economics to something physical. +- [ ] Separated probability from payoff, and capped stated confidence by evidence quality, not narrative strength. +- [ ] Tagged every input F / A / E / I; traced adjusted earnings, net debt, share count and segments to the filing. +- [ ] Scored management guidance-versus-delivery over three to five years (India: qualitative commitments and commissioning dates). +- [ ] Graded every source by proximity and incentive; traced critical claims to the original document. +- [ ] Recorded the decision — including a pass — with thesis, key variables, probability and reversal triggers, before the outcome. +- [ ] Pre-specified what future news counts as thesis-relevant and what is noise. +- [ ] Ran a pre-mortem: the concrete story of a 60% loss three years out. +- [ ] Formed the fundamental view before looking at price, target prices or entry cost; noted any unavoidable anchor. +- [ ] Sought at least one genuinely adversarial reading of the file, not the pitch. +- [ ] Confirmed that "insufficient basis for a verdict" was considered and rejected on evidence, not on effort already spent. +- [ ] Invented no company-specific number; dated and labelled every figure; stated units and currency. + +**Price layer** +- [ ] Verified the price series: split/bonus-adjusted, primary listing, consistent currency, log scale for multi-year. +- [ ] Recorded trend state: price vs 50-day and 200-day, and the 200-day slope. +- [ ] Plotted relative strength vs the broad index, the correct sector index, and named peers. +- [ ] Recorded distance from 52-week and all-time highs, with the dates they were set. +- [ ] Computed 1/3/6/12-month and 12-1 momentum, and judged whether it is earnings-backed or multiple-driven. +- [ ] Checked up/down volume; India: checked delivery percentage; cross-referenced 13F / shareholding pattern, insider and promoter activity, and pledge changes. +- [ ] Recorded realised volatility, ATR%, beta stability and up/down capture. +- [ ] Charted drawdown history and identified the fundamental cause of each, and whether it still applies. +- [ ] Assessed liquidity: ADV, spread, free float, days-to-exit; India: circuit band, T2T, ASM/GSM, F&O ban status. +- [ ] Checked short interest and crowding (India: futures OI, basis, pledge overhang). +- [ ] Reviewed the last eight to twelve earnings reactions and identified pending non-fundamental flow events. +- [ ] Defined invalidation in fundamental terms first, then in price terms; wrote the staging plan and the maximum size cap. +- [ ] Investigated any persistent price-fundamental divergence and documented the conclusion. +- [ ] Used only the pre-committed indicator set; reported the price layer separately from the fundamental verdict and labelled it supplementary. diff --git a/finance/skills/stock-analysis/references/18-forensic-mode.md b/finance/skills/stock-analysis/references/18-forensic-mode.md new file mode 100644 index 00000000..e99c8efd --- /dev/null +++ b/finance/skills/stock-analysis/references/18-forensic-mode.md @@ -0,0 +1,192 @@ +# Forensic mode — runbook + +Use this when: the question is **"can I trust these accounts?"** rather than "is this a good investment?". Triggered by requests like "check if this company is cooking the books", "is the profit real", "run a forensic check", "the cash flow doesn't match the profit", "should I be worried about this company's accounting", or when a Standard/Deep-dive run hits a Stage 3 red flag serious enough that valuation becomes pointless until it is resolved. + +Forensic mode is not a shorter version of the full analysis — it has a different question, a different output and a different verdict scale. You are not producing an investment view. You are producing an opinion on **whether the reported numbers can bear weight**, and if not, which specific numbers are load-bearing and unverified. + +Two disciplines govern everything below, both inherited from `references/07-forensic-red-flags.md` §16: + +- **Never assert fraud.** Describe what the disclosure shows, what it does not let you rule out, and what evidence would resolve it. You are analysing a real company whose reputation is a real thing; an unsupported accusation is both a professional failure and a potential harm. "The cash is fake" is not a finding. "Reported cash earns an implied yield of ~1% against ~6% short rates, which the filings do not explain" is. +- **A single flag is a question; a cluster is a finding.** Most individual anomalies have mundane explanations. What distinguishes a real accounting problem is several independent flags converging on the *same line item*. + +## Contents + +- [When NOT to run this mode](#when-not-to-run-this-mode) +- [Stage F0 — Scope and applicability gate](#stage-f0--scope-and-applicability-gate) +- [Stage F1 — The one-hour triage](#stage-f1--the-one-hour-triage) +- [Stage F2 — Follow the money to the line item](#stage-f2--follow-the-money-to-the-line-item) +- [Stage F3 — Documents and people](#stage-f3--documents-and-people) +- [Stage F4 — Independent verification](#stage-f4--independent-verification) +- [Stage F5 — Quantify the dependency](#stage-f5--quantify-the-dependency) +- [The verdict scale](#the-verdict-scale) +- [Output template](#output-template) +- [Checklist](#checklist) + +## When NOT to run this mode + +Say so plainly rather than producing a weak forensic report: + +- **You cannot obtain the primary filings.** Forensic work on aggregator summaries is not forensic work. Screener data has no notes to accounts, no auditor's report, no related-party disclosure — the places where the answers live. If you only have aggregated financials, run the Stage F1 arithmetic tests, report verdict **U**, and list exactly which documents are needed. +- **The company is a lender or insurer and you are reaching for the generic battery.** Accrual ratios, DSO and cash conversion are undefined or inverted for banks, NBFCs and insurers. Go to the sector translation section below. +- **The user wants a general analysis.** Forensic mode deliberately skips business quality, growth and valuation. If they wanted an investment view, run Standard mode with a forensic pass inside it. + +## Stage F0 — Scope and applicability gate + +1. **Identity and basis.** Which entity, which listing, and — critically — **consolidated or standalone**. Most tunnelling and most hidden leverage live in subsidiaries; a standalone-only forensic pass will miss them by construction. If only standalone is available, say so and treat it as a material limitation. +2. **Sector translation.** Confirm the generic battery applies. See the table below. +3. **Document inventory.** List what you actually have: annual report (which years), auditor's report, notes to accounts, cash flow statements, shareholding pattern, concall transcripts, rating rationales. **Write this list into the output.** A forensic verdict is only as strong as its document base, and the reader must be able to see that base. + +### Sector translation + +| Sector | Generic tests that are undefined or inverted | What replaces them | +|---|---|---| +| Banks, NBFCs | Cash conversion, DSO, accrual ratio, working capital — all meaningless. CFO is dominated by deposit and loan flows | Provisioning adequacy vs slippages, PCR trend vs flat GNPA (reserve release), restructured/written-off pool, RBI divergence disclosure (India), evergreening indicators, Stage-2 migration, related-party lending | +| Insurers | Revenue timing, receivables | Reserve adequacy and prior-year development, actuarial assumption changes, persistency vs reported VNB | +| REITs, InvITs | Earnings-based accrual tests | Fair-value gains vs realised NOI, capitalised leasing costs, AFFO adjustments, related-party asset purchases from the sponsor | +| Miners, oil & gas | Depreciation adequacy | Reserve restatements, capitalised exploration/stripping costs, rehabilitation provision adequacy | +| EPC, infrastructure | Standard revenue tests | Percentage-of-completion assumptions, unbilled revenue growth, claims and arbitration recognised as receivables, retention money ageing | + +## Stage F1 — The one-hour triage + +These six tests are cheap, quantitative, and catch the large majority of distortion cases. Run all six before going deeper. Run `python scripts/ratios.py ` — it computes most of them and raises the warnings automatically. + +| # | Test | Compute | What it means | +|---|---|---|---| +| 1 | **Cash conversion** | Cumulative CFO ÷ cumulative PAT over 5 years | The headline test. Below ~0.8 sustained means profit is not becoming cash. **This is a scoring gate: below 0.5 over 3+ years caps the composite at 4.0** | +| 2 | **Proof of cash** | Investment income ÷ average cash & liquid investments, vs short rates for that currency | An implied yield far below the risk-free rate means the cash is absent, pledged, restricted, or non-interest-bearing. India: include Ind-AS fair-value gains on liquid funds or you manufacture a false flag | +| 3 | **Receivables vs sales** | DSO trend over 5 years; receivables CAGR − revenue CAGR | Revenue that has not been collected is a hypothesis. **Gate: sustained divergence 2+ years caps at 6.0** | +| 4 | **Capex vs depreciation** | Capex ÷ D&A; implied asset life; CWIP ageing | Persistent capex far above depreciation with flat revenue is where deferred costs hide | +| 5 | **Audit opinion** | Opinion type, Key Audit Matters, Emphasis of Matter, IFC/SOX opinion, auditor changes and stated reasons | **Gates: adverse/disclaimer = veto. Qualified = cap 4.0. Resignation without clean reason = cap 4.5** | +| 6 | **Related party and pledge** | RPT as % of revenue; loans/advances to related parties; promoter pledge level and trend (India) | The primary tunnelling route. **Gates: unexplained RPT/diversion = cap 4.5; pledge >50% = cap 4.0** | + +**Before flagging test 1 or 3, rule out the innocent explanation.** A genuinely growing, working-capital-intensive business (distribution, EPC, capital goods) consumes cash while growing — that is arithmetic, not fraud. Compute **working capital as a % of sales**. Stable ratio with a growing absolute number = growth. Rising ratio = the growth is being bought. Write this test into the output whichever way it resolves. + +## Stage F2 — Follow the money to the line item + +If triage raises anything, stop generalising and answer one question: **if profit did not become cash, which asset did it become?** + +Build the five-year bridge — PAT, CFO, capex, FCF, ΔWorking capital, D&A, non-cash items — and attribute the gap to a named balance-sheet line. Each destination routes to a different investigation in `07-forensic-red-flags.md`: + +| Where the profit went | Investigate | Section | +|---|---|---| +| Receivables / unbilled revenue | Revenue recognition, ageing, ECL adequacy, channel stuffing, vendor financing | §3, §4 | +| Inventory | Obsolescence, provisioning, cost absorption into inventory | §4 | +| CWIP / intangibles / capitalised development | Cost capitalisation, useful lives, impairment timing | §5 | +| Loans & advances to related parties | Tunnelling, promoter-group diversion | §9, §10 | +| Goodwill from acquisitions | Purchase accounting, acquisition reserves, serial-acquirer distortion | §6 | +| "Other current assets" | Read the note. This is where unclassifiable claims are parked | §4 | + +Then test the **cluster rule**: are several independent flags pointing at the *same* line item? Rising DSO alone is a question. Rising DSO + shrinking ECL allowance + revenue concentrated in Q4 + a related-party customer is a finding. + +## Stage F3 — Documents and people + +- **Auditor's report in full** — opinion, basis, KAMs/CAMs, Emphasis of Matter, internal-financial-controls opinion. India: the **CARO annexure** forces explicit comment on fund diversion, related-party loans, and end-use of borrowings. Read every clause. +- **Component-auditor coverage** — what % of consolidated revenue, assets and profit is *not* audited by the principal auditor. A high unaudited share in a complex group is a structural concern in itself. +- **Year-over-year redline** — diff this year's disclosure against last year's and hunt specifically for **deletions**. Management highlights additions and never mentions removals. +- **People signals** — map CFO, controller, treasurer, internal-audit head and audit-committee-chair turnover over 5+ years. Serial finance-team churn is among the more reliable pre-restatement tells. Read resignation letters where available. +- **Enforcement and litigation history** — SEBI/SFIO/NFRA (India), SEC comment letters and enforcement (US), restatements, exchange actions. Read short-seller reports as *primary documents to be evaluated*: attribute their claims, verify independently, do not adopt. + +## Stage F4 — Independent verification + +The decisive point, and the reason a filings-only forensic pass has a ceiling: + +> Every major accounting fraud reconciled internally. The balance sheet balanced, the ratios computed, and a competent desk analyst could complete a full checklist without the numbers contradicting each other. Fabricated financials are internally consistent by construction. + +So where the fraud hypothesis is live, attack the specific load-bearing claim with **non-company evidence**: registry and insolvency filings (MCA/ROC, Companies House, EDGAR), customs and shipping records, satellite or street-level imagery for claimed physical assets, employment and hiring data, app/web traffic panels, customer and ex-employee contact, and the charge registry for pledged assets. + +State plainly what you attempted, what you obtained, and what you could not verify. **"Not verified" must never be presented as "verified clean."** + +## Stage F5 — Quantify the dependency + +A forensic pass that ends in a list of flags is unfinished. The useful output is a sentence of this shape: + +> *Roughly X% of reported EBITDA over the last three years depends on capitalisation and one-off treatments the peer group does not use; on a peer-consistent basis EBITDA would be approximately Y.* + +Derive it from disclosed line items and show the working, or state explicitly that it cannot be derived. Never invent it. Then carry the adjusted figures — not the reported ones — into `references/05-returns-and-dupont.md` and `references/06-valuation.md` if the analysis continues. + +## Challenge the verdict before assigning it + +Run `references/20-challenge-pass.md` before you settle on a letter. A forensic verdict is unusually costly to get wrong in **both** directions — a false clean bill misleads someone about to commit money, and a false concern damages a real company — so the adversarial pass is mandatory here rather than recommended. + +Attack in both directions, and say which way you tested: + +- **Against a clean verdict:** what did you not look at? Which document would most likely change the answer? Is "no flags found" actually "no flags searched for"? +- **Against a concerning verdict:** is the innocent explanation stronger than you allowed? Is this a single flag dressed as a cluster? Would a sector specialist call this normal for the industry? + +## The verdict scale + +Assign exactly one. The scale maps to the three severities in `07-forensic-red-flags.md` §16, plus an explicit "insufficient evidence" band that must never be collapsed into "clean". + +| Verdict | Meaning | What it implies | +|---|---|---| +| **A — No material concerns identified** | The triage battery ran on primary documents and surfaced nothing beyond normal accounting variation | Reported figures can bear weight. State which tests were run | +| **B — Aggressive but disclosed** | Permissive but legal and visible choices: generous capitalisation, flattering non-GAAP add-backs, a disclosed tax holiday | Adjust the numbers yourself, show the adjustment, proceed | +| **C — Unexplained anomalies** | A cluster of flags converging on a line item that disclosure does not account for | Raise the required margin of safety materially. State the specific evidence that would resolve it. Not an accusation | +| **D — Structural integrity risk** | Adverse/disclaimer/qualified opinion, auditor resignation, cash-existence KAM, large unaudited group share, Big-R restatement, regulator enforcement, related-party tunnelling | Belongs in the opening line of the report. Sufficient on its own to stop the analysis. Do not rely on reported figures | +| **U — Insufficient evidence** | Primary documents unobtainable; the tests that matter could not be run | **Explicitly not a clean bill.** List the documents required. An unchecked test and a passed test look identical unless you say which is which | + +Report the verdict with its evidence base, never as a bare grade. + +## Output template + +```markdown +# Forensic review — () +**Verdict: