MemtraceDOCS

memtrace governBeta

Point-at-anything classification for governance docs — ADRs, standing rules, agent-rule files — through the real MemCortex oracle, plus add/edit for manually asserting a doc the classifier misses. Safe for CI.

Usage#

memtrace govern <path|glob> [--exclude a,b,c] [--accept-all]Beta
memtrace govern add|edit <path> --type <adr|agent_rule|standing_rule> --guidance <text> [--scope a,b] [--ban]Beta

memtrace govern classifies governance documents — ADRs, standing rules, and agent-rule files — under a file, directory, or glob, then prints a grouped-count summary. It's the point-at-anything escape hatch for governance docs the zero-config sweep doesn't discover on its own.

Classification runs through MemCortex's real classify_governance_doc oracle over cortex.sock — the same oracle the automatic intake path uses to ingest — so what you see in the preview never diverges from what would actually be ingested. The sweep form itself is read-only and non-interactive, which makes it safe to run in CI.

There is a second, separate form: memtrace govern add/edit. It bypasses the classifier entirely and directly asserts a single doc's governance category, guidance, and scope — see add / edit — manual override below. Everything on this page up to that section describes the read-only classify/sweep form only.

REVIEW AND CONFIRM HAPPENS IN THE DASHBOARD

The sweep form only classifies and prints — it never writes a confirmation. The interactive review/confirm screen lives in the dashboard's Cortex tab, under its Governance sub-view — run memtrace start and open localhost:3030. That same sub-view also has a manual-add form mirroring govern add/edit.

Targeting a file, directory, or glob#

Exactly one positional target is accepted; a second positional is a usage error. Three forms:

  • A single file — classified as-is.
  • A directory — swept recursively for *.md/*.mdc files plus the bare agent-rule filenames .cursorrules/.windsurfrules. Dot-directories are skipped, except .cursor, .claude, .windsurf, .devin, and .github — so agent-rule ecosystems stay reachable.
  • A glob — anything containing * or ?, walked from its longest literal directory prefix (never blindly from / or .). Quote it so your shell doesn't expand it first. Unlike a directory target, a glob walk skips all dot-files and dot-directories.

A target that's neither an existing file/directory nor glob-shaped is treated as a typo: govern prints "does not exist and does not look like a glob pattern" and exits 2.

Flags#

FlagDescription
--exclude <a,b,c>Comma-separated path fragments. Any matched file whose path contains one of the fragments as a substring (not a glob) is dropped from the inventory before classification. Whitespace around segments is trimmed and empty segments are discarded. Also accepts --exclude=a,b form.
--accept-allStill accepted but not wired to any write path on the sweep form — reserved for a future confirm-writing flow. When passed, the command prints an explicit note that no confirmations were written, and points at memtrace govern add, the dashboard's Governance Review screen, or the confirm_governance MemCortex tool instead. If you want to write a confirmation today, use govern add/edit or the dashboard.
--help, -hPrint govern's own usage/help text to stderr and exit 0.

add / edit — manual override#

memtrace govern add <path> --type <adr|agent_rule|standing_rule> --guidance <text> [--scope a,b] [--ban]Beta
memtrace govern edit <path> --type <adr|agent_rule|standing_rule> --guidance <text> [--scope a,b] [--ban]Beta

add and edit are a separate verb from the sweep form above, not a target path or glob. Where memtrace govern <path|glob> only classifies and prints, add/edit skip the classifier entirely and write a governance confirmation directly — for a doc the classifier misses, gets wrong, or that lives somewhere the zero-config sweep doesn't reach. It requires MemCortex to be reachable (memtrace start), the same as the sweep form.

add and edit are literally the same operation. MemCortex's confirm_governance replaces any existing confirmation for a given doc path wholesale — it's a current-state table, not an append log — so re-running the command against the same path with new flags is how you edit one. There's no partial merge: omitting --scope or --ban on a re-run clears them, it doesn't preserve whatever was confirmed before. Both verbs require --type and --guidance every time.

FlagDescription
<path>Required positional. A single existing file — never a directory or glob, unlike the sweep form. Resolved to a repo-relative, forward-slash-normalized path under the file's git root before being sent to MemCortex.
--type <adr|agent_rule|standing_rule>Required. Which of the three governance shapes this doc plays. An unrecognized value prints the accepted set and exits 2.
--guidance <text>Required, and must be non-empty — an ungrounded assertion with no explanation of what it governs defeats the point of asserting it. Becomes the decision's epitome, the exact text surfaced back by preflight and decision-recall.
--scope <a,b>Optional, comma-separated selectors in MemCortex's scope vocabulary (path:, repo:, lang:, ext:, service: — e.g. path:apps/web/**,lang:ts). Omitted (or empty) means repo-wide: no path restriction, matching a classifier-derived doc with no governs: front matter.
--banMarks this a hard ban/constraint rather than a positive rule — mints a Contract node with a Constrains edge, matching a real ADR/standing-rule's is_ban. Defaults to false.
--help, -hPrint combined govern usage/help text and exit 0.
NO INVENTORY GATE

The sweep form's classified inventory and add/edit are independent — you can manually assert a doc the classifier has never seen, or one it explicitly rejected. MemCortex's confirm_governance exempts this manual path from the "doc must already be in the classified inventory" check that guards its other confirmation actions.

On success, the write is picked up on the repo's next memtrace start/memtrace mcp reconcile pass, or immediately if one is already running.

terminal
$ memtrace govern add docs/decisions/0001-use-postgres.md \
    --type adr --guidance "Use Postgres for all new services" --scope path:apps/api/**
# Directly asserts this doc as an accepted ADR scoped to apps/api/**,
# with no classifier round-trip.

$ memtrace govern edit docs/decisions/0001-use-postgres.md \
    --type adr --guidance "Use Postgres for all new services; SQLite for local dev only" --ban
# Re-asserts the same path with updated guidance and marks it a ban.
# --scope was omitted, so this ALSO clears the previous apps/api/** scope
# (edit re-declares the full assertion, it doesn't patch one field).

Environment variables#

VariableDefaultDescription
MEMCORTEX_STORE_DIR~/.memtrace/cortex-storeOverrides the MemCortex store directory. govern connects to <store-dir>/cortex.sock to reach the classification oracle. Falls back to the OS temp dir plus /memtrace-cortex-store when HOME is unset. Empty/whitespace values are ignored.

Reading the output#

On success, govern prints a deterministic grouped-count summary to stdout: a header like "Found 3 governance docs: 2 decision_record (1 accepted, 1 unknown), 1 standing_rule", followed by one row per document — state, path, title — sorted by path. When multiple agent-rule files hash to the same convention ID, the header's agent_rule count gets a "(W deduped)" suffix instead (e.g. "3 agent_rule (1 deduped)"), reflecting the collapsed group count — individual doc rows are never marked. An empty match prints "Found 0 governance docs."

Files the oracle rejects as not-governance — template/placeholder ADRs, numbered tutorials, README/CONTRIBUTING/CHANGELOG, issue templates, TOC/index pages, publishing front matter — are simply absent from the output, never listed with a wrong label.

Exit codes: 0 on success, whether or not any docs were found — zero docs is a legitimate answer for CI. 1 when MemCortex can't classify. 2 for usage/argument errors.

Gotchas#

HIDDEN COMMAND

govern is not listed in the main memtrace --help COMMANDS block, but it has its own dedicated help via memtrace govern --help.

REQUIRES THE MEMCORTEX SIDECAR, AND REFUSES TO GUESS

govern needs MemCortex running and entitled — start it with memtrace start. If the sidecar is unreachable (socket absent, connect/IO failure, or not entitled) or replies malformed, govern prints an honest "cannot classify" message and exits 1. It deliberately never falls back to a lower-quality local classifier — there is no local classification in the production path.

UNIX SOCKETS ONLY

The classification bridge uses a Unix domain socket with no Windows alternative in this version, so govern is macOS/Linux-oriented.

--exclude matches raw path substrings, not globs — --exclude adr drops every path containing "adr" anywhere. --accept-all is documented in the sweep form's usage string but is a deliberate no-op there; it never writes a governance confirmation itself — use govern add/edit (above) or the dashboard for that. Unreadable files (permission denied, deleted mid-sweep) are silently skipped, not reported.

Examples#

terminal
$ memtrace govern docs/adr
# Sweep docs/adr recursively (*.md, *.mdc, plus .cursorrules/.windsurfrules)
# and print the grouped classification summary.

$ memtrace govern docs/adr/0007-use-postgres.md
# Classify a single ADR file.

$ memtrace govern 'docs/**/*.md' --exclude drafts,archive
# Classify every markdown file matching the glob, dropping any path
# containing 'drafts' or 'archive'. Quote the glob so the shell doesn't
# expand it.

$ memtrace govern . --accept-all
# Sweep the whole repo; --accept-all is currently a no-op on the sweep
# form (prints a note that no confirmations were written).

$ memtrace govern add docs/team-conventions.md --type standing_rule \
    --guidance "Squash-merge only, no merge commits"
# Manually assert a standing rule the sweep either hasn't seen yet or
# doesn't apply to — no classifier round-trip, written immediately.

See also memtrace start, memtrace connect, memtrace status, and Cortex.