Agent and CLI for data quality in storage and retrieval — validating, deduplicating, and checking the integrity and freshness of data as it is stored and fetched. Split out of eidetic-cli so eidetic keeps agent-memory; sibling to daria, the Data Refinery Intelligent Agent.
Project description
data-refinery-cli
Agent and CLI for data quality in storage and retrieval — validating, deduplicating, and checking the integrity and freshness of data as it is stored and fetched. Split out of eidetic-cli so eidetic keeps the agent-memory layer; sibling to daria, the Data Refinery Intelligent Agent.
What this owns
data-refinery-cli owns the storage + data-quality infrastructure layer for the AgentCulture mesh (issue #1): the mongo + neo4j substrate, the docker stack published to GHCR, and a consumer-agnostic data-quality surface. It treats stored data as opaque documents — it never interprets them as "memories." eidetic-cli is the first consumer, over a subprocess-not-import boundary; the layer is reusable by any agent that needs a dependency-light store plus quality checks.
The split ships in waves:
| Wave | Scope | Status |
|---|---|---|
| 1 | docker stack (mongo 27018 + neo4j 7687), GHCR publish, stack CLI verb, pinnable contract |
shipped |
| 2 | generic storage envelope + importable store API, files/mongo/neo4j adapters (optional [store] extra), data-quality verbs (validate, dedup, integrity, freshness) |
shipped |
| 3 | full pinnable verb contract + eidetic consumption over the process boundary | planned |
The runtime package has no third-party dependencies by default; the heavy
store drivers (neo4j, pymongo) live behind the optional [store] extra and
are lazy-imported, so the files backend (the default) stays dependency-free.
Quickstart
uv sync
uv run pytest -n auto # run the test suite
uv run data-refinery stack up # bring up mongo + neo4j (needs docker)
uv run data-refinery stack status --json
uv run data-refinery stack down
uv run data-refinery whoami # identity from culture.yaml
uv run teken cli doctor . --strict # the agent-first rubric gate CI runs
# Store + quality (files backend is dependency-free; no docker needed):
echo '{"id":"a","content":"hello"}' | uv run data-refinery store put --json
echo '{"id":"m","content":"noted"}' | uv run data-refinery store put --type memory --json
uv run data-refinery store get a --json
uv run data-refinery store list --json
uv run data-refinery store list --type memory --json # filter by envelope type
uv run data-refinery store migrate --json # re-canonicalise own JSONL (idempotent)
uv run data-refinery integrity --json # hash matches content?
uv run data-refinery dedup --json # collapse same-hash dups (idempotent)
echo '{"id":"a","content":"x"}' | uv run data-refinery validate --json
The store is also importable — shell out or import data_refinery.store:
import data_refinery.store as store
store.put(store.Envelope(id="a", content="hello"))
store.get("a") # -> Envelope | None
store.list() # -> list[Envelope]
# Upgrade a populated legacy store to the current Envelope format — the consumer
# supplies only a transform, never a filesystem write path (data-refinery owns it):
store.migrate(record_to_envelope, base_dir="/path/to/store")
# Opt-in: write a fail-closed .gitignore so private shards stay out of git
# (files backend only; default off, byte-identical when omitted):
store.put(env, backend="files", base_dir="/path/to/store", write_gitignore=True)
CLI
| Verb | What it does |
|---|---|
stack up|down|status |
Manage the storage substrate (mongo + neo4j) via docker compose. |
store put|get|list |
Put/get/list opaque envelopes (--backend files|mongo|neo4j). |
store migrate |
Re-canonicalise the store's own Envelope-JSONL (atomic, idempotent); consumers import store.migrate(transform) to upgrade a legacy store. |
validate |
Check envelope shape for JSON piped on stdin. |
dedup |
Collapse same-hash-same-scope duplicates in the store (idempotent). |
integrity |
Check every stored hash matches sha256(content). |
freshness |
Report age/staleness facts from a metadata timestamp field. |
whoami |
Report this agent's nick, version, backend, and model from culture.yaml. |
learn |
Print a structured self-teaching prompt. |
explain <path> |
Markdown docs for any noun/verb path. |
overview |
Read-only descriptive snapshot of the agent. |
doctor |
Check the agent-identity invariants (prompt-file-present, backend-consistency). |
cli overview |
Describe the CLI surface itself. |
The envelope is storage-neutral — {id, type, hash, content, scope{name, visibility}, metadata} with no memory semantics — and the store enforces a
public/private scope no-leak: a private-scope document is never returned by a
public-scope fetch, across every backend. type (default document) describes
what the record is and is orthogonal to scope: scope isolates, type
describes; type never affects dedup or privacy. The neo4j backend also projects
a derived node label from the type (e.g. type="memory" → :Document:Memory).
Every command supports --json. Results go to stdout, errors/diagnostics to
stderr (never mixed). Exit codes: 0 success, 1 user error, 2 environment
error (e.g. docker absent — always with a hint:, never a traceback), 3+
reserved.
The storage stack
docker-compose.yml brings up mongo:8.0 on host port
27018 (not 27017 — deliberate collision-avoidance) and neo4j:5-community
on 7687 (bolt) + 7474 (UI) with apoc and no auth. The ports and auth
match eidetic-cli's historical defaults exactly, so a consumer connects with
zero config change. It is published to GHCR as a versioned OCI artifact (and
attached to each release); see docs/stack-image.md for
the image name + tag scheme and docs/contract.md for the
contract a consumer pins.
Names
Three names that differ on purpose:
- CLI command (the binary):
data-refinery - PyPI dist + mesh nick:
data-refinery-cli - Python package / import:
data_refinery
uv run data-refinery-cli … fails — the binary is data-refinery. See
CLAUDE.md for the full convention.
Contributing
See CLAUDE.md for the conventions that gate merges
(version-bump-every-PR, the cicd PR lane, dependencies = [] invariant, the
agent-first rubric) and docs/skill-sources.md for the
vendored skill provenance.
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file data_refinery_cli-0.11.0.tar.gz.
File metadata
- Download URL: data_refinery_cli-0.11.0.tar.gz
- Upload date:
- Size: 263.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d0e8646db320372529f34b5cc3fca86d517fcb18cc09836dd09007d12b9c873
|
|
| MD5 |
4203b52358ee13aabf8d85bc607ed5d1
|
|
| BLAKE2b-256 |
b3862a32e48d22ea9004cf3ac57a813e5643477ab7f8d421ab24614f60478311
|
File details
Details for the file data_refinery_cli-0.11.0-py3-none-any.whl.
File metadata
- Download URL: data_refinery_cli-0.11.0-py3-none-any.whl
- Upload date:
- Size: 72.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ea7d0738d33da67ba853ea79ee68cec87c65349c7f1755514025eb5c88ebff8
|
|
| MD5 |
f4ded3b21c5ee1cde0c95d6419bed9f3
|
|
| BLAKE2b-256 |
d86314d89a6b005ab97205be9bd57292b04e6cb9f626a12df6f7a6760bcc258a
|