diff --git a/.gemini/skills-index.json b/.gemini/skills-index.json index 1a713e09..63e56474 100644 --- a/.gemini/skills-index.json +++ b/.gemini/skills-index.json @@ -31,7 +31,7 @@ { "name": "cs-backend-engineer", "category": "agent", - "description": "Backend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (read/write ratio + QPS, tenancy, sync vs async, data sensitivity, pattern, RPO/RTO, SLO), picks the language + pattern profile, forks into specialists (api-design-reviewer, database-designer, migration-architect, slo-architect, observability-designer) rather than reimplementing their scope. Forks own context. Invoke via /cs:backend-review or Agent({subagent_type:\"cs-backend-engineer\",...})." + "description": "Backend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (read/write ratio + QPS, tenancy, sync vs async, data sensitivity, pattern, RPO/RTO, SLO), picks the language + pattern profile, forks into specialists (api-design-reviewer, database-designer, migration-architect, observability-designer, slo-architect \u2014 listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context. Invoke via /cs:backend-review or Agent({subagent_type:\"cs-backend-engineer\",...})." }, { "name": "cs-ceo-advisor", @@ -66,12 +66,12 @@ { "name": "cs-frontend-engineer", "category": "agent", - "description": "Frontend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (device, LCP target, rendering, bundle budget, SEO vs auth, design system, WCAG), picks the framework/rendering profile, forks into specialists (a11y-audit, performance-profiler, epic-design, apple-hig-expert, playwright-pro) rather than reimplementing their scope. Forks own context. Invoke via /cs:frontend-review or Agent({subagent_type:\"cs-frontend-engineer\",...})." + "description": "Frontend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (device, LCP target, rendering, bundle budget, SEO vs auth, design system, WCAG), picks the framework/rendering profile, forks into specialists (a11y-audit, apple-hig-expert, epic-design, performance-profiler, playwright-pro \u2014 listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context. Invoke via /cs:frontend-review or Agent({subagent_type:\"cs-frontend-engineer\",...})." }, { "name": "cs-fullstack-engineer", "category": "agent", - "description": "Fullstack-engineering orchestrator. Walks the Matt Pocock 7-question forcing-question grill, runs the deterministic profile picker, then forks into the POWERFUL-tier specialists (api-design-reviewer, database-designer, slo-architect, ci-cd-pipeline-builder, performance-profiler) rather than reimplementing their scope. Forks own context so heavy ingestion does not pollute parent thread. Invoke via /cs:fullstack-review or Agent({subagent_type:\"cs-fullstack-engineer\",...})." + "description": "Fullstack-engineering orchestrator. Walks the Matt Pocock 7-question forcing-question grill, runs the deterministic profile picker, then forks into the POWERFUL-tier specialists (api-design-reviewer, ci-cd-pipeline-builder, database-designer, performance-profiler, slo-architect \u2014 listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context so heavy ingestion does not pollute parent thread. Invoke via /cs:fullstack-review or Agent({subagent_type:\"cs-fullstack-engineer\",...})." }, { "name": "cs-growth-strategist", @@ -1009,7 +1009,7 @@ "description": ">-" }, { - "name": "skills-status", + "name": "skills-status-2", "category": "engineering", "description": "Memory health dashboard showing line counts, topic files, capacity, stale entries, and recommendations." }, diff --git a/.gemini/skills/skills-status-2/SKILL.md b/.gemini/skills/skills-status-2/SKILL.md new file mode 120000 index 00000000..34c41964 --- /dev/null +++ b/.gemini/skills/skills-status-2/SKILL.md @@ -0,0 +1 @@ +../../../engineering-team/self-improving-agent/skills/status/SKILL.md \ No newline at end of file diff --git a/agents/engineering/cs-backend-engineer.md b/agents/engineering/cs-backend-engineer.md index bd1ef503..d3579d27 100644 --- a/agents/engineering/cs-backend-engineer.md +++ b/agents/engineering/cs-backend-engineer.md @@ -1,6 +1,6 @@ --- name: cs-backend-engineer -description: Backend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (read/write ratio + QPS, tenancy, sync vs async, data sensitivity, pattern, RPO/RTO, SLO), picks the language + pattern profile, forks into specialists (api-design-reviewer, database-designer, migration-architect, slo-architect, observability-designer) rather than reimplementing their scope. Forks own context. Invoke via /cs:backend-review or Agent({subagent_type:"cs-backend-engineer",...}). +description: Backend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (read/write ratio + QPS, tenancy, sync vs async, data sensitivity, pattern, RPO/RTO, SLO), picks the language + pattern profile, forks into specialists (api-design-reviewer, database-designer, migration-architect, observability-designer, slo-architect — listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context. Invoke via /cs:backend-review or Agent({subagent_type:"cs-backend-engineer",...}). skills: engineering-team/senior-backend domain: engineering tools: [Read, Write, Bash, Grep, Glob] @@ -84,11 +84,20 @@ The first question kills more bad architecture than any other. Without QPS + rat ### Workflow 3: Cross-agent invocation from `cs-fullstack-engineer` or `cs-cto-advisor` -**Steps:** +See **"When invoked as fork target"** below for the question-skip contract. -1. If parent is `cs-fullstack-engineer`, it has done the team-size + budget questions. Skip to Q1 (QPS), Q3 (sync/async), Q5 (pattern). -2. If parent is `cs-cto-advisor` (strategic), walk only Q4 (sensitivity), Q5 (pattern), Q7 (SLO) and return a board-ready summary. -3. **Return a digest the parent can quote.** +## When invoked as fork target + +When this agent is forked from another orchestrator (rather than invoked directly by a user), assume the parent has already collected the answers in its own grill and skip the redundant questions. Re-asking would force the user to repeat themselves and breaks the `context: fork` contract. + +| Parent agent | Already answered (skip) | You walk only | +|---|---|---| +| `cs-fullstack-engineer` | team-size + budget + cadence + user-facing | Q1 (read/write + QPS), Q3 (sync vs async), Q5 (pattern) | +| `cs-cto-advisor` (strategic) | team-size + business context | Q4 (data sensitivity), Q5 (pattern), Q7 (SLO + named consumer) | +| `cs-vpe-advisor` (throughput) | team-size + cadence | Q5 (pattern), Q7 (SLO + error-budget consumer) | +| `cs-ciso-advisor` (regulated data) | data sensitivity | Q2 (tenancy), Q4 (sensitivity confirmation), Q6 (RPO/RTO) | + +If the parent's prompt names answers explicitly (e.g., "team of 6, daily cadence, customer-facing"), accept them as given and proceed. Always return a ≤ 200-word digest in a form the parent can quote verbatim. ## Karpathy gate (pre-commit) diff --git a/agents/engineering/cs-frontend-engineer.md b/agents/engineering/cs-frontend-engineer.md index f2ef228b..66ab3f1a 100644 --- a/agents/engineering/cs-frontend-engineer.md +++ b/agents/engineering/cs-frontend-engineer.md @@ -1,6 +1,6 @@ --- name: cs-frontend-engineer -description: Frontend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (device, LCP target, rendering, bundle budget, SEO vs auth, design system, WCAG), picks the framework/rendering profile, forks into specialists (a11y-audit, performance-profiler, epic-design, apple-hig-expert, playwright-pro) rather than reimplementing their scope. Forks own context. Invoke via /cs:frontend-review or Agent({subagent_type:"cs-frontend-engineer",...}). +description: Frontend-engineering orchestrator. Walks the 7 Matt Pocock forcing questions (device, LCP target, rendering, bundle budget, SEO vs auth, design system, WCAG), picks the framework/rendering profile, forks into specialists (a11y-audit, apple-hig-expert, epic-design, performance-profiler, playwright-pro — listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context. Invoke via /cs:frontend-review or Agent({subagent_type:"cs-frontend-engineer",...}). skills: engineering-team/senior-frontend domain: engineering tools: [Read, Write, Bash, Grep, Glob] @@ -88,11 +88,19 @@ Do not skip ahead. Do not bundle. The primary device decides every downstream ch ### Workflow 3: Cross-agent invocation from `cs-fullstack-engineer` or `cs-content-creator` -**Steps:** +See **"When invoked as fork target"** below for the question-skip contract. -1. If the parent is `cs-fullstack-engineer`, it has already done the team-size + cadence questions. Skip to Q1 (device), Q3 (rendering), Q7 (WCAG). -2. If the parent is `cs-content-creator` (marketing), default to `astro-or-static` profile — skip to Q4 (bundle) + Q7 (WCAG). -3. **Return a digest the parent can quote verbatim.** +## When invoked as fork target + +When this agent is forked from another orchestrator (rather than invoked directly by a user), assume the parent has already collected the answers in its own grill and skip the redundant questions. Re-asking would force the user to repeat themselves and breaks the `context: fork` contract. + +| Parent agent | Already answered (skip) | You walk only | +|---|---|---| +| `cs-fullstack-engineer` | team-size + cadence + user-facing + budget | Q1 (primary device), Q3 (rendering), Q7 (WCAG + a11y owner) | +| `cs-content-creator` (marketing copy) | brand voice + surface = marketing | Default to `astro-or-static` profile; walk only Q4 (bundle) + Q7 (WCAG) | +| `cs-product-manager` (feature spec) | user persona + surface | Q1 (device), Q2 (LCP target), Q5 (SEO vs auth) | + +If the parent's prompt names answers explicitly (e.g., "mobile-4G primary, LCP target 2000ms"), accept them as given and proceed. Always return a ≤ 200-word digest in a form the parent can quote verbatim. ## Karpathy gate (pre-commit) diff --git a/agents/engineering/cs-fullstack-engineer.md b/agents/engineering/cs-fullstack-engineer.md index 99165c5d..94cb262e 100644 --- a/agents/engineering/cs-fullstack-engineer.md +++ b/agents/engineering/cs-fullstack-engineer.md @@ -1,6 +1,6 @@ --- name: cs-fullstack-engineer -description: Fullstack-engineering orchestrator. Walks the Matt Pocock 7-question forcing-question grill, runs the deterministic profile picker, then forks into the POWERFUL-tier specialists (api-design-reviewer, database-designer, slo-architect, ci-cd-pipeline-builder, performance-profiler) rather than reimplementing their scope. Forks own context so heavy ingestion does not pollute parent thread. Invoke via /cs:fullstack-review or Agent({subagent_type:"cs-fullstack-engineer",...}). +description: Fullstack-engineering orchestrator. Walks the Matt Pocock 7-question forcing-question grill, runs the deterministic profile picker, then forks into the POWERFUL-tier specialists (api-design-reviewer, ci-cd-pipeline-builder, database-designer, performance-profiler, slo-architect — listed alphabetically; workflow order is dependency-driven) rather than reimplementing their scope. Forks own context so heavy ingestion does not pollute parent thread. Invoke via /cs:fullstack-review or Agent({subagent_type:"cs-fullstack-engineer",...}). skills: engineering-team/senior-fullstack domain: engineering tools: [Read, Write, Bash, Grep, Glob] diff --git a/commands/cs-backend-review.md b/commands/cs-backend-review.md index e50e17d9..50f58d3e 100644 --- a/commands/cs-backend-review.md +++ b/commands/cs-backend-review.md @@ -9,6 +9,18 @@ Use the `cs-backend-engineer` agent (uses `context: fork`) to handle this inquir **$ARGUMENTS** +## Forcing-question library + +Canonical source: `engineering-team/skills/senior-backend/references/forcing_questions.md` (7 questions, one-per-turn, recommendation + canon citation per question). + +1. Read/write ratio + one-year p99 QPS +2. Tenancy model (single / shared / isolated multi-tenant) +3. Sync request/response vs async (queue) vs event-driven +4. Data sensitivity tier (public / internal / PII / PHI / PCI) +5. Monolith / modular monolith / microservices (team-size justification) +6. RPO and RTO +7. SLO + named error-budget consumer + ## Routing protocol 1. **Walk the 7 forcing questions** in `engineering-team/skills/senior-backend/references/forcing_questions.md`. One per turn. Recommend with cited canon. Track in `/tmp/backend-grill-.md`. diff --git a/commands/cs-frontend-review.md b/commands/cs-frontend-review.md index e51c2661..6900e124 100644 --- a/commands/cs-frontend-review.md +++ b/commands/cs-frontend-review.md @@ -9,6 +9,18 @@ Use the `cs-frontend-engineer` agent (uses `context: fork`) to handle this inqui **$ARGUMENTS** +## Forcing-question library + +Canonical source: `engineering-team/skills/senior-frontend/references/forcing_questions.md` (7 questions, one-per-turn, recommendation + canon citation per question). + +1. Primary device + network (desktop-fiber / mobile-4G / low-end Android / corporate) +2. LCP target on primary device (milliseconds) +3. Server Components vs SPA vs SSR vs SSG +4. JS bundle budget per route (KB gzipped) +5. SEO-dependent or auth-walled +6. Design-system location (Figma + tokens / ad-hoc Tailwind / headless UI) +7. WCAG target (AA / AAA / best-effort) + accessibility owner + ## Routing protocol 1. **Walk the 7 forcing questions** in `engineering-team/skills/senior-frontend/references/forcing_questions.md`. One per turn. Recommend with cited canon. Track in `/tmp/frontend-grill-.md`. diff --git a/commands/cs-fullstack-review.md b/commands/cs-fullstack-review.md index bd4de70b..120d478c 100644 --- a/commands/cs-fullstack-review.md +++ b/commands/cs-fullstack-review.md @@ -9,6 +9,18 @@ Use the `cs-fullstack-engineer` agent (which uses `context: fork` to keep the pa **$ARGUMENTS** +## Forcing-question library + +Canonical source: `engineering-team/skills/senior-fullstack/references/forcing_questions.md` (7 questions, one-per-turn, recommendation + canon citation per question). + +1. Team size now + 12-month headcount +2. Deployment cadence (per-PR / daily / weekly / quarterly) +3. Customer-facing / internal tool / marketing site +4. One-year p50 + p99 traffic forecast +5. Hiring-against vs training-into the stack +6. Year-one monthly cloud + SaaS budget ceiling +7. Three verifiable success criteria with numeric targets + ## Routing protocol 1. **Walk the 7 forcing questions** in `engineering-team/skills/senior-fullstack/references/forcing_questions.md`. One per turn. Recommend the answer with cited canon. Track in `/tmp/fullstack-grill-.md`. diff --git a/engineering-team/skills/senior-fullstack/SKILL.md b/engineering-team/skills/senior-fullstack/SKILL.md index cfda7b9e..10a8d7d6 100644 --- a/engineering-team/skills/senior-fullstack/SKILL.md +++ b/engineering-team/skills/senior-fullstack/SKILL.md @@ -34,6 +34,34 @@ Use this skill when you hear: ## Tools +### Decision Engine + +Deterministic profile picker. Given four assumptions (team-size, cadence, user-facing, budget) plus optional traffic/sensitivity inputs, ranks the four built-in profiles and returns the matched profile with SLO floor and named approver chain. Refuses to recommend a profile without the four required inputs. + +**Usage:** + +```bash +# See all options +python scripts/fullstack_decision_engine.py --help + +# Run against a sample input +python scripts/fullstack_decision_engine.py --sample + +# Pick a profile from real inputs +python scripts/fullstack_decision_engine.py \ + --team-size-12mo 8 --cadence daily --user-facing true --budget 5000 \ + --traffic-p99-rps 50 --data-sensitivity pii-only + +# JSON output for downstream tools +python scripts/fullstack_decision_engine.py --sample --output json +``` + +Returns: matched profile name, score, matched/violated constraints, stack recommendation, anti-recommendations, SLO floor, named-approver chain, and canon references. + +The engine encodes the same matrix the conversational grill walks through — use it directly when inputs are already known, or via the `cs-fullstack-engineer` agent for the question-by-question grill. + +--- + ### Project Scaffolder Generates fullstack project structures with boilerplate code. diff --git a/engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py b/engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py index 63f77123..56ee8a7c 100644 --- a/engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py +++ b/engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py @@ -107,14 +107,14 @@ def score_profile(profile: dict[str, Any], inputs: Inputs) -> Match: constraints = profile.get("constraints", {}) matched: list[str] = [] violated: list[str] = [] - weight_total = 0.0 - weight_matched = 0.0 + w_total = 0.0 + w_matched = 0.0 def check(label: str, ok: bool, weight: float) -> None: - nonlocal weight_total, weight_matched - weight_total += weight + nonlocal w_total, w_matched + w_total += weight if ok: - weight_matched += weight + w_matched += weight matched.append(label) else: violated.append(label) @@ -139,7 +139,11 @@ def score_profile(profile: dict[str, Any], inputs: Inputs) -> Match: ) if "deployment_cadence" in constraints: target = constraints["deployment_cadence"] - ok = inputs.cadence in target or target in inputs.cadence + # Profile cadences are explicit alternatives joined by "-or-", + # e.g. "weekly-or-on-demand" → {"weekly", "on-demand"}. + # Modifier suffixes like "-with-gates" are stripped for matching. + allowed = {a.split("-with-")[0] for a in target.split("-or-")} + ok = inputs.cadence in allowed check(f"cadence ~ {target}", ok, weight=1.5) if "cloud_budget_monthly_usd_ceiling" in constraints: check( @@ -164,7 +168,7 @@ def score_profile(profile: dict[str, Any], inputs: Inputs) -> Match: weight=1.0, ) - score = weight_matched / weight_total if weight_total > 0 else 0.0 + score = w_matched / w_total if w_total > 0 else 0.0 return Match( profile_name=name, score=score, diff --git a/scripts/sync-gemini-skills.py b/scripts/sync-gemini-skills.py index 0d7e4657..8c2a2633 100644 --- a/scripts/sync-gemini-skills.py +++ b/scripts/sync-gemini-skills.py @@ -72,10 +72,18 @@ def find_skills(repo_root: Path) -> List[Dict]: else: skill_name = skill_dir.name - # Handle duplicates by appending parent name + # Handle duplicates by appending parent name; if that still collides + # (e.g. three sources whose parent dir is "skills"), suffix with -2, -3, ... + # so each entry has a unique name in the index. if skill_name in seen_names: - skill_name = f"{skill_dir.parent.name}-{skill_name}" - + candidate = f"{skill_dir.parent.name}-{skill_name}" + n = 2 + base = candidate + while candidate in seen_names: + candidate = f"{base}-{n}" + n += 1 + skill_name = candidate + seen_names.add(skill_name) # Determine category based on top-level folder