Naming conventions¶
Recorded so the choices are deliberate rather than accidental, and so the next person adding a module does not have to guess.
Identifiers¶
| Layer | Convention | Value |
|---|---|---|
| Project name | Title Case | Science ADK |
| PyPI package | lowercase, hyphenated | science-adk |
| npm package | lowercase, hyphenated | science-adk |
| Python import | snake_case |
science_adk |
| Console command | lowercase, hyphenated | science-adk |
| Skill directories | kebab-case |
experiment-design, agent-authoring |
Skill frontmatter name |
kebab-case, matching the directory |
name: experiment-design |
| Classes | PascalCase |
Agent, AlgorithmAgent, ToolRegistry |
| Environment variables | SCIENCE_ADK_* |
SCIENCE_ADK_TOOLS_TOKEN |
One name, science-adk, across npm, PyPI and the command line. A researcher
who has typed it once can type it anywhere.
Class names are unprefixed¶
Agent, not ScienceAgent. The package name already supplies the qualifier,
and from science_adk import ScienceAgent stutters. Anyone needing to
disambiguate can write import science_adk and refer to science_adk.Agent.
The same reasoning applies throughout: Workflow, Runner, Score, Project.
Inside a package called science_adk, a prefix on every class is noise.
Tool names are namespaced by provider, not by domain¶
Tools resolve as provider.tool, where the provider is whatever the project
called it in science.toml:
giving pubchem.search. Unqualified names resolve when unambiguous, so agent
code reads await self.call_tool("search") and only qualifies on a conflict.
A fixed taxonomy — science_<domain>_<action> — was considered and rejected.
Third-party MCP servers name their own tools and we cannot rename them without
lying about what we are calling. Provider namespacing gives the same collision
safety while telling the reader something true: where the tool came from.
No vendor prefix on the package¶
The kit works with Claude Code, Cline, Cursor, Antigravity and OpenCode, and with any MCP server. Prefixing the package with one vendor's name would misdescribe it, and would imply an endorsement that has not been given.
It depends on google-adk and says so plainly in the README. A dependency is
not an affiliation.
The import namespace is flat¶
science_adk, not google.adk.science. Extending another project's namespace
package requires coordination with its maintainers, couples our release
cadence to theirs, and produces confusing failures when the namespace package
is only partly installed. A flat top-level import costs nothing and belongs to
us.
Interoperability does not depend on where the module sits. science_adk.Agent
subclasses google.adk.workflow.Node, so an experiment is an ADK agent
regardless of its import path.
Relation to standard Google Cloud naming conventions¶
Standard Google Cloud developer patterns and PyPI ecosystem conventions suggest a different ordering for packages built on ADK:
| Context | Standard convention | Our choice | Why we diverge |
|---|---|---|---|
| PyPI package | adk-science or google-adk-science |
science-adk |
One name across npm, PyPI, and the CLI. A researcher who has typed it once can type it anywhere. |
| Python import | google.adk.science or adk_science |
science_adk |
Extending another project's namespace package couples release cadence and creates partial-install failures. A flat import costs nothing and belongs to us. |
| CLI command | adk-science |
science-adk |
Same name as the package. No mapping to remember. |
| Vendor prefix | google-adk-science |
none | The kit works with multiple coding agents and any MCP server. A dependency is not an affiliation. |
| Classes | ScienceAgent |
Agent |
The package already supplies the qualifier. |
The adk-<capability> pattern makes sense for official ADK extensions
maintained inside the ADK repository. Science ADK is a standalone,
domain-specific framework that depends on ADK but releases independently,
so science-adk (domain first) is the correct form — consistent with the
"ADK Skill / Workspace Directory" row in the standard table itself.
Adding something new¶
- A module: lowercase, one word if possible (
score.py,runner.py). - A skill:
kebab-casedirectory, frontmatternamematching it exactly, and a description saying when to use it rather than what it contains. - A class:
PascalCase, noScienceprefix. - An environment variable:
SCIENCE_ADK_*, and document it inscience.tomlas atoken_envrather than reading it implicitly.