Platform (Shared Platform Library)
Overview
Create a small, disciplined “shared kernel” that drives cohesion across services by providing stable primitives at boundaries (auth, RPC, config, telemetry, resilience, lifecycles).
The goal is not reuse-for-reuse’s-sake; it’s consistent behavior and lower cognitive load across a system.
Workflow
- Define the objective function:
- what this extraction optimizes (for example: reliability, cognitive load, release speed)
- constraints and anti-goals
- Define the “platform surface” (what belongs here vs per-service).
- Inventory repetition across services and pick 1–2 extractions with the highest leverage.
- Design the module boundaries and dependency direction (avoid cycles, keep exports stable).
- Design APIs that are:
- explicit about inputs/outputs and expected failures (
Result / tagged errors)
- explicit about lifetimes (create/start/stop/dispose)
- explicit about cancellation/time budgets (
AbortSignal, deadlines)
- explicit about telemetry fields (trace/log/metrics correlation)
- Define adoption maturity tracks with entry criteria:
- V0 (minimum viable): almost impossible to fail; one golden path; minimal config
- V1 (standard): default for most services; stronger contracts and verification
- V2 (advanced): optional optimizations for high-scale/high-complexity cases
- Implement minimal primitives + one “golden path” usage in at least two services.
- Add tests at the seam (unit tests for primitives + characterization tests for adopters if needed).
- Document usage, deprecation/migration guidance, and reversal triggers.
Clarifying Questions
- How many services currently duplicate this boundary logic (need 2+ to justify extraction)?
- What is the adoption timeline (immediate extraction vs planned migration)?
- Who owns the shared package (one team, platform team, shared ownership)?
- What is the release/versioning strategy (monorepo linked, published package, vendored copy)?
- Are there existing shared packages or "utils" files that this should consolidate or replace?
- What maturity level are adopters at (can they handle V0 minimal, or do they need V1 contracts)?
What Belongs In The Shared Platform Library
Prefer boundary primitives over “random helpers”:
- Auth/JWT verification utilities
- gRPC server/client helpers (handler wrappers, interceptors, service registration)
- HTTP client wrappers (timeouts, retries, tracing hooks)
- Typed error/result primitives and decoding helpers
- Lifecycle helpers (start/stop guards, “agent” patterns, shutdown coordination)
- Observability glue (log field mixins, span helpers, RED metric helpers)
- Resilience glue (retry helpers, circuit breaker/bulkhead primitives where applicable)
What Does Not Belong
- Business/domain logic (rules, invariants, etc.)
- One-off utilities used by one call site (“utils junk drawer” risk)
- Hidden I/O at import time (no global clients created on module load)
- High-cardinality or PII-heavy telemetry helpers (keep privacy discipline explicit)
Guardrails (Opinionated Defaults)
- “Two consumers” rule: don’t add a primitive until it’s used (or imminently needed) in 2+ services.
- Keep the public surface small: a few stable entrypoints beat dozens of micro-exports.
- Prefer composition over inheritance; “wrappers” should preserve response shapes and error semantics.
- Make operation names explicit (don’t depend on framework reflection/casing quirks).
- Keep dependencies minimal; avoid pulling in large frameworks into every service accidentally.
- If you introduce retries, you must introduce idempotency guidance.
- Don’t make V2 requirements mandatory for V0/V1 adopters.
Pattern Catalogue (Common Shared Primitives)
- Boundary handler wrappers (Template Method + interceptors): standardize “decode → call → map response” with consistent timing/logging/error mapping.
- Client proxies: wrap callback APIs into promises with
AbortSignal support and timeouts.
- Lifecycle facades: stable
start()/stop() APIs with concurrency guards to avoid start/stop races.
- Service registration validators: fail fast if a server registers an incomplete handler set.
References
Related skills:
Output Template
When applying this skill, return:
- Proposed module(s) and public API surface (what’s exported).
- What duplication this removes (call sites) and what invariants it enforces.
- Error semantics, cancellation/timeouts strategy, and telemetry fields.
- Adoption tracks (V0/V1/V2 entry criteria), first two migrations, and reversal triggers.
- Tests/verification and the review ritual for adoption progress.
1---2name: platform-43description: Design and maintain shared platform libraries (e.g. packages/shared) that standardize cross-cutting concerns (auth wrappers, config, HTTP/gRPC helpers, typed errors, retry policies, lifecycle hooks). Use when multiple services duplicate boundary logic or need a golden-path primitive; prevents "utils junk drawer" anti-pattern. NOT for single-service code structure (use typescript); NOT for choosing resilience patterns for one call (use resilience).4---5
6# Platform (Shared Platform Library)
7
8## Overview
9
10Create a small, disciplined “shared kernel” that drives cohesion across services by providing stable primitives at boundaries (auth, RPC, config, telemetry, resilience, lifecycles).
11
12The goal is not reuse-for-reuse’s-sake; it’s consistent behavior and lower cognitive load across a system.
13
14## Workflow
15
161. Define the objective function:
17 - what this extraction optimizes (for example: reliability, cognitive load, release speed)
18 - constraints and anti-goals
192. Define the “platform surface” (what belongs here vs per-service).
203. Inventory repetition across services and pick 1–2 extractions with the highest leverage.
214. Design the module boundaries and dependency direction (avoid cycles, keep exports stable).
225. Design APIs that are:
23 - explicit about inputs/outputs and expected failures (`Result` / tagged errors)
24 - explicit about lifetimes (create/start/stop/dispose)
25 - explicit about cancellation/time budgets (`AbortSignal`, deadlines)
26 - explicit about telemetry fields (trace/log/metrics correlation)
276. Define adoption maturity tracks with entry criteria:
28 - **V0 (minimum viable)**: almost impossible to fail; one golden path; minimal config
29 - **V1 (standard)**: default for most services; stronger contracts and verification
30 - **V2 (advanced)**: optional optimizations for high-scale/high-complexity cases
317. Implement minimal primitives + one “golden path” usage in at least two services.
328. Add tests at the seam (unit tests for primitives + characterization tests for adopters if needed).
339. Document usage, deprecation/migration guidance, and reversal triggers.
34
35## Clarifying Questions
36
37- How many services currently duplicate this boundary logic (need 2+ to justify extraction)?
38- What is the adoption timeline (immediate extraction vs planned migration)?
39- Who owns the shared package (one team, platform team, shared ownership)?
40- What is the release/versioning strategy (monorepo linked, published package, vendored copy)?
41- Are there existing shared packages or "utils" files that this should consolidate or replace?
42- What maturity level are adopters at (can they handle V0 minimal, or do they need V1 contracts)?
43
44## What Belongs In The Shared Platform Library
45
46Prefer **boundary primitives** over “random helpers”:
47
48- Auth/JWT verification utilities
49- gRPC server/client helpers (handler wrappers, interceptors, service registration)
50- HTTP client wrappers (timeouts, retries, tracing hooks)
51- Typed error/result primitives and decoding helpers
52- Lifecycle helpers (start/stop guards, “agent” patterns, shutdown coordination)
53- Observability glue (log field mixins, span helpers, RED metric helpers)
54- Resilience glue (retry helpers, circuit breaker/bulkhead primitives where applicable)
55
56## What Does *Not* Belong
57
58- Business/domain logic (rules, invariants, etc.)
59- One-off utilities used by one call site (“utils junk drawer” risk)
60- Hidden I/O at import time (no global clients created on module load)
61- High-cardinality or PII-heavy telemetry helpers (keep privacy discipline explicit)
62
63## Guardrails (Opinionated Defaults)
64
65- “Two consumers” rule: don’t add a primitive until it’s used (or imminently needed) in 2+ services.
66- Keep the public surface small: a few stable entrypoints beat dozens of micro-exports.
67- Prefer composition over inheritance; “wrappers” should preserve response shapes and error semantics.
68- Make operation names explicit (don’t depend on framework reflection/casing quirks).
69- Keep dependencies minimal; avoid pulling in large frameworks into every service accidentally.
70- If you introduce retries, you must introduce idempotency guidance.
71- Don’t make V2 requirements mandatory for V0/V1 adopters.
72
73## Pattern Catalogue (Common Shared Primitives)
74
75- **Boundary handler wrappers (Template Method + interceptors)**: standardize “decode → call → map response” with consistent timing/logging/error mapping.
76- **Client proxies**: wrap callback APIs into promises with `AbortSignal` support and timeouts.
77- **Lifecycle facades**: stable `start()/stop()` APIs with concurrency guards to avoid start/stop races.
78- **Service registration validators**: fail fast if a server registers an incomplete handler set.
79
80## References
81
82- Checklists: [`references/checklists.md`](references/checklists.md)
83- Module layout guidance: [`references/module-layout.md`](references/module-layout.md)
84- Templates/snippets: [`references/templates.md`](references/templates.md)
85- Boundary wrappers (error/idempotency/telemetry contracts): [`references/boundary-wrappers.md`](references/boundary-wrappers.md)
86- Related patterns: [`Microservice chassis`](../architecture/references/microservice-chassis.md), [`Service Template`](../architecture/references/service-template.md), [`Service deployment platform`](../architecture/references/service-deployment-platform.md)
87
88Related skills:
89
90- [`spec`](../spec/SKILL.md) (spec bundles + contracts)
91- [`observability`](../observability/SKILL.md) (telemetry expectations)
92- [`resilience`](../resilience/SKILL.md) (timeouts/retries/idempotency)
93- [`security`](../security/SKILL.md) (authn/authz, input validation, secrets)
94- [`typescript`](../typescript/SKILL.md) (typed boundaries/errors/lifetimes)
95- [`patterns-structural`](../patterns-structural/SKILL.md) / [`patterns-behavioral`](../patterns-behavioral/SKILL.md) (wrappers/pipelines)
96
97## Output Template
98
99When applying this skill, return:
100
101- Proposed module(s) and public API surface (what’s exported).
102- What duplication this removes (call sites) and what invariants it enforces.
103- Error semantics, cancellation/timeouts strategy, and telemetry fields.
104- Adoption tracks (V0/V1/V2 entry criteria), first two migrations, and reversal triggers.
105- Tests/verification and the review ritual for adoption progress.