acquaint.records#

The text formats acquaint stores, as pure functions: frontmatter, sections, items, source tags, slugs, log entries.

Nothing here touches a filesystem. A record is text in and data out, so the same rules hold whether the text came from disk, a dict or a remote store. Every parser accepts \r\n line endings and a leading byte-order mark, because a store edited on Windows will have them.

The formats are deliberately hand-editable Markdown: YAML frontmatter for what a machine looks up, ## Sections of items for what a person writes, and an inline [source: …] tag on every item that states a preference, a view or a rule (beside it, a fact may carry [label: …] and [sealed-from: …], read by the same tag reader). Sections, items and code blocks follow CommonMark’s rules closely enough that what a reader sees as one line under a heading is what the lint checks.

>>> slugify("Ada Lovelace")
'ada-lovelace'
>>> meta, body, errors = split_frontmatter("\ufeff---\r\nname: Ada\r\n---\r\n## Who\r\n- a mathematician\r\n")
>>> meta, list(sections(body)), errors
({'name': 'Ada'}, ['Who'], [])
>>> source_problem("- Prefers email. [source: https://example.org/thread/1]") is None
True
>>> source_problem("- Prefers email. [source: 11th September 2026]")
'a date alone is not a source'

Module Attributes

NONE_LOCATED

The words that say "no primary source was found", out loud.

Functions

blank_frontmatter(text)

The text with its frontmatter lines emptied, so line numbers still match the file.

disclosed_refs(value)

The record references a log entry's disclosed: field lists, lowercased: project:heron, org:example or [project:heron].

dump_yaml(data)

Write YAML the way a person would: keys in order, short lists inline, unicode kept.

fact_tags(text)

The label and seals one fact carries, and what is wrong with how they are written.

format_log_entry(entry_id, date, kind, text, *)

One log entry: a ## id · date · kind heading, the observation on one line, then - key: value fields.

item_blocks(text)

(section, first_line, last_line, item) for every item of a Markdown document.

items(text)

(line, item) for every item: each bullet with its wrapped lines, or a paragraph.

join_frontmatter(meta, body)

The inverse of split_frontmatter().

load_yaml(text)

Parse YAML into JSON-ready data, returning (data, errors) instead of raising: these files are hand-edited.

next_log_id(text)

The next free entry id in a log, counting every ## eNN heading however it is written.

normalize_newlines(text)

\r\n and lone \r as \n, without a leading byte-order mark.

normalize_title(title)

parse_log(text)

Entries of an append-only log/YYYY-MM.md file, oldest first.

sectioned_items(text)

(section, line, item) for every item: see item_blocks().

sections(body)

## Title blocks of a Markdown body, in order, as {normalized title: text}.

slugify(name, *[, qualifier])

A readable, ASCII-folded, lowercase id: given-family, plus --qualifier on a collision.

source_kind(ref)

Classify one source reference.

source_problem(text)

Why a preference-bearing item is not sourced, or None when it is.

source_refs(line)

Every [source: …] reference in a piece of text, stripped.

split_frontmatter(text)

Split --- YAML frontmatter from a Markdown body: (meta, body, errors).

tags(text)

Every [source: …], [label: …] and [sealed-from: …] tag in a piece of text: (name, value), in order.

acquaint.records.NONE_LOCATED = ('none located', 'no primary source located', 'no source located')#

The words that say “no primary source was found”, out loud.

acquaint.records.blank_frontmatter(text)[source]#

The text with its frontmatter lines emptied, so line numbers still match the file.

Return type:

str

>>> blank_frontmatter("---\nname: Ada\n---\nbody\n")
'\n\n\nbody\n'
acquaint.records.disclosed_refs(value)[source]#

The record references a log entry’s disclosed: field lists, lowercased: project:heron, org:example or [project:heron].

Return type:

list[str]

>>> disclosed_refs("[project:heron, Org:Example-Client]"), disclosed_refs(""), disclosed_refs(["project:heron"])
(['project:heron', 'org:example-client'], [], ['project:heron'])
acquaint.records.dump_yaml(data)[source]#

Write YAML the way a person would: keys in order, short lists inline, unicode kept.

Return type:

str

>>> print(dump_yaml({"name": "Ada", "aka": ["Ada", "Lovelace"], "links": [{"to": "org:x"}]}), end="")
name: Ada
aka: [Ada, Lovelace]
links:
- to: org:x
acquaint.records.fact_tags(text)[source]#

The label and seals one fact carries, and what is wrong with how they are written.

{"label": str | None, "sealed_from": [ids], "problems": [messages]}. The label is returned lowercased and unchecked: which labels exist is acquaint.trust’s business. A tag that starts like [label or [sealed from but is not written [label: <label>] or [sealed-from: <id>, <id>] is a problem, never ignored.

Return type:

dict[str, Any]

>>> fact_tags("- Cy is changing jobs. [label: red] [sealed-from: bram, person:dee] [source: operator]")
{'label': 'red', 'sealed_from': ['bram', 'person:dee'], 'problems': []}
>>> for problem in fact_tags("- Heron slips. [label amber] [sealed_from: bram] [source: operator]")["problems"]:
...     print(problem)
'[label amber]' is not a tag acquaint reads; write [label: <label>]
'[sealed_from: bram]' is not a tag acquaint reads; write [sealed-from: <id>, <id>]
acquaint.records.format_log_entry(entry_id, date, kind, text, *, source=None, **fields)[source]#

One log entry: a ## id · date · kind heading, the observation on one line, then - key: value fields.

An observation that would read as a field, a heading or a list item is escaped with a leading backslash, so captured text can never forge an entry or change its kind.

Return type:

str

acquaint.records.item_blocks(text)[source]#

(section, first_line, last_line, item) for every item of a Markdown document.

An item is one bullet (-, *, +, 1.) at any depth, together with the wrapped lines under it, or a paragraph. A nested bullet is an item of its own, so it needs its own source. Blank lines, headings, thematic breaks, HTML comments and fenced code are not items. section is the enclosing ## title (normalized), None before the first one or after a # heading. Blank the frontmatter first (blank_frontmatter()) if the text has one.

Return type:

list[tuple[str | None, int, int, str]]

acquaint.records.items(text)[source]#

(line, item) for every item: each bullet with its wrapped lines, or a paragraph.

Return type:

list[tuple[int, str]]

>>> doc = "- one\n  continued\n  - nested\n\nA paragraph\nwrapped.\n```\n- code, not an item\n```\n+ two\n3. three\n"
>>> items(doc)
[(1, 'one continued'), (3, 'nested'), (5, 'A paragraph wrapped.'), (10, 'two'), (11, 'three')]
acquaint.records.join_frontmatter(meta, body)[source]#

The inverse of split_frontmatter().

Return type:

str

>>> join_frontmatter({"name": "Ada"}, "## Who\n")
'---\nname: Ada\n---\n\n## Who\n'
acquaint.records.load_yaml(text)[source]#

Parse YAML into JSON-ready data, returning (data, errors) instead of raising: these files are hand-edited.

Return type:

tuple[Any, list[str]]

>>> load_yaml("a: [1, 2]\nb: !!set {x: null}")
({'a': [1, 2], 'b': ['x']}, [])
>>> data, errors = load_yaml("a: [1, 2")
>>> data, bool(errors)
(None, True)
acquaint.records.next_log_id(text)[source]#

The next free entry id in a log, counting every ## eNN heading however it is written.

Return type:

str

>>> next_log_id("## e01 · 2026-09-01 · observation\nx\n## e07 - 2026-09-02 - note\ny\n")
'e08'
>>> next_log_id("")
'e01'
acquaint.records.normalize_newlines(text)[source]#

\r\n and lone \r as \n, without a leading byte-order mark.

Return type:

str

>>> normalize_newlines("\ufeffa\r\nb\rc")
'a\nb\nc'
acquaint.records.normalize_title(title)[source]#
Return type:

str

A heading as written, minus decoration: closing ``#``s, a trailing colon, typographic apostrophes, extra space.

>>> normalize_title("  Don’t:  ## ")
"Don't"
acquaint.records.parse_log(text)[source]#

Entries of an append-only log/YYYY-MM.md file, oldest first.

Headings may use ·, - or | between their parts; an escaped prose line (a leading backslash, see format_log_entry()) is unescaped.

Return type:

list[dict]

>>> entry = format_log_entry("e01", "2026-09-11", "observation", "- kind: rule, they said",
...                          source="https://example.org/thread/1")
>>> parse_log(entry)
[{'id': 'e01', 'date': '2026-09-11', 'kind': 'observation', 'text': '- kind: rule, they said', 'source': 'https://example.org/thread/1'}]
acquaint.records.sectioned_items(text)[source]#

(section, line, item) for every item: see item_blocks().

Return type:

list[tuple[str | None, int, str]]

>>> sectioned_items(blank_frontmatter("---\nname: Ada\n---\n# Ada\n## Write to them:\n- Short. [source: operator]\n### Detail\n- More.\n"))
[('Write to them', 6, 'Short. [source: operator]'), ('Write to them', 8, 'More.')]
acquaint.records.sections(body)[source]#

## Title blocks of a Markdown body, in order, as {normalized title: text}.

A # heading ends the current section; deeper headings stay inside it; headings inside fenced code and HTML comments are not headings (and comments are left out).

Return type:

dict[str, str]

>>> sections("intro\n## Who\nAda\n### Detail\nmore\n# Aside\nnot in Who\n## Now:\n- busy\n")
{'Who': 'Ada\n### Detail\nmore\n', 'Now': '- busy\n'}
acquaint.records.slugify(name, *, qualifier=None)[source]#

A readable, ASCII-folded, lowercase id: given-family, plus --qualifier on a collision.

Return type:

str

>>> slugify("Zoë Ångström")
'zoe-angstrom'
>>> slugify("John Smith", qualifier="Example Org")
'john-smith--example-org'
acquaint.records.source_kind(ref)[source]#

Classify one source reference.

One of url, file, self, operator, none-located, other (free text: accepted, not checkable), or a defect: self-unquoted, placeholder, date-only, empty.

Return type:

str

>>> [source_kind(r) for r in ["https://example.org/x", "log/2026-09.md#e01", "self: 'don't email me'",
...     "self, it's what they're like", 'self: " "', "operator", "none located", "2026-09-01T10:00Z",
...     "last Tuesday", "todo: find link", "", "email to Ada on 2026-09-01"]]
['url', 'file', 'self', 'self-unquoted', 'self-unquoted', 'operator', 'none-located', 'date-only', 'date-only', 'placeholder', 'empty', 'other']
acquaint.records.source_problem(text)[source]#

Why a preference-bearing item is not sourced, or None when it is.

A source is a permalink, a file anchor (log/2026-09.md#e03), the person’s own words (self: "…"), the operator’s statement (operator), or an explicit none located. A date alone is not a source, and neither is a placeholder.

Return type:

str | None

>>> source_problem("- Prefers calls.")
'no [source: …] tag'
>>> source_problem('- Prefers calls. [source: self: "call me, never email"]') is None
True
>>> source_problem("- Prefers calls. [source: self, 2026-09-01]")
'self-stated sources need the quoted words: [source: self: "…"]'
>>> source_problem("- Prefers calls. [source: TODO]")
"'TODO' is a placeholder, not a source: write none located if you looked and found nothing; an inference goes under Hypotheses with its evidence"
acquaint.records.source_refs(line)[source]#

Every [source: …] reference in a piece of text, stripped.

Return type:

list[str]

>>> source_refs("- Short replies. [source: log/2026-09.md#e03] [source: operator]")
['log/2026-09.md#e03', 'operator']
acquaint.records.split_frontmatter(text)[source]#

Split --- YAML frontmatter from a Markdown body: (meta, body, errors).

A malformed header degrades to empty metadata plus an error, never an exception, so one bad hand edit cannot take down lookups of every other record.

Return type:

tuple[dict, str, list[str]]

>>> split_frontmatter("no frontmatter here")
({}, 'no frontmatter here', ['no --- frontmatter block at the top of the file'])
acquaint.records.tags(text)[source]#

Every [source: …], [label: …] and [sealed-from: …] tag in a piece of text: (name, value), in order.

Return type:

list[tuple[str, str]]

>>> tags("- Heron ships in October [label: amber] [Sealed-From: bram] [source: operator 2026-09-15]")
[('label', 'amber'), ('sealed-from', 'bram'), ('source', 'operator 2026-09-15')]