Contributed by: Mark Whaley · Source: PM Starter Kit
Use this when a PM needs to understand how systems, services, or components depend on each other to make sequencing and prioritization decisions. Inspects the identified repositories and service paths to extract internal service-to-service calls, external third-party dependencies, database tables touched, and event/topic contracts produced and consumed.
This skill produces the dependency snapshot that reveals hidden coupling, critical paths, and independent work streams. It sits at the end of the Feature Impact Radar pipeline: /technical-intent-parser → /architecture-context-reviewer → /repository-discovery → /codependency-analyzer.
Process
Step 1: Gather inputs
Ask the user:
- Repositories — The repos identified by
/repository-discovery(e.g.,payments/billing-service,messaging/notification-platform). If coming from the pipeline, these are already available. - Backend actions — The actions identified by
/technical-intent-parser(e.g., schedule_reminder, send_notification, store_user_preferences). - Data entities — The business objects identified by
/technical-intent-parser(e.g., invoice, reminder_preferences, user). - Service paths (recommended) — Where each service lives in its repo, from
/repository-discovery. - Event streams (if known) — From
/architecture-context-reviewer. - Org context (optional) — Languages/frameworks, monorepo/polyrepo, runtime environment.
If repositories, backend actions, and data entities are missing, stop and request them (or run the upstream skills first).
Step 2: Identify which personas are affected
Before generating the analysis, prompt the user:
Persona check: Which user persona(s) are affected by these systems? If you have defined personas (e.g., from
/persona-createor/persona-draft), name them. If not, describe who uses the features powered by these components.This ensures the dependency map highlights what matters to users — not just internal coupling — and helps prioritize which dependency chains to address first.
Step 3: Analyze code dependencies
For each service path, inspect code and metadata to extract dependencies. Use backend actions and data entities as search anchors to reduce noise.
Evidence sources (priority order):
- Direct client usage (HTTP/gRPC SDK calls), explicit producers/consumers
- API/event schema references + routing config
- Dependency manifests + infra config (Helm, Terraform, env vars)
- Naming inference (lowest — use only as "suspected", not fact)
What to look for:
- Internal service-to-service calls: HTTP clients calling internal hostnames, gRPC stubs, shared API client libraries, gateway routing config, service URL config vars
- External third-party dependencies: SaaS APIs (email, SMS, push), cloud-managed services (queues, storage), external partner APIs, SDK usage
- Database tables touched: Migrations, ORM models, query targets in DAOs/repositories
- Event dependencies: Producers (publishing events), consumers (subscriptions, handlers), topic names, schema references
Step 4: Present the dependency snapshot
## Dependency Analysis — (Feature/Context Name)
**Date:** (Date)
**Repos analyzed:** (List)
**Confidence level:** (High / Medium / Low)
---
### Internal Service Dependencies
| Caller | Callee | Mechanism | Evidence |
|---|---|---|---|
| (service-a) | (service-b) | (http / grpc / event / lib) | (File or config where this was found) |
### External Dependencies
| Service | External system | Type | Evidence |
|---|---|---|---|
| (service-name) | (e.g., SendGrid, Stripe, AWS SQS) | (saas / cloud / partner) | (SDK usage, client code, config) |
### Database Tables Touched
| Service | Database.Table | Access pattern | Evidence |
|---|---|---|---|
| (service-name) | (db.table or table if db unknown) | (read / write / migrate) | (Migration file, ORM model, query) |
### Event Dependencies
| Service | Role | Event / Topic | Evidence |
|---|---|---|---|
| (service-name) | (produces / consumes) | (event.name) | (Publisher/handler code, config) |
Step 5: Map the critical path and independent streams
### Dependency Map
(Text diagram showing which systems depend on which.)
[billing-service] ──http──→ [notification-service] │ │ └──http──→ [user-preferences-service] │ [billing-service] ──produces──→ invoice.due_soon ──consumed by──→ [notification-service]
### Critical Path
For (the feature/initiative): (Component A) → (Component B) → (Component C)
This means: (Plain-language explanation of the sequencing constraint.)
### Independent Work Streams
These can be worked on in parallel without blocking each other:
- **Stream 1:** (Components) — (Why they're independent)
- **Stream 2:** (Components) — (Why they're independent)
### Change Blast Radius
| If you change... | These also need to change | Ripple size |
|---|---|---|
| (Component) | (Affected components) | (Small / Medium / Large — with explanation) |
### Coupling Risks
| Risk | Components | Why it's risky | Mitigation |
|---|---|---|---|
| (e.g., shared database) | (Components sharing it) | (What goes wrong) | (How to mitigate) |
Step 6: Review and validate
Ask the user:
- Does this dependency map match your understanding?
- Are there dependencies engineers have mentioned that aren't captured here?
- Does the critical path align with your team's capacity and sequencing?
- Are there external dependencies (vendor APIs, partner systems) that should be on this map?
Adjust as needed.
Related skills
/repository-discovery— upstream: provides the repos and service paths this skill analyzes./architecture-context-reviewer— upstream: provides verified services, databases, and event streams./technical-intent-parser— pipeline entry point: decomposes a feature into technical signals./pre-mortem— when you want to stress-test sequencing decisions for failure modes./ipm-plan— when you're ready to turn the sequencing into an iteration plan.
Output location
Present the dependency snapshot, critical path, and independent streams as formatted text in the conversation. The user copies the output into planning documentation, shares it in roadmap discussions, or uses it to facilitate sequencing conversations with engineering leads.
Example Output
Input
- Repositories:
commerce/checkout-service,payments/billing-service,messaging/notification-platform,identity/user-preferences-service - Backend actions:
process_payment,apply_promo_code,send_order_confirmation,store_payment_method - Data entities:
order,payment_method,promo_code,user_preferences - Service paths:
checkout-service/src/clients/,billing-service/src/handlers/,notification-platform/src/consumers/,user-preferences-service/src/models/ - Event streams: Kafka topics —
order.completed,payment.failed,promo.redeemed - Org context: Polyrepo, Node.js/TypeScript services, Kubernetes on GCP, Stripe SDK in use
Output (abbreviated)
Dependency Analysis — One-Click Checkout with Promo Support
Date: 2025-06-11
Repos analyzed: commerce/checkout-service, payments/billing-service, messaging/notification-platform, identity/user-preferences-service
Confidence level: High (direct client code + Kafka config inspected; one suspected dependency noted)
Internal Service Dependencies
| Caller | Callee | Mechanism | Evidence |
|---|---|---|---|
| checkout-service | billing-service | HTTP | checkout-service/src/clients/billing.client.ts — POST /charges |
| checkout-service | user-preferences-service | HTTP | checkout-service/src/clients/preferences.client.ts — GET /payment-methods/:userId |
| notification-platform | user-preferences-service | HTTP | notification-platform/src/consumers/order-completed.handler.ts — fetches email/push prefs |
| billing-service | checkout-service | Suspected HTTP | Naming inference on checkout.callback env var — unconfirmed |
External Dependencies
| Service | External System | Type | Evidence |
|---|---|---|---|
| billing-service | Stripe | SaaS | stripe npm package, billing-service/src/handlers/charge.handler.ts |
| notification-platform | SendGrid | SaaS | @sendgrid/mail SDK, notification-platform/src/senders/email.sender.ts |
| notification-platform | Firebase Cloud Messaging | Cloud | firebase-admin SDK, notification-platform/src/senders/push.sender.ts |
| billing-service | GCP Secret Manager | Cloud | @google-cloud/secret-manager in billing-service/src/config/secrets.ts |
Database Tables Touched
| Service | Database.Table | Access Pattern | Evidence |
|---|---|---|---|
| checkout-service | commerce.orders | read / write | checkout-service/src/models/order.model.ts, migration 0041_create_orders |
| checkout-service | commerce.promo_codes | read / write | checkout-service/src/models/promo.model.ts, query in apply_promo_code.ts |
| billing-service | payments.payment_methods | read / write | billing-service/src/models/payment-method.model.ts |
| billing-service | payments.transactions | write | billing-service/src/handlers/charge.handler.ts |
| user-preferences-service | identity.user_preferences | read / write | user-preferences-service/src/models/preferences.model.ts |
Event Dependencies
| Service | Role | Event / Topic | Evidence |
|---|---|---|---|
| checkout-service | produces | order.completed | checkout-service/src/publishers/order.publisher.ts |
| checkout-service | produces | promo.redeemed | checkout-service/src/publishers/promo.publisher.ts |
| billing-service | produces | payment.failed | billing-service/src/handlers/charge.handler.ts |
| notification-platform | consumes | order.completed | notification-platform/src/consumers/order-completed.handler.ts |
| notification-platform | consumes | payment.failed | notification-platform/src/consumers/payment-failed.handler.ts |
Dependency Map
[checkout-service] ──http──→ [billing-service] ──→ Stripe
│ │
│ └──produces──→ payment.failed ──→ [notification-platform]
│
└──http──→ [user-preferences-service]
│ ↑
│ (also called by notification-platform)
│
└──produces──→ order.completed ──→ [notification-platform] ──→ SendGrid / FCM
└──produces──→ promo.redeemed (no consumer found — orphan event)
Critical Path
For one-click checkout with promo support:
user-preferences-service → billing-service → checkout-service → notification-platform
This means: checkout-service cannot complete a purchase flow without user-preferences-service returning a stored payment method and billing-service successfully charging it. notification-platform is downstream of the order.completed event, so it can be integrated last — but its dependency on user-preferences-service for delivery preferences must be validated before go-live.
Independent Work Streams
These can be worked on in parallel without blocking each other:
- Stream 1:
user-preferences-serviceschema +store_payment_methodendpoint — no inbound service dependencies; can be built and tested in isolation - Stream 2:
notification-platformconsumer logic fororder.completedandpayment.failed— depends only on Kafka topic contracts being finalized, not on checkout flow completion - Stream 3: Stripe integration hardening in
billing-service— internal to that service; only interface contract (POST/chargesresponse shape) needs to be stable for checkout-service
Change Blast Radius
| If you change... | These also need to change | Ripple size |
|---|---|---|
user-preferences-service /payment-methods response schema | checkout-service, notification-platform | Large — two independent callers; coordinate contract change or version the endpoint |
order.completed Kafka topic schema | notification-platform consumer handler | Medium — one consumer, but schema break causes silent failures if not versioned |
| Stripe charge API (e.g., payment intent migration) | billing-service only | Small — fully encapsulated; no surface exposed to other services |
commerce.promo_codes table structure | checkout-service only | Small — single owner, no cross-service reads detected |
Coupling Risks
| Risk | Components | Why It's Risky | Mitigation |
|---|---|---|---|
Shared user-preferences-service called synchronously by two services | checkout-service, notification-platform | Latency spike or downtime in preferences service blocks both checkout completion and order confirmation delivery simultaneously | Add response caching in each caller; consider async fallback for notification path |
Orphan event: promo.redeemed produced but no consumer found | checkout-service | Event is being published to Kafka with no handler — either a consumer is missing (analytics? loyalty?) or dead code is accumulating | Confirm intended consumer with engineering; remove or document the topic contract |
Suspected callback dependency from billing-service → checkout-service | billing-service, checkout-service | If confirmed, this creates a circular HTTP dependency — a failure in checkout would cascade back into billing | Inspect CHECKOUT_CALLBACK_URL env var; convert to event-driven if circular call is confirmed |
Review Questions for Engineering
- Does the
billing-service→checkout-servicecallback exist? If so, what triggers it and can it be replaced with an event? - Is there an intended consumer for the
promo.redeemedtopic — e.g., a loyalty or analytics service not yet in scope? - Does
notification-platformhave a fallback ifuser-preferences-serviceis slow at the time anorder.completedevent arrives?