Agent skill

Microservices

by kid-sid in kid-sid/claude-spellbook

A skill your agent uses when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an…

MITAuto-check passedBackend & APIs

Install Microservices

skills CLI
$ npx skills add kid-sid/claude-spellbook --skill microservices -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install kid-sid/claude-spellbook microservices --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/microservices .claude/skills/microservices && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
microservices
GitHub stars
189
Token cost
~3.5k tokens
SKILL.md length
700 words
Files
1
Skills in repo
52
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an…

  • Decomposing a monolith
  • SKILL.md covers When to Activate, Service Decomposition, Inter-Service Communication and Resilience Patterns, plus 6 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Designing inter-service communication

What it does

Microservices is an agent skill from kid-sid/claude-spellbook. Use when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an API gateway for a distributed system.

Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Microservices. It works with gRPC. The repository describes itself as: A curated collection of skills, prompts, and workflows that extend Claude's capabilities — your personal grimoire for AI-powered development. The licence is MIT.

When your agent uses it

  • Decomposing a monolith
  • Designing inter-service communication
  • Implementing circuit breakers
  • Reasoning about data ownership across services

Example prompts

  • “/microservices”

Requirements

  • Python 3
  • Docker

What it can do on your machine

Read from SKILL.md and the folder at commit a7c2ac9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python, typescript, go, proto and yaml).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Microservices loads about 3.5k tokens when it runs. Until then it costs about 57 tokens; SKILL.md has 700 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~57
When it runs · the whole SKILL.md, loaded when a task matches
~3.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from kid-sid/claude-spellbook at commit a7c2ac9, republished under its MIT licence (© kid-sid). 700 words, ~3,526 tokens.

Download SKILL.mdSave it as .claude/skills/microservices/SKILL.md (or your agent's skills folder).
name
microservices
description
Use when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an API gateway for a distributed system.

Microservices Patterns

Design and implementation patterns for decomposing monoliths and building reliable distributed backend systems.

When to Activate

  • Decomposing a monolith into services or defining service boundaries
  • Choosing between synchronous (REST/gRPC) and asynchronous (messaging) communication
  • Implementing resilience patterns: circuit breaker, retry, bulkhead, timeout
  • Designing data ownership and cross-service transactions (Saga, CQRS)
  • Setting up an API gateway or BFF for client-facing traffic
  • Designing for eventual consistency or event-driven workflows
  • Debugging distributed failures, cascading errors, or data inconsistency

Service Decomposition

Decomposition Strategies
StrategyApproachBest For
By domain (DDD)Align services to bounded contextsGreenfield, domain-rich systems
By subdomainCore / supporting / generic subdomainsPrioritising build-vs-buy
Strangler figIncrementally replace monolith routesExisting monoliths
By volatilityIsolate frequently-changing logicHigh-churn business rules
Bounded Context Rules
# BAD: Shared User model across services
OrderService   → reads User.loyaltyPoints
PaymentService → reads User.billingAddress
EmailService   → reads User.email

# GOOD: Each service owns what it needs
OrderService   → owns OrderCustomer { id, name, loyaltyPoints }
PaymentService → owns PaymentProfile { userId, billingAddress, paymentMethods }
EmailService   → owns ContactRecord { userId, email, preferences }

Each service owns its data. No direct cross-service DB queries.

Strangler Fig Migration
1. Route all traffic through a facade (nginx / API gateway)
2. Identify one vertical slice (e.g., /api/payments/*)
3. Implement that slice as a new service
4. Re-route the facade to the new service
5. Delete the monolith code for that slice
6. Repeat — monolith shrinks, services grow

Inter-Service Communication

Sync vs Async Decision
FactorSync (REST / gRPC)Async (Queue / Events)
Latency requirementLow — caller needs immediate responseCan tolerate delay
CouplingTemporal coupling (both must be up)Decoupled — producer/consumer independent
Use caseQueries, user-facing readsCommands, workflows, notifications
Error handlingPropagates to caller immediatelyDead-letter queue, retry policies
ThroughputLimited by slowest serviceBuffered; consumer scales independently
Sync: REST
python
# Python — requests with retry and timeout
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
def get_user(user_id: str) -> dict:
    response = httpx.get(
        f"http://user-service/users/{user_id}",
        timeout=2.0,  # always set a timeout
    )
    response.raise_for_status()
    return response.json()["data"]
typescript
// TypeScript — fetch with timeout and retry
async function getUser(userId: string): Promise<User> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 2000);
  try {
    const res = await fetch(`http://user-service/users/${userId}`, {
      signal: controller.signal,
    });
    if (!res.ok) throw new Error(`upstream error: ${res.status}`);
    return (await res.json()).data;
  } finally {
    clearTimeout(timeout);
  }
}
go
// Go — http client with timeout
func (c *UserClient) GetUser(ctx context.Context, userID string) (*User, error) {
    ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
    defer cancel()

    req, _ := http.NewRequestWithContext(ctx, http.MethodGet,
        fmt.Sprintf("http://user-service/users/%s", userID), nil)
    resp, err := c.http.Do(req)
    if err != nil {
        return nil, fmt.Errorf("user-service: %w", err)
    }
    defer resp.Body.Close()
    // decode...
}
Sync: gRPC (preferred for internal service-to-service)
proto
// order.proto
service OrderService {
  rpc GetOrder (GetOrderRequest) returns (Order);
  rpc CreateOrder (CreateOrderRequest) returns (Order);
  rpc ListOrders (ListOrdersRequest) returns (stream Order);  // server streaming
}

message GetOrderRequest { string order_id = 1; }
message Order {
  string id = 1;
  string customer_id = 2;
  OrderStatus status = 3;
  repeated OrderItem items = 4;
}
Async: Message Broker
python
# Python — publishing an event (Kafka)
from confluent_kafka import Producer
import json

producer = Producer({"bootstrap.servers": "kafka:9092"})

def publish_order_placed(order: Order):
    event = {
        "event_type": "order.placed",
        "order_id": order.id,
        "customer_id": order.customer_id,
        "total": str(order.total),
        "occurred_at": order.created_at.isoformat(),
    }
    producer.produce(
        topic="orders",
        key=order.id,
        value=json.dumps(event).encode(),
    )
    producer.flush()
typescript
// TypeScript — consuming events (Kafka / KafkaJS)
const consumer = kafka.consumer({ groupId: "notification-service" });
await consumer.subscribe({ topic: "orders", fromBeginning: false });
await consumer.run({
  eachMessage: async ({ message }) => {
    const event = JSON.parse(message.value!.toString());
    if (event.event_type === "order.placed") {
      await notifyCustomer(event.customer_id, event.order_id);
    }
  },
});

Resilience Patterns

Circuit Breaker
python
# Python — using pybreaker
import pybreaker

breaker = pybreaker.CircuitBreaker(fail_max=5, reset_timeout=30)

@breaker
def call_inventory_service(product_id: str) -> int:
    return inventory_client.get_stock(product_id)

# States: CLOSED (normal) → OPEN (failing, fast-fail) → HALF-OPEN (probing)
go
// Go — using gobreaker
import "github.com/sony/gobreaker"

cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
    Name:        "inventory-service",
    MaxRequests: 3,                // requests allowed in half-open
    Interval:    10 * time.Second, // rolling window
    Timeout:     30 * time.Second, // how long to stay OPEN
    ReadyToTrip: func(counts gobreaker.Counts) bool {
        return counts.ConsecutiveFailures > 5
    },
})

stock, err := cb.Execute(func() (interface{}, error) {
    return inventoryClient.GetStock(ctx, productID)
})
Bulkhead
python
# Isolate thread pools per downstream dependency
from concurrent.futures import ThreadPoolExecutor

_inventory_pool = ThreadPoolExecutor(max_workers=10)  # capped per service
_payment_pool   = ThreadPoolExecutor(max_workers=5)

def get_stock(product_id: str):
    future = _inventory_pool.submit(inventory_client.get_stock, product_id)
    return future.result(timeout=2)
Retry and Backoff
# GOOD: exponential backoff with jitter
attempt 1: wait 1s ± 0.5s
attempt 2: wait 2s ± 1s
attempt 3: wait 4s ± 2s
→ stop after 3 attempts, raise to caller

# BAD: retry storm
for i in range(10):
    try: call_service()
    except: continue  # hammers a degraded service

Data Management

Per-Service Database (Mandatory)
# BAD: shared database
OrderService   → SELECT * FROM payments.transactions WHERE order_id = ?
PaymentService → SELECT * FROM orders.orders WHERE user_id = ?

# GOOD: service-owned databases, expose data via API or events
OrderService   → owns orders_db (Postgres)
PaymentService → owns payments_db (Postgres)
InventoryService → owns inventory_db (Redis + Postgres)
Saga Pattern (Distributed Transactions)

Two flavours:

TypeMechanismUse When
ChoreographyEach service emits events that trigger the nextSimple flows, low coupling
OrchestrationCentral saga orchestrator drives the stepsComplex flows, explicit rollback
python
# Choreography saga — order placement
# 1. OrderService publishes order.created
# 2. PaymentService listens → charges card → publishes payment.succeeded or payment.failed
# 3. InventoryService listens to payment.succeeded → reserves stock → publishes stock.reserved
# 4. OrderService listens to stock.reserved → marks order CONFIRMED
# 5. On any failure: compensating events roll back upstream steps

# Compensating transaction example
def on_payment_failed(event):
    order_service.cancel_order(event["order_id"])   # compensation
    notification_service.notify_customer(event["customer_id"], "payment_failed")
CQRS (Command Query Responsibility Segregation)
Write path:  POST /orders        → OrderCommandHandler → orders_db (normalized)
                                 → publishes order.placed event

Read path:   GET /orders/:id     → OrderQueryHandler   → orders_read_db (denormalized view)
             GET /orders?user=X  → OrderQueryHandler   → orders_read_db (pre-joined)

Read model updated by: consuming order.placed / order.updated events

Use CQRS when read and write models have fundamentally different shapes or scale requirements.

API Gateway and BFF

API Gateway Responsibilities
Client → API Gateway → [UserService, OrderService, ProductService]

Gateway handles:
  - Authentication (JWT verification)
  - Rate limiting per client / API key
  - Request routing / URL rewriting
  - SSL termination
  - Logging and distributed trace injection (X-Request-ID, traceparent)
  - Response aggregation (optional)
Backend for Frontend (BFF)
Mobile App   → Mobile BFF   → [fine-grained internal APIs]
Web App      → Web BFF      → [fine-grained internal APIs]
Partner API  → Partner BFF  → [fine-grained internal APIs]

# Each BFF is thin: aggregate, reshape, and auth-scope data for its client
# BAD: one general-purpose gateway trying to serve all clients equally

Service Discovery

MethodHowExample
Client-sideClient queries registry, picks instanceNetflix Eureka, Consul
Server-sideLoad balancer queries registryAWS ALB, Kubernetes Service
DNS-basedUse DNS SRV recordsKubernetes (default), Consul DNS
EnvironmentInject service URLs at deploy timeDocker Compose, Helm values

Kubernetes DNS-based (simplest):

yaml
# payment-service resolves to:
# http://payment-service.payments-ns.svc.cluster.local:8080
# within the same namespace: http://payment-service:8080

Observability in Microservices

Distributed tracing is non-negotiable:

python
# Propagate trace context across services (OpenTelemetry)
from opentelemetry import trace
from opentelemetry.propagate import inject, extract

tracer = trace.get_tracer("order-service")

def place_order(order_data: dict, headers: dict):
    ctx = extract(headers)  # pull trace context from incoming request
    with tracer.start_as_current_span("place_order", context=ctx) as span:
        span.set_attribute("order.customer_id", order_data["customer_id"])
        outbound_headers = {}
        inject(outbound_headers)  # inject into outbound calls
        payment_client.charge(order_data, headers=outbound_headers)

See also: observability

Show full SKILL.md (361 more words)Show less

Red Flags

  • Services sharing a database — two services reading and writing the same table are coupled at the schema level; a migration needed by one service blocks or breaks the other, defeating the purpose of independent deployment
  • Synchronous HTTP chain more than 2 hops deep — a request that fans out through 5 services compounds each service's p99 latency multiplicatively; use async messaging for workflows that do not need an immediate response
  • No timeout on inter-service HTTP calls — an unresponsive downstream service holds goroutines/threads until the connection pool is exhausted, cascading the failure to every caller upstream
  • Saga with no compensating transaction defined — a choreography saga that publishes order.created without a cancel_order compensation path leaves partial state (charged payment, no order) when any downstream step fails
  • Consumer reading directly from the producer's database — bypassing the API to read raw DB rows creates an undocumented cross-service coupling; any schema change in the producer silently breaks the consumer
  • gRPC without deadline propagation — calling a downstream gRPC service without passing the parent context deadline means the downstream call ignores the caller's timeout and can outlive the client connection
  • Circuit breaker with the same threshold for all dependencies — a cache (millisecond latency, 99.99% uptime) and a fraud-check API (200ms, 99.9% uptime) need different fail_max and reset_timeout values; one-size config causes false trips on critical paths
  • Event consumer processing messages synchronously within eachMessage — blocking the consumer callback blocks partition consumption; use async handlers and commit offsets only after successful processing to avoid message loss

Checklist

  • Each service owns its own database — no shared tables or direct cross-DB queries
  • Service boundaries align to domain bounded contexts, not technical layers
  • All synchronous calls have explicit timeouts and retry with exponential backoff
  • Circuit breaker configured for every downstream dependency
  • Async event schemas are versioned; consumers tolerate unknown fields
  • Saga compensating transactions defined for every distributed workflow
  • API gateway handles auth, rate limiting, and trace injection centrally
  • Distributed tracing propagated across all service calls (W3C traceparent)
  • Dead-letter queues configured for all async consumers
  • Health check endpoints (/healthz, /readyz) implemented in every service
  • Services degrade gracefully when a dependency is unavailable (fallback/cache)
  • Data contracts (API schemas, event schemas) reviewed before breaking changes

© kid-sid, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/microservices of kid-sid/claude-spellbook.

Open the folder on GitHubat commit a7c2ac9

Compare with similar skills

Microservices next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Microservices compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Microservices this skillkid-sid/claude-spellbook189—~3.5kAutomated safety check: PassMIT
Golang Proantoniopaya22/go-rest-template1723 repos~1.2kAutomated safety check: PassMIT
Pixiu HTTP To Dubboapache/dubbo-go-pixiu568—~2.4kAutomated safety check: PassApache-2.0
Kratos Developmentaide-family/moon253—~1.5kAutomated safety check: PassNone
Pixiu Filter Authorapache/dubbo-go-pixiu568—~1.1kAutomated safety check: PassApache-2.0
API Design InterviewerPrepLabsAI/InterviewMentor112—~2.6kAutomated safety check: PassMIT

Similar skills

  • Golang Pro

    antoniopaya22/go-rest-template

    Implements concurrent Go patterns using goroutines and channels, designs and builds microservices with gRPC or REST, optimizes Go application performance with pprof, and enforces idiomatic Go with…

    172 GitHub starsUsed in 3 repos~1.2k tokens
    Backend & APIsAuto-check passed
  • Pixiu HTTP To Dubbo

    apache/dubbo-go-pixiu

    Creates and debugs dubbo-go-pixiu HTTP-to-Dubbo route YAML. An agent skill from apache/dubbo-go-pixiu.

    568 GitHub stars~2.4k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • Kratos Development

    aide-family/moon

    Develops Go microservices with Kratos v2 following official design philosophy, DDD/Clean Architecture layout, Protobuf API, error/config/middleware patterns, and observability.

    253 GitHub stars~1.5k tokensUpdated 3 mo ago
    Backend & APIsAuto-check passed
  • Pixiu Filter Author

    apache/dubbo-go-pixiu

    Creates and debugs dubbo-go-pixiu HTTP/Network filters. An agent skill from apache/dubbo-go-pixiu.

    568 GitHub stars~1.1k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • API Design Interviewer

    PrepLabsAI/InterviewMentor

    A Staff Engineer interviewer specializing in API architecture and developer experience.

    112 GitHub stars~2.6k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Intrinsic Core Service Authoring

    intrinsic-ai/intrinsic-core

    Intrinsic Core microservice authoring, ServiceManifest definitions (realspec vs simspec), RuntimeContext port bindings (gRPC port 1 vs HTTP port 7), SIGTERM lifecycle handling, and .binpb sideloading.

    553 GitHub stars~2.2k tokensUpdated today
    Backend & APIsAuto-check passed

More from kid-sid/claude-spellbook

All 52 skills in this repo
  • Accessibility

    kid-sid/claude-spellbook

    A skill your agent uses when building or reviewing UI components for keyboard and screen reader compatibility, adding ARIA to custom widgets, auditing a page for WCAG AA conformance, or preparing…

    189 GitHub stars~3.2k tokensUpdated 2 mo ago
    Auto-check passed
  • Agentex

    kid-sid/claude-spellbook

    A skill your agent uses when building, wiring, or debugging an Agentex agent — choosing agent type, configuring acp.py and manifest.yaml, using adk.messages or adk.state, or resolving…

    189 GitHub stars~2.2k tokensUpdated 2 mo ago
    Auto-check: notes
  • AI Engineer

    kid-sid/claude-spellbook

    A skill your agent uses when building production LLM applications — designing RAG pipelines, choosing vector databases, implementing agent orchestration, optimizing cost, or adding AI safety…

    189 GitHub stars~3.7k tokensUpdated 2 mo ago
    Auto-check passed
  • Angular

    kid-sid/claude-spellbook

    A skill your agent uses when building or refactoring Angular applications — choosing between signals, RxJS, and NgRx for state, configuring routing with guards and lazy loading, optimizing change…

    189 GitHub stars~5k tokensUpdated 2 mo ago
    Auto-check passed
  • API Design

    kid-sid/claude-spellbook

    A skill your agent uses when designing new REST endpoints, reviewing an existing API contract, adding pagination or filtering, planning a versioning strategy, or building a public or partner-facing…

    189 GitHub stars~3.6k tokensUpdated 2 mo ago
    Auto-check passed
  • Auth

    kid-sid/claude-spellbook

    A skill your agent uses when implementing login flows, issuing or validating JWTs, setting up OAuth2/OIDC with a provider, designing role-based or attribute-based access control, securing API…

    189 GitHub stars~3.2k tokensUpdated 2 mo ago
    Auto-check passed

Works with

Categories

Questions about Microservices

What does Microservices do?

A skill your agent uses when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an…. Microservices is an agent skill from kid-sid/claude-spellbook. Use when decomposing a monolith, designing inter-service communication, implementing circuit breakers or sagas, reasoning about data ownership across services, or setting up an API gateway for a distributed system.

When should I use Microservices?

Microservices fits situations like: decomposing a monolith; designing inter-service communication; implementing circuit breakers; reasoning about data ownership across services.

How do I install Microservices in Claude Code?

Run `npx skills add kid-sid/claude-spellbook --skill microservices -a claude-code`. Or copy the skill folder (skills/microservices in kid-sid/claude-spellbook) into .claude/skills/microservices in your project. Claude Code loads it when a task matches its description.

How do I install Microservices in Codex?

Run `npx skills add kid-sid/claude-spellbook --skill microservices -a codex`. Or copy the skill folder (skills/microservices in kid-sid/claude-spellbook) into .agents/skills/microservices in your project. Codex loads it when a task matches its description.

Can I use Microservices in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kid-sid/claude-spellbook --skill microservices -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/microservices, .gemini/skills/microservices, .github/skills/microservices and .opencode/skills/microservices in your project.

What does Microservices need to run?

SKILL.md names no scripts, command-line tools or credentials: Microservices is instructions for the agent only. Our summary lists: Python 3; Docker.

Does Microservices access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Microservices safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Microservices use?

Microservices is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Microservices use?

About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Microservices?

Skills that share tags, products or a category with Microservices: Golang Pro (antoniopaya22/go-rest-template, 172 stars), Pixiu HTTP To Dubbo (apache/dubbo-go-pixiu, 568 stars), Kratos Development (aide-family/moon, 253 stars) and Pixiu Filter Author (apache/dubbo-go-pixiu, 568 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Microservices?

kid-sid (a GitHub user) maintains it in kid-sid/claude-spellbook, which has 189 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on August 5, 2026.

Source: kid-sid/claude-spellbook on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.