acquaint.tools#

The single source of truth for every surface: plain functions, flat arguments in, JSON-ready dicts out.

The CLI is cw over TOOLS; the MCP server exposes the same functions (by acquaint.tools:<name> reference); the shipped skills describe these verbs. Nothing in this module knows about any of those surfaces.

Every tool takes data_dir (default: $ACQUAINT_DATA_DIR, else data_dir in ~/.config/acquaint/config.toml, else ~/.local/share/acquaint). Every result carries ok and a one-line summary; long human-readable content is in text.

Tools never act on a guess. A name, alias, handle or email counts only when exactly one entity has it exactly; a partial match is returned as a suggestion. rename and forget need the exact id. Library callers with their own store use the core functions (acquaint.lookup.find_entity(), acquaint.brief.compose_brief(), …) with a Store.

Module Attributes

TOOLS

Every tool, in the order surfaces list them.

SIDE_EFFECTS

What each tool changes, for surfaces that must decide what to expose or confirm.

Functions

brief(person, *[, purpose, project, ref, ...])

Everything to know before writing to someone: card, writing style, reach, project norms, recent observations, gaps.

check(text, *[, data_dir])

Scan prose that names people before publishing it: conflations (one person written as two), ambiguous names, unknown names.

disclosure(people, *[, projects, audience, ...])

Who may be told what, before writing to a set of readers (ids or channel identities, plus an optional correspond audience record as JSON): the tier and clearance in force for each, the least clearance, which records each is cleared for, the seals, the vocabulary a gate must scan for, what each was already told, and the gaps.

forget(entity, *[, confirm, data_dir])

Remove an entity's folder and leave a salted tombstone.

lint([entity, data_dir])

Check records: every preference, view and rule sourced; tiers, labels and seals set by the operator; nothing POLICY.md forbids; files parse; entry files within budget.

new(kind, name, *[, qualifier, description, ...])

Create a person, project, org or group from its template (a readable slug id; qualifier separates two of the same name).

reach(person, *[, purpose, urgency, ...])

Ordered channels for reaching someone in a context.

remember(entity, text, *[, source, kind, ...])

Append a dated observation (observation, interaction, identity, preference, view, rule) to an entity's log, with its source.

rename(entity, to, *[, data_dir])

Change an entity's id (to is a slug) or name and id (to is a name), rewriting links to it.

resolve(handle, *[, data_dir])

Map a channel handle (github:octocat, email:ada@example.org) to the entity it belongs to, with the evidence.

review(person, *[, today, data_dir])

Everything the store says about one person's disclosure standing, with sources and dates, to confirm when a collaboration ends, when someone changes role, or before a tier changes: tier entries, links, the default tiers and clearances reached through links, seals on records and on fact lines, and the rules that name them.

style_lint(text, *[, recipient, tolerance, ...])

The deterministic half of deslop: machine-writing tells in a draft, at the recipient's tolerance and against their blocklist.

sync_init(*, repo[, remote_url, ...])

Make the data root a checkout of a PRIVATE GitHub repository (created private through gh unless existing_only), with a pre-push guard.

sync_pull(*[, dry_run, data_dir])

Pull the store from its private remote, rebasing local work on top.

sync_push(*[, message, dry_run, data_dir])

Commit, rebase onto the remote and push the store, after re-checking the remote, the guard and the visibility.

sync_status(*[, check_visibility, data_dir])

Whether the store is synced, to which repository, uncommitted changes, ahead/behind, the guard, and live visibility.

todo_preflight(project, people, *[, data_dir])

Before filing a meeting's todos as GitHub issues: is the project unambiguous, is every participant (comma-separated) registered and linked to it, and does it declare a meta repository that is private now? Returns the repository, each person's GitHub login, and a fix for every problem.

who(name, *[, field, brief, data_dir])

Look up one person, project, org or group by exact id, name, alias, handle or email.

Exceptions

AcquaintError

An expected failure with a message meant for the person or agent that asked.

exception acquaint.tools.AcquaintError[source]#

Bases: Exception

An expected failure with a message meant for the person or agent that asked.

acquaint.tools.SIDE_EFFECTS = {'brief': 'read', 'check': 'read', 'disclosure': 'read', 'forget': 'destructive', 'lint': 'read', 'new': 'create', 'reach': 'read', 'remember': 'append', 'rename': 'rewrite', 'resolve': 'read', 'review': 'read', 'style_lint': 'read', 'sync_init': 'external', 'sync_pull': 'rewrite', 'sync_push': 'external', 'sync_status': 'external-read', 'todo_preflight': 'external-read', 'who': 'read'}#

What each tool changes, for surfaces that must decide what to expose or confirm. read changes nothing and stays local; append adds to a log; create adds a record; rewrite changes existing records; destructive removes data; external-read queries a remote service; external acts on one.

acquaint.tools.TOOLS = [<function who>, <function resolve>, <function check>, <function reach>, <function brief>, <function remember>, <function lint>, <function new>, <function rename>, <function forget>, <function sync_init>, <function sync_push>, <function sync_pull>, <function sync_status>, <function style_lint>, <function disclosure>, <function review>, <function todo_preflight>]#

Every tool, in the order surfaces list them.

acquaint.tools.brief(person, *, purpose=None, project=None, ref=None, audience=None, data_dir=None)[source]#

Everything to know before writing to someone: card, writing style, reach, project norms, recent observations, gaps. With ref (the conversation the message goes to; correspond is asked who can read it, and an unknown audience is public) or audience (an audience record as JSON), it opens with the ceiling, the records not to identify, how many lines were withheld, and what they were already told.

Return type:

dict

acquaint.tools.check(text, *, data_dir=None)[source]#

Scan prose that names people before publishing it: conflations (one person written as two), ambiguous names, unknown names.

Return type:

dict

acquaint.tools.disclosure(people, *, projects=None, audience=None, today=None, data_dir=None)[source]#

Who may be told what, before writing to a set of readers (ids or channel identities, plus an optional correspond audience record as JSON): the tier and clearance in force for each, the least clearance, which records each is cleared for, the seals, the vocabulary a gate must scan for, what each was already told, and the gaps. projects limits the records to those plus people. Reads only.

Return type:

dict

acquaint.tools.forget(entity, *, confirm=False, data_dir=None)[source]#

Remove an entity’s folder and leave a salted tombstone. Needs the exact id; without confirm, only reports what would be removed.

Return type:

dict

acquaint.tools.lint(entity=None, *, data_dir=None)[source]#

Check records: every preference, view and rule sourced; tiers, labels and seals set by the operator; nothing POLICY.md forbids; files parse; entry files within budget.

Return type:

dict

acquaint.tools.new(kind, name, *, qualifier=None, description=None, force=False, data_dir=None)[source]#

Create a person, project, org or group from its template (a readable slug id; qualifier separates two of the same name).

Return type:

dict

acquaint.tools.reach(person, *, purpose=None, urgency=None, project=None, message_type=None, topic=None, data_dir=None)[source]#

Ordered channels for reaching someone in a context. Only active addresses; returns them, sends nothing. outcome is reachable, no_address (a rule matched, but neither states an address nor finds a usable one recorded for its channels) or no_channel. Each channel’s address_kind is stated, identity (the person’s handle, which a conversation-addressed channel does not take) or None.

Return type:

dict

acquaint.tools.remember(entity, text, *, source=None, kind='observation', disclosed=None, reactivate=False, data_dir=None)[source]#

Append a dated observation (observation, interaction, identity, preference, view, rule) to an entity’s log, with its source. An interaction may list the records the message identified (disclosed: exact ids, never the text). An identity equal to an inactive one (stale, retracted, …) is refused, naming that entry and the command with which the operator can make it active again.

Return type:

dict

acquaint.tools.rename(entity, to, *, data_dir=None)[source]#

Change an entity’s id (to is a slug) or name and id (to is a name), rewriting links to it. Needs the exact id.

Return type:

dict

acquaint.tools.resolve(handle, *, data_dir=None)[source]#

Map a channel handle (github:octocat, email:ada@example.org) to the entity it belongs to, with the evidence.

ok is true only when an active identity on the named platform belongs to exactly one entity. A handle without a platform (@octocat), a match by name only, an inactive identity, or several owners all return ok: false with what was found.

Return type:

dict

acquaint.tools.review(person, *, today=None, data_dir=None)[source]#

Everything the store says about one person’s disclosure standing, with sources and dates, to confirm when a collaboration ends, when someone changes role, or before a tier changes: tier entries, links, the default tiers and clearances reached through links, seals on records and on fact lines, and the rules that name them. Not ok when an affiliation has ended while a permissive tier is still in force. Reads only.

Return type:

dict

acquaint.tools.style_lint(text, *, recipient=None, tolerance=None, data_dir=None)[source]#

The deterministic half of deslop: machine-writing tells in a draft, at the recipient’s tolerance and against their blocklist.

Return type:

dict

acquaint.tools.sync_init(*, repo, remote_url=None, existing_only=False, dry_run=False, data_dir=None)[source]#

Make the data root a checkout of a PRIVATE GitHub repository (created private through gh unless existing_only), with a pre-push guard.

Return type:

dict

acquaint.tools.sync_pull(*, dry_run=False, data_dir=None)[source]#

Pull the store from its private remote, rebasing local work on top.

Return type:

dict

acquaint.tools.sync_push(*, message=None, dry_run=False, data_dir=None)[source]#

Commit, rebase onto the remote and push the store, after re-checking the remote, the guard and the visibility.

Return type:

dict

acquaint.tools.sync_status(*, check_visibility=True, data_dir=None)[source]#

Whether the store is synced, to which repository, uncommitted changes, ahead/behind, the guard, and live visibility.

Return type:

dict

acquaint.tools.todo_preflight(project, people, *, data_dir=None)[source]#

Before filing a meeting’s todos as GitHub issues: is the project unambiguous, is every participant (comma-separated) registered and linked to it, and does it declare a meta repository that is private now? Returns the repository, each person’s GitHub login, and a fix for every problem.

Return type:

dict

acquaint.tools.who(name, *, field=None, brief=False, data_dir=None)[source]#

Look up one person, project, org or group by exact id, name, alias, handle or email.

Costs scale with what you ask: field returns one value (aka, email, github, label, tier, any frontmatter key), brief the identity block, and the default the whole entry file. It never guesses: no exact match, or several, returns the candidates and ok: false.

Return type:

dict