skilldrop-cli 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +413 -0
- package/bin/skilldrop.js +338 -0
- package/model-routing.json +147 -0
- package/package.json +36 -0
- package/packs.json +90 -0
- package/skills/accessibility-audit/SKILL.md +74 -0
- package/skills/accessibility-audit/examples/login-form.md +76 -0
- package/skills/accessibility-audit/manifest.json +11 -0
- package/skills/accessibility-audit/reference.md +69 -0
- package/skills/adr-generator/SKILL.md +49 -0
- package/skills/adr-generator/manifest.json +11 -0
- package/skills/adr-generator/templates/madr.md +56 -0
- package/skills/adr-generator/templates/nygard.md +19 -0
- package/skills/ai-usage-report/SKILL.md +111 -0
- package/skills/ai-usage-report/examples/weekly-engineering-team.md +133 -0
- package/skills/ai-usage-report/manifest.json +11 -0
- package/skills/ai-usage-report/scripts/build_report.py +436 -0
- package/skills/ai-usage-report/templates/report-per-user.md +42 -0
- package/skills/ai-usage-report/templates/report-team-rollup.md +49 -0
- package/skills/ai-usage-report/templates/usage-event-schema.md +76 -0
- package/skills/api-contract-draft/SKILL.md +69 -0
- package/skills/api-contract-draft/manifest.json +11 -0
- package/skills/api-contract-draft/reference.md +73 -0
- package/skills/api-contract-draft/templates/openapi-skeleton.yaml +148 -0
- package/skills/architecture-diagrams/SKILL.md +66 -0
- package/skills/architecture-diagrams/examples/aws-three-tier.md +44 -0
- package/skills/architecture-diagrams/examples/c4-container-saas.md +51 -0
- package/skills/architecture-diagrams/examples/microservices-sequence.md +49 -0
- package/skills/architecture-diagrams/manifest.json +28 -0
- package/skills/architecture-diagrams/templates/c4-container.puml +31 -0
- package/skills/architecture-diagrams/templates/mermaid-aws.md +52 -0
- package/skills/architecture-diagrams/templates/mermaid-flowchart.md +37 -0
- package/skills/architecture-diagrams/templates/mermaid-sequence.md +39 -0
- package/skills/audience-profile/SKILL.md +73 -0
- package/skills/audience-profile/manifest.json +11 -0
- package/skills/audience-profile/reference.md +175 -0
- package/skills/brief-intake/SKILL.md +78 -0
- package/skills/brief-intake/manifest.json +11 -0
- package/skills/brief-intake/templates/brief-adr.md +41 -0
- package/skills/brief-intake/templates/brief-decision-log.md +35 -0
- package/skills/brief-intake/templates/brief-deck.md +43 -0
- package/skills/brief-intake/templates/brief-design-doc.md +48 -0
- package/skills/brief-intake/templates/brief-exec-summary.md +47 -0
- package/skills/brief-intake/templates/brief-generic.md +45 -0
- package/skills/brief-intake/templates/brief-runbook.md +44 -0
- package/skills/brief-intake/templates/brief-tech-comparison.md +38 -0
- package/skills/bug-triage/SKILL.md +67 -0
- package/skills/bug-triage/manifest.json +11 -0
- package/skills/bug-triage/templates/bug-ticket.md +86 -0
- package/skills/business-case/SKILL.md +64 -0
- package/skills/business-case/manifest.json +11 -0
- package/skills/business-case/templates/business-case.md +60 -0
- package/skills/capacity-cost-model/SKILL.md +64 -0
- package/skills/capacity-cost-model/manifest.json +11 -0
- package/skills/capacity-cost-model/reference.md +54 -0
- package/skills/capacity-cost-model/templates/cost-model.md +68 -0
- package/skills/council-review/SKILL.md +106 -0
- package/skills/council-review/examples/redis-cache-decision.md +75 -0
- package/skills/council-review/manifest.json +11 -0
- package/skills/council-review/reference.md +76 -0
- package/skills/council-review/seats/architect.md +29 -0
- package/skills/council-review/seats/bench.md +39 -0
- package/skills/council-review/seats/operator.md +27 -0
- package/skills/council-review/seats/pragmatist.md +29 -0
- package/skills/council-review/seats/security-engineer.md +29 -0
- package/skills/council-review/seats/user-advocate.md +27 -0
- package/skills/council-review/templates/council-review.md +59 -0
- package/skills/data-contract/SKILL.md +67 -0
- package/skills/data-contract/manifest.json +11 -0
- package/skills/data-contract/reference.md +46 -0
- package/skills/data-contract/templates/data-contract.md +69 -0
- package/skills/db-schema-design/SKILL.md +68 -0
- package/skills/db-schema-design/manifest.json +11 -0
- package/skills/db-schema-design/reference.md +56 -0
- package/skills/db-schema-design/templates/schema-design.md +75 -0
- package/skills/decision-log/SKILL.md +67 -0
- package/skills/decision-log/manifest.json +11 -0
- package/skills/deck-builder/SKILL.md +114 -0
- package/skills/deck-builder/examples/exec-board-update.md +108 -0
- package/skills/deck-builder/manifest.json +17 -0
- package/skills/deck-builder/reference.md +92 -0
- package/skills/deck-builder/requirements.txt +1 -0
- package/skills/deck-builder/scripts/build_deck.py +309 -0
- package/skills/deck-builder/templates/deck-spec.json +97 -0
- package/skills/deck-builder/templates/palettes.json +59 -0
- package/skills/design-doc/SKILL.md +49 -0
- package/skills/design-doc/manifest.json +11 -0
- package/skills/design-doc/templates/design-doc.md +98 -0
- package/skills/devils-advocate/SKILL.md +142 -0
- package/skills/devils-advocate/lenses/adversarial-review.md +88 -0
- package/skills/devils-advocate/lenses/edge-cases.md +95 -0
- package/skills/devils-advocate/lenses/future-proofing.md +75 -0
- package/skills/devils-advocate/lenses/test-coverage.md +90 -0
- package/skills/devils-advocate/manifest.json +11 -0
- package/skills/devils-advocate/templates/challenge.md +118 -0
- package/skills/doc-critique/SKILL.md +119 -0
- package/skills/doc-critique/manifest.json +11 -0
- package/skills/doc-critique/rubrics/adr.md +36 -0
- package/skills/doc-critique/rubrics/decision-log.md +39 -0
- package/skills/doc-critique/rubrics/deck.md +45 -0
- package/skills/doc-critique/rubrics/design-doc.md +42 -0
- package/skills/doc-critique/rubrics/exec-summary.md +41 -0
- package/skills/doc-critique/rubrics/generic.md +40 -0
- package/skills/doc-critique/rubrics/runbook.md +42 -0
- package/skills/doc-critique/rubrics/tech-comparison.md +40 -0
- package/skills/doc-critique/templates/critique.md +49 -0
- package/skills/exec-summary/SKILL.md +45 -0
- package/skills/exec-summary/manifest.json +11 -0
- package/skills/exec-summary/templates/exec-summary.md +48 -0
- package/skills/feature-implement-loop/SKILL.md +83 -0
- package/skills/feature-implement-loop/manifest.json +11 -0
- package/skills/figma-diagrams/SKILL.md +85 -0
- package/skills/figma-diagrams/manifest.json +35 -0
- package/skills/figma-diagrams/reference.md +91 -0
- package/skills/figma-diagrams/requirements.txt +1 -0
- package/skills/figma-diagrams/scripts/_figma_client.py +71 -0
- package/skills/figma-diagrams/scripts/frame_to_mermaid.py +102 -0
- package/skills/figma-diagrams/scripts/inspect_file.py +46 -0
- package/skills/figma-diagrams/scripts/list_comments.py +35 -0
- package/skills/figma-diagrams/scripts/post_comment.py +52 -0
- package/skills/figma-diagrams/templates/figjam-import.json +20 -0
- package/skills/guide-builder/SKILL.md +76 -0
- package/skills/guide-builder/examples/local-setup-guide.md +127 -0
- package/skills/guide-builder/manifest.json +11 -0
- package/skills/guide-builder/templates/api-reference.md +120 -0
- package/skills/guide-builder/templates/design-walkthrough.md +72 -0
- package/skills/guide-builder/templates/setup-guide.md +109 -0
- package/skills/incident-comms/SKILL.md +68 -0
- package/skills/incident-comms/manifest.json +11 -0
- package/skills/incident-comms/reference.md +43 -0
- package/skills/incident-comms/templates/messages.md +82 -0
- package/skills/llm-eval-harness/SKILL.md +73 -0
- package/skills/llm-eval-harness/manifest.json +11 -0
- package/skills/llm-eval-harness/reference.md +58 -0
- package/skills/llm-eval-harness/templates/eval-plan.md +63 -0
- package/skills/llm-eval-harness/templates/golden-case.jsonl +5 -0
- package/skills/migration-plan/SKILL.md +68 -0
- package/skills/migration-plan/manifest.json +11 -0
- package/skills/migration-plan/templates/migration-plan.md +68 -0
- package/skills/nfr-spec/SKILL.md +63 -0
- package/skills/nfr-spec/manifest.json +11 -0
- package/skills/nfr-spec/reference.md +74 -0
- package/skills/nfr-spec/templates/nfr-spec.md +56 -0
- package/skills/observability-plan/SKILL.md +70 -0
- package/skills/observability-plan/manifest.json +11 -0
- package/skills/observability-plan/reference.md +67 -0
- package/skills/observability-plan/templates/observability-plan.md +62 -0
- package/skills/okr-cascade/SKILL.md +59 -0
- package/skills/okr-cascade/evals/eval_queries.json +12 -0
- package/skills/okr-cascade/evals/evals.json +28 -0
- package/skills/okr-cascade/manifest.json +11 -0
- package/skills/okr-cascade/templates/okr-cascade.md +46 -0
- package/skills/postmortem-generator/SKILL.md +65 -0
- package/skills/postmortem-generator/manifest.json +11 -0
- package/skills/postmortem-generator/templates/postmortem.md +67 -0
- package/skills/prd-draft/SKILL.md +62 -0
- package/skills/prd-draft/manifest.json +11 -0
- package/skills/prd-draft/templates/prd.md +66 -0
- package/skills/prfaq/SKILL.md +75 -0
- package/skills/prfaq/evals/eval_queries.json +13 -0
- package/skills/prfaq/evals/evals.json +32 -0
- package/skills/prfaq/manifest.json +11 -0
- package/skills/prfaq/templates/prfaq.md +60 -0
- package/skills/release-notes/SKILL.md +61 -0
- package/skills/release-notes/manifest.json +11 -0
- package/skills/release-notes/templates/release-notes.md +83 -0
- package/skills/requirements-interview/SKILL.md +61 -0
- package/skills/requirements-interview/manifest.json +11 -0
- package/skills/requirements-interview/templates/interview-kit.md +63 -0
- package/skills/reverse-architecture/SKILL.md +103 -0
- package/skills/reverse-architecture/manifest.json +11 -0
- package/skills/reverse-architecture/reference.md +150 -0
- package/skills/reverse-architecture/templates/description.md +52 -0
- package/skills/reverse-architecture/templates/extraction.md +55 -0
- package/skills/runbook-generator/SKILL.md +42 -0
- package/skills/runbook-generator/manifest.json +11 -0
- package/skills/runbook-generator/templates/runbook.md +109 -0
- package/skills/slide-outliner/SKILL.md +58 -0
- package/skills/slide-outliner/manifest.json +11 -0
- package/skills/slide-outliner/templates/deck-outline.md +131 -0
- package/skills/sonar-onboard/SKILL.md +170 -0
- package/skills/sonar-onboard/manifest.json +11 -0
- package/skills/sonar-onboard/reference.md +151 -0
- package/skills/sonar-onboard/templates/github-actions-sonar-server.yml.tmpl +50 -0
- package/skills/sonar-onboard/templates/github-actions-sonarcloud.yml.tmpl +53 -0
- package/skills/sonar-onboard/templates/readme-snippet.md +38 -0
- package/skills/sonar-onboard/templates/sonar-project.properties.tmpl +31 -0
- package/skills/sonar-review/SKILL.md +220 -0
- package/skills/sonar-review/lenses/bugs.md +48 -0
- package/skills/sonar-review/lenses/code-smells.md +64 -0
- package/skills/sonar-review/lenses/coverage-and-duplication.md +74 -0
- package/skills/sonar-review/lenses/security-hotspots.md +56 -0
- package/skills/sonar-review/lenses/vulnerabilities.md +52 -0
- package/skills/sonar-review/manifest.json +37 -0
- package/skills/sonar-review/reference.md +167 -0
- package/skills/sonar-review/templates/report.md +84 -0
- package/skills/strategy-analysis/SKILL.md +63 -0
- package/skills/strategy-analysis/evals/eval_queries.json +13 -0
- package/skills/strategy-analysis/evals/evals.json +36 -0
- package/skills/strategy-analysis/manifest.json +11 -0
- package/skills/success-metrics/SKILL.md +63 -0
- package/skills/success-metrics/evals/eval_queries.json +11 -0
- package/skills/success-metrics/evals/evals.json +27 -0
- package/skills/success-metrics/manifest.json +11 -0
- package/skills/success-metrics/templates/metrics-plan.md +55 -0
- package/skills/tech-comparison-matrix/SKILL.md +56 -0
- package/skills/tech-comparison-matrix/manifest.json +11 -0
- package/skills/tech-comparison-matrix/templates/matrix.md +45 -0
- package/skills/test-plan-generator/SKILL.md +59 -0
- package/skills/test-plan-generator/manifest.json +11 -0
- package/skills/test-plan-generator/templates/test-plan.md +83 -0
- package/skills/threat-model/SKILL.md +65 -0
- package/skills/threat-model/examples/document-upload.md +56 -0
- package/skills/threat-model/manifest.json +11 -0
- package/skills/threat-model/reference.md +69 -0
- package/skills/user-journey-map/SKILL.md +64 -0
- package/skills/user-journey-map/evals/eval_queries.json +12 -0
- package/skills/user-journey-map/evals/evals.json +30 -0
- package/skills/user-journey-map/examples/b2b-saas-onboarding.md +69 -0
- package/skills/user-journey-map/manifest.json +11 -0
- package/skills/user-journey-map/templates/journey-map.md +47 -0
- package/skills/user-story-splitter/SKILL.md +88 -0
- package/skills/user-story-splitter/examples/notifications-epic.md +123 -0
- package/skills/user-story-splitter/manifest.json +11 -0
- package/skills/user-story-splitter/templates/story.md +40 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Metrics-plan template
|
|
2
|
+
|
|
3
|
+
One primary. Everything else exists to steer toward it or to catch it lying.
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Success metrics: {feature}
|
|
7
|
+
|
|
8
|
+
**Goal (from PRD):** {the outcome this feature exists to cause}
|
|
9
|
+
**Decision authority:** {role who acts on the decision rule} `[reported]`
|
|
10
|
+
|
|
11
|
+
## Primary metric (exactly one)
|
|
12
|
+
|
|
13
|
+
**Metric:** {outcome the user experiences or the business banks}
|
|
14
|
+
**Why this over {runner-up}:** {one sentence}
|
|
15
|
+
**Proxy?** {no | yes — proxy for {real outcome}; label it as proxy wherever cited}
|
|
16
|
+
|
|
17
|
+
| Baseline | Target | Judged at | Patience window |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| {value + source, or "MILESTONE 1: measure baseline by {date}"} | {value} | {date / days post-launch} | {why not earlier — novelty, weekly cycle, cohort maturity} |
|
|
20
|
+
|
|
21
|
+
## Leading indicators (steering only — they never declare success)
|
|
22
|
+
|
|
23
|
+
| Metric | Moves within | Causal sentence |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| {e.g. % agents opening unified view} | days | {if this doesn't move, primary can't} |
|
|
26
|
+
|
|
27
|
+
## Guardrails (must not degrade)
|
|
28
|
+
|
|
29
|
+
| Metric | Current | Alert threshold | Action on breach |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| {error rate / latency / adjacent conversion / support volume} | {value, or "measure wk 1" for a new surface} | {value} | pause rollout / page owner |
|
|
32
|
+
|
|
33
|
+
## Counter-metric (the gaming catch)
|
|
34
|
+
|
|
35
|
+
**Primary could be gamed by:** {the behavior}
|
|
36
|
+
**Caught by:** {metric + threshold} — reviewed alongside the primary, every review.
|
|
37
|
+
|
|
38
|
+
## Instrumentation plan (launch dependency, not fast-follow)
|
|
39
|
+
|
|
40
|
+
| Event | Properties (incl. slice dimensions) | Fires where | Status |
|
|
41
|
+
|---|---|---|---|
|
|
42
|
+
| `domain.object.action` | {tenant, plan, platform, …} | {surface/service} | exists / **must build** |
|
|
43
|
+
|
|
44
|
+
**Must-build events are launch blockers.** Dashboard: {where} · Owner: {role} · Review cadence: {weekly until judged-at date}
|
|
45
|
+
|
|
46
|
+
## Decision rule (pre-committed — action-shaped)
|
|
47
|
+
|
|
48
|
+
- If {primary condition} at {judged-at} with {adoption/leading condition} → {action}
|
|
49
|
+
- If {primary misses} but {adoption low} → fix adoption first, re-judge at {date}
|
|
50
|
+
- Guardrail breach at any time → {action}
|
|
51
|
+
|
|
52
|
+
## Out of scope for measurement
|
|
53
|
+
|
|
54
|
+
- {what this plan deliberately doesn't measure, and why}
|
|
55
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tech-comparison-matrix
|
|
3
|
+
description: Produce a weighted comparison matrix for a technology selection question (e.g., "Postgres vs DynamoDB", "Kafka vs Kinesis vs RabbitMQ", "Snowflake vs Databricks"). Surfaces criteria, weights, per-option scores, totals, and a recommended pick. Use when the user is choosing between technologies, vendors, frameworks, or architectural approaches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# tech-comparison-matrix
|
|
7
|
+
|
|
8
|
+
You help the user make defensible tech-selection decisions by producing a weighted comparison matrix that they can paste into a design doc, ADR, or steering-committee deck.
|
|
9
|
+
|
|
10
|
+
## How to respond
|
|
11
|
+
|
|
12
|
+
1. **Pin down the question.** Make sure you have:
|
|
13
|
+
- **The options** (2–5 — past 5 the matrix becomes noise; cut the long-shots first)
|
|
14
|
+
- **The use case in one sentence** ("primary OLTP store for a multi-tenant SaaS app, ~10k writes/sec, latency p99 < 50ms")
|
|
15
|
+
- **Hard constraints** (e.g., "must run on-prem", "must be open source", "team has zero ops capacity for self-hosting")
|
|
16
|
+
|
|
17
|
+
Ask at most 2 clarifying questions. If the user only gave you the options without a use case, ask for the use case — it determines the criteria.
|
|
18
|
+
|
|
19
|
+
2. **Pick the criteria.** Default to a balanced set across these axes (8–10 criteria is the sweet spot — fewer feels shallow, more becomes noise):
|
|
20
|
+
|
|
21
|
+
| Axis | Example criteria |
|
|
22
|
+
|---|---|
|
|
23
|
+
| **Capability fit** | Throughput, latency, query model, consistency model, schema flexibility |
|
|
24
|
+
| **Operational** | Self-hosted vs managed, scaling story, backup/restore, observability |
|
|
25
|
+
| **Cost** | License, infrastructure, support, total cost of ownership at scale |
|
|
26
|
+
| **Risk** | Vendor lock-in, ecosystem maturity, hiring market, our team's familiarity |
|
|
27
|
+
|
|
28
|
+
Mention any criteria you intentionally **excluded** so the user can challenge it. ("I left out 'community size' — let me know if that matters for you.")
|
|
29
|
+
|
|
30
|
+
3. **Apply weights.** Use 1–5 (5 = critical to the decision, 1 = nice-to-have). Tie the weights to the use case in writing. *"Latency is weighted 5 because the use case demands sub-50ms p99"* makes the matrix audit-able; bare numbers don't.
|
|
31
|
+
|
|
32
|
+
4. **Score each option per criterion** on a 1–5 scale. Justify every 5 and every 1 in one phrase — the body of the deliverable is the *reasoning*, not the numbers.
|
|
33
|
+
|
|
34
|
+
5. **Total it up.** `Total = sum(weight × score)`. Highest total ≠ automatic winner — if the gap is small (< 5%), call that out and let the user pick on gut feel.
|
|
35
|
+
|
|
36
|
+
6. **Recommend explicitly.** End with a "Recommendation" paragraph: which option, why, and what would change the answer.
|
|
37
|
+
|
|
38
|
+
## Output format
|
|
39
|
+
|
|
40
|
+
Use [`templates/matrix.md`](templates/matrix.md) as the skeleton. The deliverable should fit on **one screen** when rendered — if it doesn't, you have too many criteria.
|
|
41
|
+
|
|
42
|
+
## Quality bar
|
|
43
|
+
|
|
44
|
+
- **Every score has a one-line justification.** A bare "4/5" is not a comparison.
|
|
45
|
+
- **Tie scores are fine** — don't force differentiation that isn't there.
|
|
46
|
+
- **The recommendation is one sentence, not a paragraph of hedging.**
|
|
47
|
+
- **Show your weights** — a matrix with hidden weights is just an opinion.
|
|
48
|
+
- **No false precision.** If a number is a guess, say "rough" or "directional".
|
|
49
|
+
|
|
50
|
+
## Anti-patterns to avoid
|
|
51
|
+
|
|
52
|
+
- ❌ Scoring every criterion 3/5 ("balanced") — the matrix exists to differentiate, not to be polite.
|
|
53
|
+
- ❌ Picking criteria that all favour the option you secretly want to win.
|
|
54
|
+
- ❌ Including "community popularity" as a top-weighted criterion when the use case doesn't care.
|
|
55
|
+
- ❌ Recommending an option whose score wasn't highest, without explaining the override.
|
|
56
|
+
- ❌ Inventing benchmarks. If you don't have a number, say "estimated" and source the estimate.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tech-comparison-matrix",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Produce a weighted comparison matrix for a technology selection question (e.g., \"Postgres vs DynamoDB\", \"Kafka vs Kinesis vs RabbitMQ\", \"Snowflake vs Databricks\"). Surfaces criteria, weights, per-option scores, totals, and a recommended pick. Use when the user is choosing between technologies, vendors, frameworks, or architectural approaches.",
|
|
5
|
+
"entrypoint": "SKILL.md",
|
|
6
|
+
"deps": { "npm": [], "pip": [] },
|
|
7
|
+
"env": { "required": [], "optional": [] },
|
|
8
|
+
"related": [],
|
|
9
|
+
"tags": ["decisions", "comparison", "tech-selection", "vendor-evaluation"],
|
|
10
|
+
"model": { "tier": "heavy", "rationale": "Weighted multi-criteria judgment with a recommendation. Mis-weighting is the failure mode. Never downgrade." }
|
|
11
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# {Decision title — e.g. "Primary OLTP datastore for ProjectX"}
|
|
2
|
+
|
|
3
|
+
**Use case:** {one sentence describing the workload / constraints — this is what the weights are tuned to}
|
|
4
|
+
|
|
5
|
+
**Hard constraints:** {bulleted list of things that must be true; an option failing any of these is eliminated, not scored}
|
|
6
|
+
|
|
7
|
+
**Options evaluated:** {Option A}, {Option B}, {Option C}
|
|
8
|
+
**Options excluded (and why):** {e.g. "MongoDB — single-region writes only, fails the multi-region constraint"}
|
|
9
|
+
|
|
10
|
+
## Scoring scheme
|
|
11
|
+
|
|
12
|
+
- **Weight (1–5):** how much this criterion matters for *this* use case. Justified inline.
|
|
13
|
+
- **Score (1–5):** how well the option meets the criterion. Each 5 and 1 has a one-line justification.
|
|
14
|
+
|
|
15
|
+
## Matrix
|
|
16
|
+
|
|
17
|
+
| Criterion | Weight | {Option A} | {Option B} | {Option C} |
|
|
18
|
+
|---|---:|---:|---:|---:|
|
|
19
|
+
| Throughput (writes/sec at p99 < 50ms) — *weight 5: directly stated in use case* | 5 | 5 — published bench 50k/s | 3 — caps around 15k/s | 4 — 30k/s with read replicas |
|
|
20
|
+
| Consistency model fit — *weight 5: financial data, no eventual consistency tolerated* | 5 | 5 | 2 — eventual by default | 5 |
|
|
21
|
+
| Operational complexity (self-hosted) — *weight 4: team has 1 SRE* | 4 | 3 | 4 — fully managed | 2 — manual sharding |
|
|
22
|
+
| Cost at projected scale — *weight 3: budget approved but not unlimited* | 3 | 4 | 2 — egress fees | 5 |
|
|
23
|
+
| Team familiarity — *weight 3: shortens ramp* | 3 | 5 | 2 | 3 |
|
|
24
|
+
| Vendor lock-in — *weight 2: prefer portable but not blocking* | 2 | 5 — open source | 2 — proprietary | 4 |
|
|
25
|
+
| Ecosystem / tooling — *weight 2* | 2 | 5 | 4 | 3 |
|
|
26
|
+
| Backup & restore story — *weight 4: compliance requirement* | 4 | 4 | 5 | 3 |
|
|
27
|
+
| **Weighted total** | | **{=Σ w·s}** | **{=Σ w·s}** | **{=Σ w·s}** |
|
|
28
|
+
|
|
29
|
+
## Justifications for outlier scores
|
|
30
|
+
|
|
31
|
+
- *{Option A}, Throughput = 5:* {one-line evidence — link to vendor bench, internal load test, or known reference deployment}
|
|
32
|
+
- *{Option B}, Consistency = 2:* {one-line evidence}
|
|
33
|
+
- *{Option C}, Operational complexity = 2:* {one-line evidence}
|
|
34
|
+
|
|
35
|
+
## Recommendation
|
|
36
|
+
|
|
37
|
+
**Pick {Option X}** — it's strongest on the two highest-weighted criteria (throughput + consistency) and acceptable on the rest. The gap to {next option} is meaningful (~{N}%), so this is not a close call.
|
|
38
|
+
|
|
39
|
+
**What would change this answer:**
|
|
40
|
+
- If managed-ness becomes the top constraint (e.g., SRE leaves), reconsider {Option B}.
|
|
41
|
+
- If we relax the latency target above 100ms, {Option C} becomes viable and cheaper.
|
|
42
|
+
|
|
43
|
+
## Open questions
|
|
44
|
+
|
|
45
|
+
- {Question for stakeholders — e.g., "Is multi-region active-active in scope for v1, or v2+?"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-plan-generator
|
|
3
|
+
description: Generate a risk-based test plan for a feature, PR, or release — risks ranked by likelihood × impact, test cases pushed to the lowest pyramid level that catches the failure, every acceptance criterion mapped to a test, and an explicit "not tested" list. Use when the user asks for a test plan, test cases, a QA strategy for a change, "how should we test this", or pre-release test coverage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# test-plan-generator
|
|
7
|
+
|
|
8
|
+
Produces a test plan that says what to test *first*, what to test *where* (unit vs integration vs e2e), and — the part most plans omit — what is deliberately not tested and why. Downstream of `user-story-splitter` (its ACs map straight into the coverage table); sibling of `feature-implement-loop` (which writes the tests this plan prioritizes).
|
|
9
|
+
|
|
10
|
+
## How to respond
|
|
11
|
+
|
|
12
|
+
1. **Ingest the change.** Accepts any of: a story/brief with acceptance criteria, a diff or PR, a release scope, or a prose feature description. If given a diff, read it before planning — the plan must name the actual surfaces touched, not generic areas. Ask at most 2 clarifying questions; tag every other unknown `[assumption]`.
|
|
13
|
+
|
|
14
|
+
2. **Rank risks before writing a single test case.** Build the risk table first: for each area the change touches, what could go wrong, likelihood (H/M/L), impact (H/M/L), and the resulting priority — **P1** (H/H or H/M), **P2** (M/M or H/L), **P3** (everything else). Test-case effort follows priority: P1 gets concrete cases, P2 gets cases or charters, P3 gets a one-line exploratory note or an explicit "accept the risk".
|
|
15
|
+
|
|
16
|
+
3. **Push each test to the lowest pyramid level that can catch the failure.** Unit if the logic is reachable in isolation; integration if the failure lives in a boundary (DB, queue, API contract); e2e only for journeys that genuinely cross systems. ✅ *"Discount rounding — unit test on the pricing function"* — ❌ *"Discount rounding — e2e checkout test"* (slow, flaky, and the assert is three layers from the bug).
|
|
17
|
+
|
|
18
|
+
4. **Map every acceptance criterion to at least one test case.** Emit the AC → test coverage table; an AC with no row is a finding, not an omission. Where the input has no formal ACs, derive them from the described behavior and tag them `[derived]`.
|
|
19
|
+
|
|
20
|
+
5. **Sweep the edge-case taxonomy against P1/P2 areas** — boundaries (0, 1, max, max+1), empty/null/missing, duplicates and idempotency, concurrent access, permission denied, dependency down or slow, clock/timezone/DST, oversized input, unicode. Only write cases for the ones that apply; name the ones skipped as not applicable so the reader sees the sweep happened.
|
|
21
|
+
|
|
22
|
+
6. **Write observable entry/exit criteria.** Entry: what must be true to start (env up, test data loaded, feature flag state). Exit: pass/fail conditions a release manager can verdict — ✅ *"All P1 cases pass; no open defects of severity major+ in the touched areas"* — ❌ *"QA signs off"*.
|
|
23
|
+
|
|
24
|
+
7. **Emit the plan with [`templates/test-plan.md`](templates/test-plan.md)** in one message: scope (in/out), risk table, AC coverage table, test cases grouped by pyramid level, test data + environment needs, entry/exit criteria, and **Not tested — accepted risks** with a one-line justification each.
|
|
25
|
+
|
|
26
|
+
## Useful references in this skill
|
|
27
|
+
|
|
28
|
+
- [`templates/test-plan.md`](templates/test-plan.md) — the full plan skeleton with the risk and coverage tables
|
|
29
|
+
|
|
30
|
+
## Quality bar
|
|
31
|
+
|
|
32
|
+
- **Risk table precedes test cases, and effort tracks priority.** A plan that gives equal depth to every area was written by coverage habit, not risk.
|
|
33
|
+
- **Every test case has a concrete expected result.** ✅ *"Then the response is 422 with error code `DUPLICATE_SKU`"* — ❌ *"Then an appropriate error is shown"*.
|
|
34
|
+
- **Every AC appears in the coverage table.** Uncovered ACs are listed as gaps at the top of the plan, never silently absent.
|
|
35
|
+
- **The "Not tested" section is non-empty.** A plan that tests everything is a plan that prioritized nothing — naming accepted risks is the deliverable.
|
|
36
|
+
- **Pyramid placement is justified by failure location**, not by what's easiest to write. Each e2e case states why no lower level could catch it.
|
|
37
|
+
|
|
38
|
+
## When to use this skill
|
|
39
|
+
|
|
40
|
+
- ✅ A feature/story is ready for test planning before or during implementation
|
|
41
|
+
- ✅ A PR or release needs a documented QA pass and exit criteria
|
|
42
|
+
- ✅ "How should we test this?" for a risky change (migration, payment flow, auth)
|
|
43
|
+
- ✅ Turning `user-story-splitter` output into a test strategy for the sprint
|
|
44
|
+
|
|
45
|
+
## When NOT to use this skill
|
|
46
|
+
|
|
47
|
+
- ❌ Writing the test code itself — hand the plan to `feature-implement-loop` or a human
|
|
48
|
+
- ❌ Adversarial review of code already written — that's `devils-advocate`
|
|
49
|
+
- ❌ Static-analysis or quality-gate findings — that's `sonar-review`
|
|
50
|
+
- ❌ A trivial change (typo, copy edit) — the plan would cost more than the risk
|
|
51
|
+
|
|
52
|
+
## Anti-patterns to avoid
|
|
53
|
+
|
|
54
|
+
- ❌ **Coverage theater.** Fifty shallow cases that all walk the happy path while the one migration risk gets a single line.
|
|
55
|
+
- ❌ **"Verify it works correctly" as an expected result.** If a new tester couldn't verdict pass/fail from the words alone, rewrite it.
|
|
56
|
+
- ❌ **Everything at e2e level.** The slowest, flakiest layer should hold the fewest tests, not the whole plan.
|
|
57
|
+
- ❌ **Omitting the not-tested list** because it feels like admitting weakness. Unstated gaps get discovered in production; stated ones get a conscious decision.
|
|
58
|
+
- ❌ **Test data as an afterthought.** "Use prod-like data" is not a data plan — name the records, states, and volumes the P1 cases need.
|
|
59
|
+
- ❌ **Exit criteria that name people instead of conditions.** Sign-off follows the criteria; it isn't one.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "test-plan-generator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Generate a risk-based test plan for a feature, PR, or release — risks ranked by likelihood × impact, test cases pushed to the lowest pyramid level that catches the failure, every acceptance criterion mapped to a test, and an explicit \"not tested\" list. Use when the user asks for a test plan, test cases, a QA strategy for a change, \"how should we test this\", or pre-release test coverage.",
|
|
5
|
+
"entrypoint": "SKILL.md",
|
|
6
|
+
"deps": { "npm": [], "pip": [] },
|
|
7
|
+
"env": { "required": [], "optional": [] },
|
|
8
|
+
"related": ["devils-advocate", "feature-implement-loop", "sonar-review", "user-story-splitter"],
|
|
9
|
+
"tags": ["testing", "test-plan", "qa", "risk-based", "test-cases", "quality"],
|
|
10
|
+
"model": { "tier": "standard", "rationale": "Synthesizes a structured plan from a change description. Risk ranking needs judgment but is bounded; escalate via ambiguous-input on contested or high-stakes releases." }
|
|
11
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Test plan template
|
|
2
|
+
|
|
3
|
+
Sections in the order a reviewer reads them: what's at stake first, cases later. Keep every section; an empty one gets a stated reason, not deletion.
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Test plan: {feature / PR / release name}
|
|
7
|
+
|
|
8
|
+
**Source:** {story ID, PR link, or brief}
|
|
9
|
+
**Date:** {YYYY-MM-DD}
|
|
10
|
+
[assumption] {any defaults picked; omit if none}
|
|
11
|
+
|
|
12
|
+
## Coverage gaps found in the input
|
|
13
|
+
|
|
14
|
+
{ACs with no testable behavior, contradictions, missing error specs — or "none".}
|
|
15
|
+
|
|
16
|
+
## Scope
|
|
17
|
+
|
|
18
|
+
**In scope:** {surfaces this plan covers}
|
|
19
|
+
**Out of scope:** {touched-adjacent areas deliberately excluded} → see "Not tested"
|
|
20
|
+
|
|
21
|
+
## Risk table
|
|
22
|
+
|
|
23
|
+
| Area | What could go wrong | Likelihood | Impact | Priority |
|
|
24
|
+
|---|---|---|---|---|
|
|
25
|
+
| {surface} | {failure mode, specific} | H/M/L | H/M/L | P1/P2/P3 |
|
|
26
|
+
|
|
27
|
+
## Acceptance-criteria coverage
|
|
28
|
+
|
|
29
|
+
| AC | Test case(s) | Level |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| AC1 {short text} | TC-1, TC-4 | unit / integration / e2e |
|
|
32
|
+
| AC2 `[derived]` {…} | TC-2 | … |
|
|
33
|
+
|
|
34
|
+
## Test cases
|
|
35
|
+
|
|
36
|
+
### Unit
|
|
37
|
+
|
|
38
|
+
- **TC-1 (P1)** — {name}
|
|
39
|
+
- Given {…} When {…} Then {concrete expected result}
|
|
40
|
+
|
|
41
|
+
### Integration
|
|
42
|
+
|
|
43
|
+
- **TC-4 (P1)** — {name}
|
|
44
|
+
- Setup: {fixture / contract state}
|
|
45
|
+
- Steps: {…}
|
|
46
|
+
- Expected: {observable result, exact codes/values}
|
|
47
|
+
|
|
48
|
+
### End-to-end
|
|
49
|
+
|
|
50
|
+
- **TC-7 (P1)** — {journey name}
|
|
51
|
+
- Why e2e: {the cross-system failure no lower level catches}
|
|
52
|
+
- Steps / Expected: {…}
|
|
53
|
+
|
|
54
|
+
### Exploratory charters (P2/P3)
|
|
55
|
+
|
|
56
|
+
- **CH-1** — Explore {area} for {risk}; timebox {30–60 min}; note anything where {tripwire}.
|
|
57
|
+
|
|
58
|
+
## Test data
|
|
59
|
+
|
|
60
|
+
| Need | Detail |
|
|
61
|
+
|---|---|
|
|
62
|
+
| {record/state} | {exact shape, volume, how created or seeded} |
|
|
63
|
+
|
|
64
|
+
## Environment & flags
|
|
65
|
+
|
|
66
|
+
{Env, feature-flag states, third-party sandbox/stub mode.}
|
|
67
|
+
|
|
68
|
+
## Entry criteria
|
|
69
|
+
|
|
70
|
+
- {observable precondition}
|
|
71
|
+
|
|
72
|
+
## Exit criteria
|
|
73
|
+
|
|
74
|
+
- All P1 cases pass.
|
|
75
|
+
- {defect threshold, e.g. "no open major+ defects in touched areas"}
|
|
76
|
+
- {anything else a release manager can verdict without interpretation}
|
|
77
|
+
|
|
78
|
+
## Not tested — accepted risks
|
|
79
|
+
|
|
80
|
+
| Skipped | Why acceptable |
|
|
81
|
+
|---|---|
|
|
82
|
+
| {area or taxonomy item} | {one line: low likelihood/impact, covered elsewhere, or cost > risk} |
|
|
83
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: threat-model
|
|
3
|
+
description: Produce a STRIDE threat model from a design doc, architecture description, or feature spec — assets and trust boundaries first, threats anchored to boundary crossings with concrete attack scenarios, severity-ranked with verifiable mitigations. Use when the user asks to threat-model a design, run a security review of an architecture, ask "how could this be attacked", or needs security sign-off input before build.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# threat-model
|
|
7
|
+
|
|
8
|
+
Finds the attacks a design permits *before* the code exists, when fixes are a diagram edit instead of a migration. Design-phase counterpart to `devils-advocate` (which attacks written code); consumes `design-doc` or `reverse-architecture` output directly. Threats live where data crosses a trust boundary — the model is anchored there, not in a generic checklist.
|
|
9
|
+
|
|
10
|
+
## How to respond
|
|
11
|
+
|
|
12
|
+
1. **Establish the system before any threats.** From the input, extract and state:
|
|
13
|
+
- **Assets** — what an attacker wants (credentials, PII, payment data, compute, availability), ranked by damage-if-lost
|
|
14
|
+
- **Entry points** — every way data or commands get in (APIs, queues, file uploads, admin panels, CI/CD, third-party webhooks)
|
|
15
|
+
- **Trust boundaries** — every line where the trust level changes (internet→edge, service→service, app→DB, human→system, tenant→tenant)
|
|
16
|
+
Ask at most 2 questions, and spend them on trust boundaries — misplaced boundaries invalidate the whole model. Tag everything else `[assumption]`.
|
|
17
|
+
|
|
18
|
+
2. **Enumerate boundary crossings, then run STRIDE per crossing** using the question banks in [`reference.md`](reference.md) — Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. Not every category applies at every crossing; say "n/a" with one word of why rather than padding.
|
|
19
|
+
|
|
20
|
+
3. **Write each threat as a concrete attack scenario**: actor → path → result. ✅ *"A tenant crafts a report name containing `../`, the export service writes to another tenant's S3 prefix, cross-tenant data exposure"* — ❌ *"Path traversal is possible"*. A threat that can't be narrated as a scenario isn't understood yet.
|
|
21
|
+
|
|
22
|
+
4. **Severity-rank with the shared markers** — 🟥 critical (unauthenticated or cross-tenant compromise of a top asset), 🟧 high (authenticated bypass, single-tenant data exposure), 🟨 medium (requires chaining or insider position), ⚪ low/accepted. Likelihood × impact, judged against *this* system's assets — not CVSS theater. If everything is 🟥, the ranking failed.
|
|
23
|
+
|
|
24
|
+
5. **Assess existing mitigations honestly** before recommending new ones. Each threat gets: what already mitigates it (and whether that's verified or assumed), then the recommended mitigation with a **verification step** — ✅ *"Presigned URLs scoped to tenant prefix; verify with a cross-tenant fetch test in CI"* — ❌ *"Use proper access controls"*.
|
|
25
|
+
|
|
26
|
+
6. **Force the insider and authz passes.** Two systematic blind spots, swept explicitly: what can a *legitimate authenticated user* do to another tenant or to escalate (authn is not authz), and what can a malicious or compromised insider/CI-token do. One finding or an explicit all-clear for each.
|
|
27
|
+
|
|
28
|
+
7. **Emit the model in one message**: system summary (assets / entry points / boundaries), findings grouped by severity, the n/a ledger, **assumptions**, **out of scope**, and **questions for the team** — the unknowns that block a finding from being confirmed or dismissed. End with the revisit trigger: the model is stale when a new entry point, boundary, or asset class appears.
|
|
29
|
+
|
|
30
|
+
## Useful references in this skill
|
|
31
|
+
|
|
32
|
+
- [`reference.md`](reference.md) — STRIDE question banks per boundary type + common-mitigation table
|
|
33
|
+
- [`examples/document-upload.md`](examples/document-upload.md) — worked example: upload feature → 6 ranked findings
|
|
34
|
+
|
|
35
|
+
## Quality bar
|
|
36
|
+
|
|
37
|
+
- **Every threat is anchored** to a named trust-boundary crossing or asset. An unanchored finding is checklist residue — cut it.
|
|
38
|
+
- **Every threat narrates a scenario** with actor, path, and result. "X is possible" is not a finding.
|
|
39
|
+
- **Severity spread is honest.** A model where everything is critical (or nothing is) hasn't ranked anything; the 🟥 set is what you'd halt the build for.
|
|
40
|
+
- **Every recommended mitigation has a verification step** a reviewer can run or check. Advice without verification is a wish.
|
|
41
|
+
- **Existing mitigations are credited** — and marked verified vs assumed. A model that ignores what the design already does right teaches the team to ignore the model.
|
|
42
|
+
- **The insider and authz sweeps produced output** — findings or an explicit reasoned all-clear, never silence.
|
|
43
|
+
|
|
44
|
+
## When to use this skill
|
|
45
|
+
|
|
46
|
+
- ✅ A design doc or RFC needs security scrutiny before implementation starts
|
|
47
|
+
- ✅ "How could this be attacked?" for a new feature, integration, or entry point
|
|
48
|
+
- ✅ Input for a formal security review / sign-off gate
|
|
49
|
+
- ✅ A `reverse-architecture` extraction of a legacy system that never had a threat model
|
|
50
|
+
|
|
51
|
+
## When NOT to use this skill
|
|
52
|
+
|
|
53
|
+
- ❌ Reviewing written code for vulnerabilities — that's `devils-advocate` (its security lens) or `sonar-review`
|
|
54
|
+
- ❌ Compliance attestation (SOC2, PCI evidence) — this models attacks, it doesn't certify controls
|
|
55
|
+
- ❌ Incident analysis after an exploit — that's `postmortem-generator`
|
|
56
|
+
- ❌ Pen-testing a live system — this is paper analysis; it tells the pen test where to aim
|
|
57
|
+
|
|
58
|
+
## Anti-patterns to avoid
|
|
59
|
+
|
|
60
|
+
- ❌ **OWASP-checklist dumping** — twenty generic items ("ensure input validation") untied to any boundary in *this* system. Volume isn't rigor.
|
|
61
|
+
- ❌ **Stopping at authentication.** "Users must log in" answers spoofing only; the authz pass (tenant→tenant, user→admin) is where real findings live.
|
|
62
|
+
- ❌ **"Use encryption" as a mitigation.** Of what, where, against which threat? Encryption at rest does nothing for a tampered request in flight.
|
|
63
|
+
- ❌ **Modeling only the happy architecture.** Admin panels, CI/CD pipelines, support tooling, and webhook receivers are entry points — usually the softest ones.
|
|
64
|
+
- ❌ **Inflating severity to be taken seriously.** One cried-wolf 🟥 and the next model gets skimmed.
|
|
65
|
+
- ❌ **One-and-done modeling.** A threat model without a revisit trigger expires silently the first time the design changes.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Worked example — document-upload feature → 6 ranked findings
|
|
2
|
+
|
|
3
|
+
## Input (design-doc excerpt, verbatim)
|
|
4
|
+
|
|
5
|
+
> New feature: customers upload contract PDFs for e-signing. Browser gets a presigned S3 URL from `upload-api` (authenticated), uploads directly to the `contracts` bucket, then `upload-api` enqueues a message; `doc-processor` consumes it, runs OCR via a third-party API, and writes extracted text to Postgres. Support staff can view any customer's documents in the admin panel to help with signing issues. Multi-tenant SaaS, tenant ID in the JWT.
|
|
6
|
+
|
|
7
|
+
## Output
|
|
8
|
+
|
|
9
|
+
### System summary
|
|
10
|
+
|
|
11
|
+
**Assets (ranked):** customer contracts (legal PII — top asset), extracted contract text in Postgres, S3 credentials / presigned-URL minting capability, OCR API key.
|
|
12
|
+
**Entry points:** `upload-api` (authn'd HTTP), direct browser→S3 upload, SQS queue into `doc-processor`, third-party OCR API responses, admin panel.
|
|
13
|
+
**Trust boundaries:** internet→upload-api, internet→S3 (presigned), upload-api→queue→doc-processor, doc-processor→OCR vendor (data leaves our trust domain), doc-processor→Postgres, support-staff→admin panel, tenant→tenant throughout.
|
|
14
|
+
[assumption] Presigned URLs are PUT-only. [assumption] OCR vendor is contractually approved for PII.
|
|
15
|
+
|
|
16
|
+
### Findings
|
|
17
|
+
|
|
18
|
+
**🟥 TM-1 — Cross-tenant document read via unscoped presigned URLs** (boundary: internet→S3; STRIDE: I, E)
|
|
19
|
+
Scenario: a tenant inspects their presigned URL, finds object keys are `contracts/{uuid}.pdf` with no tenant prefix; any later GET-capable URL or a key-guessing bug exposes other tenants' contracts — compromise of the top asset.
|
|
20
|
+
Existing mitigation: none stated in the design. Recommended: keys become `contracts/{tenant_id}/{uuid}.pdf`, minted only from the JWT's tenant claim, GET URLs scoped to prefix and ≤5 min. **Verify:** CI test fetches tenant B's key with tenant A's session — must 403.
|
|
21
|
+
|
|
22
|
+
**🟥 TM-2 — Malicious file detonates in doc-processor** (boundary: queue→doc-processor; STRIDE: T, E)
|
|
23
|
+
Scenario: attacker uploads a crafted PDF (parser exploit, zip bomb, SSRF-triggering embedded URL); doc-processor parses it with vendor-library defaults and processor credentials. RCE here reaches Postgres and the OCR key.
|
|
24
|
+
Existing mitigation: none stated. Recommended: validate content-type + size at presign and on consume; parse inside a sandboxed, least-privilege worker (no Postgres write role until post-parse); pin and patch the parser. **Verify:** corpus of hostile PDFs in CI lands in DLQ, not crash-loop or exec.
|
|
25
|
+
|
|
26
|
+
**🟧 TM-3 — Support staff can browse any tenant's contracts with no audit trail** (boundary: human→system; STRIDE: I, R; insider pass)
|
|
27
|
+
Scenario: a support login (insider or phished) bulk-reads contracts across tenants; the design grants "view any customer's documents" with no purpose-binding or logging — undetectable until external disclosure.
|
|
28
|
+
Existing mitigation: admin panel is authenticated. Recommended: case-bound access (support sees a document only via an open ticket reference), immutable audit log of every view, MFA on support accounts. **Verify:** admin-action integration test asserts the audit row; access without ticket reference → denied.
|
|
29
|
+
|
|
30
|
+
**🟧 TM-4 — Queue accepts unauthenticated/poisoned messages** (boundary: upload-api→queue; STRIDE: S, T)
|
|
31
|
+
Scenario: any internal workload (or attacker post-TM-2) enqueues `{tenant_id: victim, s3_key: attacker_file}`; doc-processor trusts the message and writes attacker text into the victim tenant's Postgres rows.
|
|
32
|
+
Existing mitigation: queue is network-internal `[assumption: flat internal trust]`. Recommended: doc-processor re-derives tenant from the S3 key prefix (post-TM-1) instead of trusting the message field; schema-validate on consume; producer allow-list via IAM. **Verify:** message with mismatched tenant/key → rejected with alert.
|
|
33
|
+
|
|
34
|
+
**🟨 TM-5 — Contract PII leaves trust domain to OCR vendor unminimized** (boundary: doc-processor→vendor; STRIDE: I)
|
|
35
|
+
Scenario: full contracts ship to the vendor; a vendor breach exposes the top asset with no detection on our side. Requires the vendor's failure, hence 🟨 not 🟧.
|
|
36
|
+
Existing mitigation: `[assumption]` contractual DPA. Recommended: confirm the DPA covers this data class; disable vendor-side retention; log per-document egress so exposure is enumerable after a vendor incident. **Verify:** vendor account settings reviewed + egress log row asserted in tests.
|
|
37
|
+
|
|
38
|
+
**🟨 TM-6 — Unbounded uploads as cost/availability attack** (boundary: internet→S3; STRIDE: D)
|
|
39
|
+
Scenario: a scripted tenant requests thousands of presigned URLs and uploads max-size files; S3 cost spike and OCR-queue saturation delay every tenant's processing (noisy-neighbor DoS).
|
|
40
|
+
Existing mitigation: authn required. Recommended: per-tenant presign rate limit + size cap at presign time; queue depth alarm with per-tenant fairness. **Verify:** load test on the presign endpoint shows throttling before queue saturation.
|
|
41
|
+
|
|
42
|
+
### n/a ledger
|
|
43
|
+
Repudiation at internet→S3: n/a beyond TM-3's audit log — S3 access logging assumed on. DoS at admin panel: internal user base, marginal.
|
|
44
|
+
|
|
45
|
+
### Authz / insider pass
|
|
46
|
+
Authz: TM-1, TM-4 (tenant→tenant). Insider: TM-3. Sweeps produced findings — no all-clear claimed.
|
|
47
|
+
|
|
48
|
+
### Questions for the team
|
|
49
|
+
1. Are presigned URLs PUT-only, and is there any GET path today? (confirms or escalates TM-1)
|
|
50
|
+
2. Does the OCR vendor contract cover contract PII, and is vendor-side retention off? (resolves TM-5's assumptions)
|
|
51
|
+
|
|
52
|
+
### Out of scope
|
|
53
|
+
E-signing flow itself (separate design); S3 bucket-policy review (assumed account-standard); browser-side threats (XSS) — covered by the web app's existing model.
|
|
54
|
+
|
|
55
|
+
### Revisit trigger
|
|
56
|
+
New entry point (e.g. email-in ingestion), new document consumer, or any change to support-access rules.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "threat-model",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Produce a STRIDE threat model from a design doc, architecture description, or feature spec — assets and trust boundaries first, threats anchored to boundary crossings with concrete attack scenarios, severity-ranked with verifiable mitigations. Use when the user asks to threat-model a design, run a security review of an architecture, ask \"how could this be attacked\", or needs security sign-off input before build.",
|
|
5
|
+
"entrypoint": "SKILL.md",
|
|
6
|
+
"deps": { "npm": [], "pip": [] },
|
|
7
|
+
"env": { "required": [], "optional": [] },
|
|
8
|
+
"related": ["design-doc", "devils-advocate", "postmortem-generator", "reverse-architecture", "sonar-review"],
|
|
9
|
+
"tags": ["threat-model", "security", "stride", "architecture", "design-review", "trust-boundaries"],
|
|
10
|
+
"model": { "tier": "heavy", "rationale": "Adversarial reasoning over a design — cheaper models emit checklist residue, miss authz/insider paths, and inflate severity. Never downgrade." }
|
|
11
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# threat-model reference — STRIDE question banks + mitigation table
|
|
2
|
+
|
|
3
|
+
Questions are prompts for the analysis, not a checklist to transcribe. A question only becomes a finding when it can be narrated as actor → path → result against a named boundary in the system under review.
|
|
4
|
+
|
|
5
|
+
## STRIDE by boundary type
|
|
6
|
+
|
|
7
|
+
### Internet → edge (public API, web app, webhook receiver)
|
|
8
|
+
|
|
9
|
+
- **S** — Can a caller forge identity? Token audience/issuer validated? Webhook signatures checked, or just a "secret" URL? API keys distinguishable from user auth?
|
|
10
|
+
- **T** — Are request bodies/headers trusted downstream (forwarded `X-User-Id`)? Can query params alter server-side behavior beyond their contract (mass assignment, prototype pollution)?
|
|
11
|
+
- **R** — Are authentication failures and privileged calls logged with caller identity? Could a caller plausibly deny an action?
|
|
12
|
+
- **I** — Do error responses leak stack traces, internal hostnames, versions? Do list endpoints leak other users' resource IDs? Timing differences on auth (user enumeration)?
|
|
13
|
+
- **D** — Unauthenticated endpoints with expensive work (search, export, PDF render)? Rate limits per-IP only (trivially rotated) or per-principal? Payload size caps?
|
|
14
|
+
- **E** — Do any endpoints trust client-supplied role/scope claims? Hidden admin routes guarded by obscurity?
|
|
15
|
+
|
|
16
|
+
### Service → service (internal APIs, queues, RPC)
|
|
17
|
+
|
|
18
|
+
- **S** — Does service B verify *which* service is calling, or accept anything inside the network ("flat trust")? mTLS / workload identity, or shared static secrets?
|
|
19
|
+
- **T** — Are queue messages signed or schema-validated, or does the consumer trust whatever's enqueued? Can a compromised producer poison downstream state?
|
|
20
|
+
- **R** — Can an action be traced through the chain (correlation IDs), or does attribution die at the first hop?
|
|
21
|
+
- **I** — Do internal payloads carry more data than the consumer needs (full user record where an ID would do)?
|
|
22
|
+
- **D** — Can one service exhaust another (no backpressure, unbounded fan-out, retry storms)?
|
|
23
|
+
- **E** — Does a low-privilege service hold credentials that grant more than it uses (over-scoped IAM)?
|
|
24
|
+
|
|
25
|
+
### App → datastore (DB, object storage, cache)
|
|
26
|
+
|
|
27
|
+
- **S** — Shared DB credentials across services, or per-service identity?
|
|
28
|
+
- **T** — String-built queries anywhere? Can the app write rows/objects outside its tenant scope (key-prefix discipline)?
|
|
29
|
+
- **I** — Tenant isolation by `WHERE` clause convention only? Backups/replicas/cache covered by the same access controls as primaries? Presigned URLs scoped and short-lived?
|
|
30
|
+
- **D** — Unbounded queries reachable from user input (no LIMIT, full scans)? Cache stampede paths?
|
|
31
|
+
- **E** — Does the app account hold DDL/admin rights it never uses?
|
|
32
|
+
|
|
33
|
+
### Human → system (admin panels, support tooling, CI/CD)
|
|
34
|
+
|
|
35
|
+
- **S** — Admin auth at the same strength as user auth, or stronger (MFA, hardware keys)? Sessions revocable?
|
|
36
|
+
- **T** — Can CI run arbitrary code with deploy credentials on a PR from a fork? Are build artifacts verifiable (signed, pinned digests)?
|
|
37
|
+
- **R** — Are support/admin actions on user data logged immutably with operator identity?
|
|
38
|
+
- **I** — Can support staff browse data beyond the case at hand (no purpose-binding)?
|
|
39
|
+
- **E** — Path from "support role" to "admin role"? Long-lived personal tokens with org-wide scope?
|
|
40
|
+
|
|
41
|
+
### Tenant → tenant (multi-tenant SaaS) — run with the authz pass
|
|
42
|
+
|
|
43
|
+
- IDs guessable/enumerable across tenants (sequential integers, predictable UUIDs in URLs)?
|
|
44
|
+
- Every query path tenant-scoped by construction (middleware/RLS), or by developer discipline?
|
|
45
|
+
- Shared compute side-channels: can one tenant's load degrade another's (noisy neighbor as DoS)?
|
|
46
|
+
- Export/report/search features — the classic cross-tenant leak surfaces.
|
|
47
|
+
|
|
48
|
+
## Insider / compromised-credential pass
|
|
49
|
+
|
|
50
|
+
Assume one legitimate credential is attacker-held: a user account, a support login, a CI token, one service's IAM role. For each, what's the blast radius before detection? Findings here are usually 🟧 — they need position, but position is bought cheaply (phishing, leaked token).
|
|
51
|
+
|
|
52
|
+
## Common mitigations (with the verification that makes them real)
|
|
53
|
+
|
|
54
|
+
| Threat shape | Mitigation | Verified by |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| Forged inbound identity | Token validation incl. audience+issuer+expiry; webhook HMAC | Negative test: tampered/expired token rejected in CI |
|
|
57
|
+
| Cross-tenant access | Tenant scoping by construction (RLS, scoped prefixes), not per-query discipline | Cross-tenant fetch test as a permanent CI case |
|
|
58
|
+
| Trusted internal headers | Strip/rewrite identity headers at the edge; sign internal assertions | Request with spoofed header from outside → rejected |
|
|
59
|
+
| Queue poisoning | Schema validation on consume; producer allow-list | Malformed message → DLQ with alert, not crash-loop |
|
|
60
|
+
| Resource exhaustion | Per-principal rate limits, payload caps, timeouts, bounded queries | Load test on the most expensive unauthenticated path |
|
|
61
|
+
| Over-scoped credentials | Per-service identity, least-privilege IAM, short-lived tokens | Periodic automated diff of granted vs used permissions |
|
|
62
|
+
| Silent admin abuse | Immutable audit log, purpose-bound support access | Audit-log entry asserted in admin-action integration tests |
|
|
63
|
+
|
|
64
|
+
## Severity calibration
|
|
65
|
+
|
|
66
|
+
- 🟥 **critical** — unauthenticated attacker, or any cross-tenant data compromise, against a top-ranked asset. Halt-the-build territory.
|
|
67
|
+
- 🟧 **high** — authenticated user bypasses authz; single-tenant data exposure; insider blast radius covering a top asset.
|
|
68
|
+
- 🟨 **medium** — requires chaining 2+ weaknesses or unusual position; degraded availability short of outage.
|
|
69
|
+
- ⚪ **low / accepted** — real but marginal; document the acceptance so it's a decision, not an oversight.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: user-journey-map
|
|
3
|
+
description: Map a customer's end-to-end journey toward an outcome — 3–6 stages, each with actions, emotions, pains, and opportunities, plus a rendered Mermaid emotion arc and the ranked pain points design should attack first. Use when the user wants a journey map, customer experience map, "map the user's path through onboarding", touchpoint analysis, or "where do users feel friction".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# user-journey-map
|
|
7
|
+
|
|
8
|
+
Maps what one customer experiences on the way to one outcome — outside-in, frontstage only — and converts the map's pains into a **ranked improvement target**, because a journey map that ends as wall art has failed. The emotional low points get found and named (peak-end rule: users judge an experience by its worst moment and its ending, not its average), so downstream design knows exactly which two stages to fix first. Sibling of `architecture-diagrams` (systems, not people) and upstream of `prd-draft` / `user-story-splitter` when an opportunity becomes committed work.
|
|
9
|
+
|
|
10
|
+
## How to respond
|
|
11
|
+
|
|
12
|
+
1. **Anchor persona, outcome, and evidence level.** Ask at most 2 questions, spent on the weakest anchors: *"whose journey — one specific persona?"* and *"what outcome are they trying to reach?"* No persona or outcome → don't draft; a journey for "users" toward "using the product" has no stage boundaries. Non-interactive run (no user to ask): derive a specific persona and outcome from the input if defensible and tag them `[assumption]`; underivable → emit `BLOCKED: need persona + outcome` naming both. Tag the whole map's **evidence level**: `[observational]` (interviews, session recordings), `[survey/analytics]`, or `[assumption-based]` (team hypothesis). Assumption-based is legitimate — it's a hypothesis that directs research — but it must say so at the top, not masquerade as findings.
|
|
13
|
+
|
|
14
|
+
2. **Fix the journey's edges.** Start trigger (the event that puts the persona on this path — in their life, not on your site: ✅ *"payroll fails on the last Friday of the month"*) and end state (what "done" means *to the persona* — ❌ "completes checkout" if their outcome is "salary problem solved"). Wrong edges are the most common defect: starting at the landing page amputates the discovery pain, ending at purchase hides the abandonment cliff in activation.
|
|
15
|
+
|
|
16
|
+
3. **Divide into 3–6 named stages.** Stages are coarse phases of the persona's goal — *discover, evaluate, start, get value, return* — never screens or clicks. More than 6 stages means the altitude has dropped to flow level; that's `user-story-splitter` / flow-design territory, say so and re-chunk.
|
|
17
|
+
|
|
18
|
+
4. **Fill the four rows per stage** — this table is the artifact's core:
|
|
19
|
+
- **Actions**: what the persona does, in their words, frontstage only. What the org does backstage ("support reviews the request") is out of scope — note it in the hand-off, don't map it.
|
|
20
|
+
- **Emotion**: score 1–5 with the *reason*: ✅ *"2 — asked for the same information a third time"* — ❌ *"2 — frustrated"*.
|
|
21
|
+
- **Pains**: friction, confusion, dead ends — each tagged with the step-1 evidence level if it differs from the map's default.
|
|
22
|
+
- **Opportunities**: what would change the experience if the pain were removed — stated as an outcome, not a solution: ✅ *"never re-enter data the system already has"* — ❌ *"add autofill"* (that's a design decision that belongs downstream).
|
|
23
|
+
|
|
24
|
+
5. **Mark the peaks, then rank.** From the emotion row: the **1–2 steepest dips** and the **single highest peak**, plus the *ending* emotion (peak-end rule counts it double). Rank the opportunities: severity of the dip × how many personas/journeys hit it × evidence strength. Top 2 opportunities become the named improvement targets; the rest are listed but explicitly deprioritized — an unranked list re-delegates the judgment to the reader.
|
|
25
|
+
|
|
26
|
+
6. **Render and emit** with [`templates/journey-map.md`](templates/journey-map.md), in one message: the stage table, a Mermaid `journey` diagram (one `section` per stage, scored actions drawing the emotion arc), ranked opportunities with the two named targets, and hand-offs — target becomes committed work → `prd-draft` or `user-story-splitter`; measurement for a fix → `success-metrics`; backstage causes implicated → name them for the service owner. See [`examples/b2b-saas-onboarding.md`](examples/b2b-saas-onboarding.md) for the full pattern.
|
|
27
|
+
|
|
28
|
+
## Useful references in this skill
|
|
29
|
+
|
|
30
|
+
- [`templates/journey-map.md`](templates/journey-map.md) — stage table, Mermaid journey skeleton, ranked-opportunities block
|
|
31
|
+
- [`examples/b2b-saas-onboarding.md`](examples/b2b-saas-onboarding.md) — worked example: trial-to-activation journey, assumption-based, with ranked targets
|
|
32
|
+
|
|
33
|
+
## Quality bar
|
|
34
|
+
|
|
35
|
+
- **One persona, one outcome**, both named in the title. A map for "users" is a map of nothing.
|
|
36
|
+
- **The evidence level is declared at the top** and every pain that deviates from it is tagged individually.
|
|
37
|
+
- **Stage edges live in the persona's life**, not on the product's surface — the trigger precedes the product; the end state is the persona's outcome.
|
|
38
|
+
- **Every emotion score carries its reason.** A bare number row is decoration.
|
|
39
|
+
- **Opportunities are outcomes, not features.** The moment "add a button" appears, the map has started doing design's job without design's process.
|
|
40
|
+
- **The dips, the peak, and the ending are explicitly marked**, and exactly 1–2 opportunities are named as the targets. Ranking is the deliverable.
|
|
41
|
+
- **The Mermaid renders.** Scores 1–5, one section per stage — check syntax before emitting.
|
|
42
|
+
|
|
43
|
+
## When to use this skill
|
|
44
|
+
|
|
45
|
+
- ✅ "Map the customer journey through onboarding/purchase/support"
|
|
46
|
+
- ✅ "Where do users feel the most friction?" — with or without research data
|
|
47
|
+
- ✅ Before a redesign: agree on the as-is experience and where it hurts most
|
|
48
|
+
- ✅ Turning scattered user feedback into one shared picture of the path
|
|
49
|
+
|
|
50
|
+
## When NOT to use this skill
|
|
51
|
+
|
|
52
|
+
- ❌ Screen-by-screen interaction or flow design — that's below this altitude; the map hands off to it
|
|
53
|
+
- ❌ Internal/employee process mapping — this skill is outside-in; org-internal flows are a process diagram (`architecture-diagrams` sequence flows)
|
|
54
|
+
- ❌ Backstage service wiring behind the touchpoints — `reverse-architecture` / `architecture-diagrams`
|
|
55
|
+
- ❌ A committed feature needing requirements — `prd-draft`
|
|
56
|
+
|
|
57
|
+
## Anti-patterns to avoid
|
|
58
|
+
|
|
59
|
+
- ❌ **One stage per screen.** "Landing → Signup form → Email verify → Dashboard" is a screen list, not a journey — stages are phases of the persona's goal.
|
|
60
|
+
- ❌ **Mapping the org, not the customer.** "Support triages the ticket" is backstage; the customer's row says *"waits two days, chases twice"*.
|
|
61
|
+
- ❌ **Hypothesis dressed as research.** An assumption-based map presented without its tag poisons every decision built on it. The tag is load-bearing.
|
|
62
|
+
- ❌ **Happy-path-only journeys.** A map with no dip below 3 didn't look — errors, waits, and re-entry live in every real journey.
|
|
63
|
+
- ❌ **Solutioning in the opportunities row.** "Add SSO" pre-empts design with a guess; "signing in stops being the reason trials stall" keeps the problem open and measurable.
|
|
64
|
+
- ❌ **The unranked pain inventory.** Fourteen equal pains means the reader does the prioritizing — the map's whole job was to do it for them.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "query": "Map the customer journey through our onboarding flow", "should_trigger": true },
|
|
3
|
+
{ "query": "Where do users feel the most friction in the purchase experience?", "should_trigger": true },
|
|
4
|
+
{ "query": "Create a journey map for a new user's first week", "should_trigger": true },
|
|
5
|
+
{ "query": "Turn this pile of user feedback into a customer experience map", "should_trigger": true },
|
|
6
|
+
{ "query": "Map the touchpoints from trial signup to activation", "should_trigger": true },
|
|
7
|
+
|
|
8
|
+
{ "query": "Design the screen-by-screen flow for the checkout wizard", "should_trigger": false },
|
|
9
|
+
{ "query": "Diagram how the order service talks to the payment service", "should_trigger": false },
|
|
10
|
+
{ "query": "Map our internal ticket-escalation process", "should_trigger": false },
|
|
11
|
+
{ "query": "Write the PRD for the onboarding redesign", "should_trigger": false }
|
|
12
|
+
]
|