Produces natural-language summaries of what code does at the function, class, module, or subsystem level, with length and abstraction scaled to the scope. Explains purpose, side effects, and non-obvious behavior rather than restating syntax. Use when onboarding to unfamiliar code, when the user asks what something does, when generating docstrings or architecture notes, or when preparing a handoff document.
Install with Tessl CLI
npx tessl i github:santosomar/general-secure-coding-agent-skills --skill code-summarizer100
Quality
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Say what the code is for, not what it says. "Iterates over the list and appends items where status is active" is a translation, not a summary. "Returns only the invoices that are eligible for payment" is a summary.
The answer to "what does this do" changes with how much code "this" covers. Decide up front:
| Scope | Length | Abstraction level | Goal |
|---|---|---|---|
| Single expr | 1 phrase | What value, in domain terms | Replace with a well-named variable |
| Function | 1–3 sentences | Contract: inputs → outputs → effects | A reader can call it correctly without reading the body |
| Class | 1 paragraph | Responsibility + lifecycle + main collaborators | A reader knows when to use it and when not to |
| Module / file | 2–4 paragraphs | Subsystem role + what enters/leaves | A reader can decide whether to open it |
| Package / dir | Bullets | Architectural role + public surface | A reader can navigate to the right file |
If the user doesn't specify scope, infer from what they pasted: 10 lines → function-level; 500 lines → module-level; a directory path → package-level.
You don't read a 300-line function top-to-bottom to summarize it. You scan for high-information locations:
process or handle, skip to step 2.test_rejects_expired_token tells you more about the function's purpose than its body does.Before writing anything else, complete: "This exists so that ___." If you can't, you don't understand it yet — go back to Step 2.
Good patterns:
Bad patterns (translation, not summary):
After the purpose sentence, add only things that are true, not obvious from the signature, and would change how a caller uses it:
audit_log table on every call." Always worth stating — they're invisible from the signature.QuotaExceededError rather than returning null" — if there's a choice a reasonable person might get wrong.items is already sorted by timestamp."Leave out what the types already say, what any function in this language does (e.g., "returns a value"), and any uncertainty you'd be guessing at.
<One-sentence purpose, active voice.>
<Side effects, if any. Be specific.>
<Error behavior, if non-obvious.>
<Preconditions or cost warnings, if any.>Example. For:
def reconcile(ledger, bank_txns):
matched, unmatched = [], []
for txn in bank_txns:
entry = ledger.find(amount=txn.amount, date_within=timedelta(days=3))
if entry and not entry.reconciled:
entry.reconciled = True
matched.append((entry, txn))
else:
unmatched.append(txn)
ledger.save()
return matched, unmatchedBad (translates): "Iterates over bank transactions, calls ledger.find for each, checks if reconciled, appends to matched or unmatched lists, then saves the ledger."
Good (summarizes): "Matches bank transactions against ledger entries by amount within a 3-day window, marking each matched entry as reconciled. Persists the ledger. Returns (matched pairs, unmatched transactions). A transaction with no same-amount entry in the window, or whose entry is already reconciled, lands in unmatched."
The good version lets a caller predict behavior without reading the body. The bad version just makes them read the body slower.
Don't list every method. Answer: what is this class responsible for, and what does it deliberately leave to others?
RateLimiter
Tracks request counts per client and decides whether to admit or reject
the next request. Uses a sliding window — a client at the limit is
rejected until its oldest counted request ages out, not until a fixed
interval elapses.
State is in-memory only. Does not persist across restarts; does not
coordinate across instances. For distributed limiting, wrap a shared
store.
Thread-safe (internal lock). Not async-safe — do not `await` while
holding a reference to a window.Note: "what it doesn't do" (persist, coordinate) is as valuable as what it does.
At module scope, the reader is deciding whether to open this file. Tell them what crosses the boundary:
payments/stripe_adapter.py
Isolates all Stripe SDK usage behind four operations: charge, refund,
subscribe, cancel. The rest of the codebase speaks in our `Payment` and
`Subscription` types and never imports `stripe` directly.
Incoming: our domain types + tenant config (API key per tenant).
Outgoing: Stripe HTTP; audit log; `payment.completed` event on the bus.
Stripe errors are caught here and re-raised as our `PaymentError`
hierarchy — callers never see raw Stripe exceptions. Retries transient
failures (5xx, rate limits) internally with backoff.config.VALIDATION_MODE at call time."foo() — behavior depends on that."invoice, say invoice — don't genericize to "the object" or "the record."47d56bb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.