functionality-scan
Skill3 starsChanged 31 days agoMITView on GitHub
Describes what the software actually does, reverse-engineered from the code: purpose and audience, feature inventory, entry points (commands, endpoints, screens, hooks), end-to-end workflows, managed data, integrations, hidden or dormant behaviour, and where the docs disagree with the code. Use for "what does this codebase do", a feature list, a product manual, a capability inventory, or a README-vs-code check.
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 0 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Write findings, validate, render, and report per the core workflow.
- Very specific: line 75
When the intent behind a gap is unclear (deliberately unlisted power-user flag vs.
- Very specific: line 81
After a first successful run on a project that already has a combined-report.json, re-run merge_findings.py (see the core skill) so the …
- Very specific: line 85
Follow the core workflow: write _sokrates/reports/ai-insights/functionality-scan.json, validate until OK, render the explorer, report …
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Functionality scan
Ask three people what a system does and you get the README's aspiration, the last release's changelog, and one engineer's mental model — none of them the code. This scanner writes the functional description from primary sources: for each thing the software can do, where a user reaches it, what it does, what data it touches, and how it is switched on. The product is the manual a maintainer would sign off on: complete enough for a handover, honest about what is half-built, and explicit where the documentation and the code disagree.
First read sokrates-scan-core/SKILL.md (sibling skill) — output format, evidence rules, validate/render scripts, _sokrates data layout. This file adds only what is specific to describing functionality.
Scope boundaries with sibling scanners
domain-language-scannames the concepts (the nouns) and maps capability families onto components; this scanner describes the behaviour (the verbs) — what a user can do, through which surface, with what outcome. Infull-scanthis scanner runs first, so the domain map reuses the feature inventory as its capability list; do not re-derive the glossary here.architecture-scanexplains how the parts are structured. Split on a shared surface such as an RPC protocol: this scanner owns which methods exist and what they do; the architecture scan owns how the protocol is versioned, layered and transported. Name the component a feature lives in (sokrates_refs), but leave component responsibilities and boundaries to the architecture scan.tech-stack-scaninventories technologies; an integration is a feature here only when it does something for the user (sync to a calendar, deploy to a cloud), not merely when a library is linked.security-scan(witharchitecture-scan's security boundaries) andobservability-scanown security and telemetry behaviour. Mention them inside a feature only where they are user-facing (an approval prompt, an opt-out flag) — citing the approval enum to make a feature description honest is fine; describing the policy model is not.cicd-scanowns packaging, install channels and containers; here they appear only inpurpose(how the software is obtained) unless the packaging changes what a user can do.evolution-scanrecords deprecations and retired experiments as history; this scanner records their present user-facing consequence (still reachable, still documented). Cross-reference rather than duplicate: put the sibling finding's id insokrates_refsasfinding:<id>— only ids you have actually seen in the sibling file (list them first); never guess an id.- If sibling findings already exist in
_sokrates/reports/ai-insights/, read theirsummaryandstatsfirst and reuse their component names. When a domain map withcapabilities/*findings already exists, align your feature clusters to its family names and cross-reference them (finding:<id>) rather than inventing a competing grouping. For shared data stores, this scanner owns what is in the store and its lifecycle; the architecture scan owns the contract and its versioning. Every evidence citation must still be minted from files you read in this run.
Workflow
The realistic reading strategy for anything beyond a small project is registration tables, not handlers: the subcommand enum, the slash-command table, the route or RPC-method macro, the menu definition, the feature-flag registry, the config schema. These few files enumerate the entire functional surface; one load-bearing line from a handler per feature then anchors the behaviour. Do not try to trace every handler end to end — spend that depth on the handful of features every workflow passes through. Sokrates hotspots and churn are weak guides for this scanner (they point at engines, not surfaces); the component list and file inventory are what you need, and data.zip can be skipped.
- Orient per the core skill:
config.jsonfor components and ignores; sibling scanners' summaries if present. Read the README and user docs last, not first — form the picture from code, then compare. Documentation the harness injects before you start (aCLAUDE.md,AGENTS.md) is documentation too: treat it as claims to be checked, never as ground truth — it is a rich source of gaps. - Find the entry points. Enumerate every surface from the code that registers it: CLI commands and argument parsers, HTTP/RPC route tables and API schemas, UI screens and menus, message or event handlers, scheduled jobs, plugin or hook registration, configuration keys. Every feature below must hang off at least one entry point, and every command, route, screen or hook must be accounted for by some feature or filed as hidden/dormant. Configuration keys are covered by naming them in the surface finding and in the features that consume them — not by one line each. Counting convention, so runs agree: count registered variants in the dispatch table (enum variants, route entries); report aliases, platform-gated entries, hidden entries, and legacy/compat duplicates as separate keys rather than folding them in; report the documented count separately when it differs.
- Describe each feature. Pick the 10–20 features that carry the product. For each: entry point, inputs, what it computes or changes, what it persists or sends, what the user gets back, what fails it. Depth is proportional to weight — a feature every workflow passes through gets a read of its handler; a peripheral command gets its doc comment and one decisive line.
- Reconstruct the workflows. Features combine into the sequences users actually perform: setup, the core loop, the exceptional paths (recovery, undo, migration). Describe 3–6 workflows as ordered steps, each step naming the feature it uses and the state it leaves behind. Workflows are where hidden prerequisites surface ("nothing works until X is configured").
- Inventory the data. What the system stores (files, databases, caches, remote state), in what shape, where, with what lifecycle, and which features own it — and what leaves the machine (telemetry, uploads, sync targets; this belongs to
data, notintegrations). - Map integrations. External systems the software talks to as functionality: services called, protocols spoken, formats imported and exported, tools driven or driving it. State what each enables and what happens when it is unavailable.
- Hunt the hidden and the gaps. Feature flags and experiments (defaults, who can flip them), undocumented commands and flags, dead or dormant features still wired in, stubs on user-visible paths, and every place the README, help text or docs promise something the code does not do — or the code does something the docs never mention. Each gap cites both sides.
- Write findings, validate, render, and report per the core workflow. Fields:
scanner: "functionality-scan",scanner_version: "1.0".
Group taxonomy
| group | contents |
purpose | The one-page answer: what the software is, for whom, what problem it solves, what it deliberately is not, and the feature families at a glance. It names the product surfaces and how they relate; it does not describe them (that is entry-points). One or two findings, the first thing a newcomer reads |
features | The feature inventory: one finding per feature (or tight feature cluster), each with entry point(s), inputs, behaviour, outputs, failure modes, and the component that implements it |
entry-points | The surfaces through which functionality is reached, one finding per surface family (the CLI command set, the HTTP/RPC API, the UI navigation, the hook/plugin protocol, the configuration file): what is exposed, how it is versioned, which entries are undocumented, and — for entries not described as features — a one-line behaviour each |
workflows | End-to-end user journeys as ordered steps, each step tied to a feature, with prerequisites, state left behind and exceptional paths |
data | What the system manages: stores shared across features or with their own lifecycle, and what leaves the system |
integrations | External systems as functionality: what each enables, how it is configured, and the behaviour when it is absent |
hidden-and-gaps | Flags and experiments, undocumented or dormant functionality, stubs on user-visible paths, and documentation-versus-code disagreements in both directions |
Tie-breakers, settled once so runs agree:
- A feature reachable from several surfaces is described once in
featureswith all its entry points listed (attributes.entry_points,attributes.surfacesas lists); eachentry-pointsfinding just points to it. - Flags mean anything that switches user-visible behaviour: feature-flag registries, experiments, and plain configuration booleans alike (a CLI's
skipXswitches count). When the project has a central feature-flag table, write onehidden-and-gapsfinding for the registry (counts by stage, defaults, how users flip them, stale keys still parsed) and add aflagsattribute only to the features whose behaviour a flag materially changes. Without a registry: a flag gating a shipped feature is an attribute of that feature; a flag gating unshipped behaviour is its ownhidden-and-gapsfinding. - Shipped but off by default is a
featuresfinding withstatus: shipped-off-by-default; it becomeshidden-and-gapsonly when nothing documents how to turn it on. - Documented but unimplemented (a config section nothing reads, a report page nothing fills, a documented option the parser rejects) is one
hidden-and-gapsfinding, not afeaturesfinding withstatus: stub—stubis for functionality that is registered on a surface but does nothing. - Runtime dependencies of the software's output (generated reports that load scripts from a CDN, exported files that need an external viewer) are
integrations: the decisive attribute is what happens when they are unavailable. - Deprecated surfaces are described in
entry-points(withstatus: deprecated); a separatehidden-and-gapsfinding exists only if the docs or help text still present the surface as current, or no replacement is named. - The data a single feature owns lives inside that feature's finding;
datafindings cover shared stores and what leaves the machine.
What a good finding looks like
A feature finding's evidence is the registration line (the subcommand variant, the route, the menu entry) plus one line from the handler that shows the load-bearing behaviour — two or three citations, not a tour. The description reads like a manual page written by someone who read the implementation: "codex resume lists sessions from ~/.codex/sessions, picks the selected rollout and replays it into a new turn; it fails with no sessions found when the directory is empty" — behaviour, location, failure, in that order.
Structured facts go in attributes: entry_points (list), surfaces (list drawn from cli, api, ui, config, env, hook, job, library, mcp), status (shipped, shipped-off-by-default, experimental, deprecated, stub), flags (list; keep the project's own flag names, and its own stage vocabulary in flag_stage if it has one), component.
A workflow finding's description is the numbered sequence; its evidence is the two or three steps where the sequence is actually decided in code (the dispatch, the precondition check), not one citation per step — the core evidence cap applies. Inferred ordering is likely, not certain.
A gap finding cites both sides with the evidence note saying which is which: the promise (README line, help text, doc comment) and the code that breaks it — or, for undocumented behaviour, the code and the nearest documentation that should have mentioned it.
Almost everything here is info — this scanner's product is a description, not an alarm. Expected shape: 10–20 features, and 2–5 each of the other groups; total around 25–40 on a large project. Merge over split, and cluster minor variants (the --json output flag of every command) into the feature or surface they belong to.
Severity calibration
medium— documentation or help text that promises behaviour the code does not implement on a main path (a documented command that is a stub, a described safeguard that is not wired), or a user-visible path that silently does nothing.low— undocumented user-facing functionality that matters (commands, flags, environment variables users would want to know), dormant features still reachable, experiments on by default without documentation, deprecated surfaces still documented as current.info— the description itself: purpose, features, entry points, workflows, data, integrations, and documented flags.
When the intent behind a gap is unclear (deliberately unlisted power-user flag vs. forgotten documentation), say so and mark confidence possible — reading a design decision as an omission is this scanner's main failure mode.
Practical notes
- Before choosing line numbers, run a small Python script that prints
path:line: textfor the candidate lines and paste from its output intosnippet— every off-by-one in testing came from counting insidesedwindows. Prefer lines without escaped quotes (JSON-in-JSON escaping is where citations break). If a cited line is slightly off, the validator reports where the snippet actually is; multi-line snippets tolerate leading-whitespace differences. - On a re-run, keep the previous
functionality-scan.jsonas a diff baseline outside the findings folder (a scratch directory) — anything left inside it is picked up byrender/mergeas another scanner file. Keepscanner_versionat1.0unless the skill's taxonomy changes; new or changed findings do not bump it. - After a first successful run on a project that already has a
combined-report.json, re-runmerge_findings.py(see the core skill) so the combined report includes this scanner.
Output
Follow the core workflow: write _sokrates/reports/ai-insights/functionality-scan.json, validate until OK, render the explorer, report leading with the purpose statement in one paragraph (what it is, for whom, the five or so feature families) followed by the hidden-and-gaps findings.
Use these stats keys where they apply (canonical, counting things in the software, never findings — example numbers fictional): features_described, entry_points_by_surface (an object, e.g. {"cli_subcommands": 9, "rpc_methods": 99} — a single total across surfaces is not meaningful), surfaces (the number of distinct values used in attributes.surfaces across findings, from the fixed list cli, api, ui, config, env, hook, job, library, mcp; a GUI is its own surface even when it calls the CLI underneath, while an SDK that merely wraps a CLI counts under that CLI), workflows_described, data_stores_found, integrations_found, flags_found (config switches included; flags_by_stage when the project has stages), model_tools_found (agent products only: first-party tool names in the handler specs, excluding tools discovered at runtime from MCP servers), doc_code_gaps_found (distinct documentation-versus-code disagreements — the one stat that is allowed to count what the gap findings describe; it may differ from the number of hidden-and-gaps findings), e.g. {"features_described": 9, "entry_points_by_surface": {"cli_subcommands": 9, "rpc_methods": 99}, "surfaces": 9, "workflows_described": 9, "data_stores_found": 9, "integrations_found": 9, "flags_found": 99, "doc_code_gaps_found": 9}. Omit keys that do not apply (a CLI without flags reports no flags_found rather than 0). Add extras freely alongside.
In this repository27 other files it gives its agents.
- sokrates-decompositionsSkill
- sokrates-features-of-interestSkill
- sokrates-landscape-configSkill
- sokrates-people-configSkill
- sokrates-repo-configSkill
- sokrates-virtual-landscapesSkill
- sokrates-improveSkill
- architecture-scanSkill
- cicd-scanSkill
- configuration-scanSkill
- domain-language-scanSkill
- evolution-scanSkill
- full-scanSkill
- iac-scanSkill
- landscape-synthesis-scanSkill
- maintainability-scanSkill
- network-scanSkill
- observability-scanSkill
- performance-scanSkill
- reliability-scanSkill
- risk-synthesis-scanSkill
- security-scanSkill
- sokrates-scan-coreSkill
- storage-scanSkill
- tech-stack-scanSkill
- testing-scanSkill
- sokratesSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

