Version: 1.0.0 Schema version: 2 Date: 2026-04-13
Citation CLI is a code distribution pattern where reference implementations are cited into consumer projects as organic code rather than imported as dependencies. This specification defines the metadata schema that tracks which code was cited, from where, and at what level of engagement — Quote, Paraphrase, or Synthesize.
The citation metaphor is literal. In any academic or intellectual discipline, there are exactly three ways to use a source:
Each level implies deeper introspection, which is exactly what the pattern encodes.
pyproject.toml)Citation metadata lives under [tool.citation] following
PEP 518 conventions for
tool-specific configuration.
[tool.citation.packages.<entry-name>]
schema = 2
source = "<path-or-url>"
version = "<semver>"
target = "<local-path>"
cited = "<YYYY-MM-DD>"
[tool.citation.packages.<entry-name>.files]
"<filename>" = { status = "quote", sha256 = "<hash>" }
"<filename>" = { status = "paraphrase" }
"<filename>" = { status = "synthesize", into = "<consumer-file>" }
package.json)Citation metadata lives under the "citation" top-level key.
{
"citation": {
"packages": {
"<entry-name>": {
"schema": 2,
"source": "<path-or-url>",
"version": "<semver>",
"target": "<local-path>",
"cited": "<YYYY-MM-DD>",
"files": {
"<filename>": {
"status": "quote",
"sha256": "<hash>"
},
"<filename>": {
"status": "paraphrase"
},
"<filename>": {
"status": "synthesize",
"into": "<consumer-file>"
}
}
}
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
schema |
integer | yes | Schema version (currently 2) |
source |
string | yes | Path or URL to the reference |
version |
string | yes | Semver of the reference at citation time |
target |
string | yes | Local directory where files were placed |
cited |
string | yes | ISO date (YYYY-MM-DD) of citation |
source can be:
"../packages/agent-harness""/home/user/refs/agent-harness""https://github.com/org/repo/tree/main/packages/x"entry-name is a user-chosen identifier for this citation.
When the same reference is cited into multiple targets, use
distinct entry names (e.g., agent-harness-claude,
agent-harness-codex).
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | yes | One of: quote, paraphrase, synthesize |
sha256 |
string | quote only |
Hash of the file at citation time |
into |
string | synthesize only |
Consumer file where code was absorbed |
quoteThe file was copied without modification — a verbatim citation.
The sha256 field records the hash at citation time, enabling
integrity checks: if the local file’s hash differs from the
recorded hash, it was modified outside the citation workflow.
A quote is a conscious choice. You are saying: this code, exactly as it is, is what I need.
paraphraseThe file was copied and then intentionally rewritten in the consumer’s terms. The logic stays, but the code has been adapted to fit the consumer’s style, idioms, or surrounding architecture. No hash is recorded because divergence is the point.
A paraphrase means you understood the source well enough to restate it.
synthesizeThe file’s contents were absorbed into an existing consumer file.
There is no standalone copy of the reference file in the consumer
project. The into field records which consumer file absorbed the
code.
This is the most “organic” placement mode — the cited code becomes indistinguishable from the consumer’s own code. A synthesis means you internalized the source completely.
When the reference package is updated, consumers can propagate changes using these rules:
| File status | Action on update |
|---|---|
quote |
Replace file, update sha256, version, cited |
paraphrase |
Do not overwrite. Flag for review |
synthesize |
Do not touch. Flag for review |
Additional rules:
quote to the consumer.Propagation can be performed by an AI coding agent reading the
[tool.citation] metadata, or by the forthcoming cite sync
command.
A monorepo with a reference package cited into two backends:
# pyproject.toml
[tool.citation.packages.harness-claude]
schema = 2
source = "../packages/agent-harness"
version = "0.6.0"
target = "culture/clients/claude"
cited = "2026-04-13"
[tool.citation.packages.harness-claude.files]
"daemon.py" = { status = "paraphrase" }
"agent_runner.py" = { status = "paraphrase" }
"supervisor.py" = { status = "paraphrase" }
"irc_transport.py" = { status = "quote", sha256 = "e3b0c44..." }
"message_buffer.py" = { status = "quote", sha256 = "a7ffc6f..." }
"socket_server.py" = { status = "quote", sha256 = "2c26b46..." }
"ipc.py" = { status = "quote", sha256 = "fcde2b2..." }
"webhook.py" = { status = "quote", sha256 = "d7a8fbb..." }
"config.py" = {
status = "synthesize",
into = "culture/clients/claude/settings.py",
}
[tool.citation.packages.harness-codex]
schema = 2
source = "../packages/agent-harness"
version = "0.6.0"
target = "culture/clients/codex"
cited = "2026-04-13"
[tool.citation.packages.harness-codex.files]
"daemon.py" = { status = "paraphrase" }
"agent_runner.py" = { status = "paraphrase" }
"supervisor.py" = { status = "paraphrase" }
"irc_transport.py" = { status = "quote", sha256 = "e3b0c44..." }
"message_buffer.py" = { status = "quote", sha256 = "a7ffc6f..." }
"socket_server.py" = { status = "quote", sha256 = "2c26b46..." }
"ipc.py" = { status = "quote", sha256 = "fcde2b2..." }
"webhook.py" = { status = "quote", sha256 = "d7a8fbb..." }
"config.py" = { status = "quote", sha256 = "b5bb9d8..." }
Note how the same reference package is cited differently: Claude’s
backend synthesized config.py into its own settings.py, while
Codex kept it as a quote.
When you encounter [tool.citation] in a pyproject.toml or
"citation" in a package.json:
Citation CLI supersedes the earlier Assimilai project. The schema and vocabulary map one-to-one:
| Assimilai v1 | Citation CLI v1 |
|---|---|
[tool.assimilai] |
[tool.citation] |
"assimilai" (package.json) |
"citation" (package.json) |
assimilated field |
cited field |
status verbatim |
status quote |
status adapted |
status paraphrase |
status dissolved |
status synthesize |
(no schema field) |
schema = 2 |
To migrate an existing manifest, run:
cite migrate # rewrite pyproject.toml or package.json in place
cite migrate --dry-run # preview the translation
The migrator refuses to run if a [tool.citation] block already
exists, and errors on any unknown file status.