brainiac-cli 0.16.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brain/__init__.py +39 -0
- brain/__main__.py +14 -0
- brain/_assets/AGENTS.md +564 -0
- brain/_assets/overlay/template/brand/brand-guide.md +24 -0
- brain/_assets/overlay/template/keywords/glossary.md +15 -0
- brain/_assets/overlay/template/people/roster.md +14 -0
- brain/_assets/overlay/template/voice/voice-profile.md +34 -0
- brain/_assets/routines/manifest.json +257 -0
- brain/_assets/scripts/brain-brief-mac.plist +59 -0
- brain/_assets/scripts/brain-brief.sh +74 -0
- brain/_assets/scripts/brain-synthesis-mac.plist +48 -0
- brain/_assets/scripts/brain-synthesis.sh +214 -0
- brain/_assets/scripts/install-brief-mac.sh +152 -0
- brain/_assets/scripts/install-brief-windows.ps1 +97 -0
- brain/_assets/scripts/register_tasks.py +386 -0
- brain/_assets/templates/company.md +21 -0
- brain/_assets/templates/concept.md +27 -0
- brain/_assets/templates/daily.md +20 -0
- brain/_assets/templates/decision.md +42 -0
- brain/_assets/templates/meeting.md +33 -0
- brain/_assets/templates/person.md +20 -0
- brain/_assets/templates/project.md +23 -0
- brain/_assets/templates/state-moc.md +40 -0
- brain/_version.py +12 -0
- brain/anchor.py +121 -0
- brain/audit.py +422 -0
- brain/backup.py +210 -0
- brain/brief.py +417 -0
- brain/capture.py +117 -0
- brain/chunk.py +249 -0
- brain/classification.py +134 -0
- brain/cli.py +1906 -0
- brain/config.py +368 -0
- brain/connect.py +362 -0
- brain/context.py +108 -0
- brain/core.py +3018 -0
- brain/doctor.py +1161 -0
- brain/egress.py +148 -0
- brain/embed.py +857 -0
- brain/encryption.py +217 -0
- brain/frontmatter.py +102 -0
- brain/golden_probe.py +678 -0
- brain/graph.py +369 -0
- brain/graphify.py +352 -0
- brain/index.py +1576 -0
- brain/ingest/__init__.py +19 -0
- brain/ingest/handlers/__init__.py +43 -0
- brain/ingest/handlers/base.py +95 -0
- brain/ingest/handlers/docx.py +78 -0
- brain/ingest/handlers/email.py +228 -0
- brain/ingest/handlers/html.py +142 -0
- brain/ingest/handlers/image.py +91 -0
- brain/ingest/handlers/pdf.py +99 -0
- brain/ingest/handlers/pptx.py +69 -0
- brain/ingest/handlers/tables.py +41 -0
- brain/ingest/handlers/text.py +43 -0
- brain/ingest/handlers/xlsx.py +100 -0
- brain/ingest/handlers/zip.py +163 -0
- brain/ingest/pipeline.py +839 -0
- brain/ingest/transcript.py +158 -0
- brain/init.py +870 -0
- brain/maintenance.py +2266 -0
- brain/mcp_adapter.py +217 -0
- brain/multihop.py +232 -0
- brain/notes.py +195 -0
- brain/overlay.py +183 -0
- brain/projection.py +79 -0
- brain/rerank.py +425 -0
- brain/snapshot.py +231 -0
- brain/update.py +743 -0
- brain/vectors.py +225 -0
- brainiac_cli-0.16.0.dist-info/METADATA +306 -0
- brainiac_cli-0.16.0.dist-info/RECORD +77 -0
- brainiac_cli-0.16.0.dist-info/WHEEL +5 -0
- brainiac_cli-0.16.0.dist-info/entry_points.txt +4 -0
- brainiac_cli-0.16.0.dist-info/licenses/LICENSE +202 -0
- brainiac_cli-0.16.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""ING-04 — transcript capture route (ADR-0003 Ruling 1 companion, S06).
|
|
2
|
+
|
|
3
|
+
Meeting transcripts are produced EXTERNALLY (the transcriber MCP/CLI — never
|
|
4
|
+
in-kernel, AGENTS.md) and are already Markdown, so unlike the binary
|
|
5
|
+
drop-zone (``ingest/pipeline.py``) there is no extraction step and no
|
|
6
|
+
"original binary vs. extracted Markdown" split: the transcript file's own
|
|
7
|
+
text IS the note body. What the generic drop-zone pipeline genuinely CANNOT
|
|
8
|
+
express is real-world provenance — its own ``origin`` always points at an
|
|
9
|
+
archived COPY of whatever was dropped, never at the real-world thing the
|
|
10
|
+
content was recorded from. This module's whole job is exactly that gap: an
|
|
11
|
+
EXPLICIT, caller-supplied ``origin`` (a source audio/video file path, or the
|
|
12
|
+
literal string ``"verbal"`` for a no-recording capture) plus an optional
|
|
13
|
+
``language`` stamp detected from the filename (never guessed from prose).
|
|
14
|
+
|
|
15
|
+
Reuses ``ingest.pipeline``'s hardened building blocks (create-exclusive
|
|
16
|
+
archival, control-char-safe frontmatter, the shared density gate, the SAME
|
|
17
|
+
content-hash dedup manifest as the binary pipeline) rather than
|
|
18
|
+
reimplementing them — one dedup universe across every ingest surface.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import datetime as _dt
|
|
23
|
+
import hashlib
|
|
24
|
+
import re
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import Any
|
|
27
|
+
|
|
28
|
+
from . import pipeline as _pipeline
|
|
29
|
+
from .handlers.base import density_gate
|
|
30
|
+
from ..notes import safe_slug
|
|
31
|
+
|
|
32
|
+
MAX_TRANSCRIPT_BYTES = 50 * 1024 * 1024
|
|
33
|
+
_ENCODINGS = ("utf-8", "utf-8-sig", "latin-1")
|
|
34
|
+
|
|
35
|
+
# Presence-based ONLY — "language if present in the filename" (S06 brief)
|
|
36
|
+
# means a literal recognised code as its own path segment (e.g.
|
|
37
|
+
# "standup_2026-07-05_en.md", "reuniao.pt.md"), never an inference from the
|
|
38
|
+
# transcript's prose. A wrong guess is worse than an absent field.
|
|
39
|
+
_LANG_CODES = ("en", "pt", "es", "fr", "de", "it", "nl")
|
|
40
|
+
_LANG_RE = re.compile(r"(?:^|[._-])(" + "|".join(_LANG_CODES) + r")(?:[._-]|$)", re.IGNORECASE)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def detect_language(filename: str) -> str | None:
|
|
44
|
+
m = _LANG_RE.search(Path(filename).stem)
|
|
45
|
+
return m.group(1).lower() if m else None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def ingest_transcript(
|
|
49
|
+
core: Any, path: str | Path, *, origin: str, language: str | None = None,
|
|
50
|
+
document_date: str | None = None, classification: str = "Internal",
|
|
51
|
+
) -> dict[str, Any]:
|
|
52
|
+
"""Promote a transcript ``.md`` file into ``vault/raw/`` via the SAME
|
|
53
|
+
audited host-broker write path as the binary drop-zone. Returns a result
|
|
54
|
+
dict shaped like ``pipeline``'s ``processed``/``duplicates`` entries
|
|
55
|
+
(``ok: False`` + ``reason`` on failure — never raises for an ordinary
|
|
56
|
+
content/quality problem, matching every handler's own contract).
|
|
57
|
+
|
|
58
|
+
HOST-broker only: ``core.write_note`` already fails closed on the VM
|
|
59
|
+
role; ``BrainCore.ingest_transcript`` additionally calls
|
|
60
|
+
``_require_host`` up front for the same fail-fast-before-any-I/O shape as
|
|
61
|
+
``ingest_dropzone``.
|
|
62
|
+
"""
|
|
63
|
+
path = Path(path)
|
|
64
|
+
vault = core.vault
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
size = path.stat().st_size
|
|
68
|
+
except OSError as exc:
|
|
69
|
+
return {"ok": False, "reason": f"transcript_read_error:{type(exc).__name__}: {exc}"}
|
|
70
|
+
if size > MAX_TRANSCRIPT_BYTES:
|
|
71
|
+
return {"ok": False, "reason": "file_too_large"}
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
raw_bytes = path.read_bytes()
|
|
75
|
+
except OSError as exc:
|
|
76
|
+
return {"ok": False, "reason": f"transcript_read_error:{type(exc).__name__}: {exc}"}
|
|
77
|
+
|
|
78
|
+
text = None
|
|
79
|
+
for enc in _ENCODINGS:
|
|
80
|
+
try:
|
|
81
|
+
text = raw_bytes.decode(enc)
|
|
82
|
+
break
|
|
83
|
+
except UnicodeDecodeError:
|
|
84
|
+
continue
|
|
85
|
+
if text is None:
|
|
86
|
+
return {"ok": False, "reason": "transcript_decode_error"}
|
|
87
|
+
|
|
88
|
+
reason = density_gate(text)
|
|
89
|
+
if reason:
|
|
90
|
+
return {"ok": False, "reason": reason}
|
|
91
|
+
|
|
92
|
+
original_sha = hashlib.sha256(raw_bytes).hexdigest()
|
|
93
|
+
manifest = _pipeline._load_manifest(vault)
|
|
94
|
+
if original_sha in manifest:
|
|
95
|
+
return {"ok": True, "duplicate": True, "existing_id": manifest[original_sha], "file": str(path)}
|
|
96
|
+
|
|
97
|
+
today = _dt.date.today().isoformat()
|
|
98
|
+
stem = _pipeline._slugify_stem(path.stem)
|
|
99
|
+
slug = safe_slug(f"{today}-{stem}")
|
|
100
|
+
archive_subdir = vault / "raw" / "originals" / f"{today}-{stem}"
|
|
101
|
+
archive_path = archive_subdir / _pipeline._sanitize_archive_name(path.name)
|
|
102
|
+
|
|
103
|
+
arch_status = _pipeline._create_exclusive_or_collision(archive_path, raw_bytes, known_sha=original_sha)
|
|
104
|
+
if arch_status == "collision":
|
|
105
|
+
return {
|
|
106
|
+
"ok": False, "reason": "archive_collision",
|
|
107
|
+
"detail": f"archived-original target already holds different content: {archive_path}",
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
body_sha = hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
111
|
+
lang = language or detect_language(path.name)
|
|
112
|
+
meta: dict[str, Any] = {
|
|
113
|
+
"id": slug,
|
|
114
|
+
"type": "source",
|
|
115
|
+
"classification": classification,
|
|
116
|
+
"captured": today,
|
|
117
|
+
"origin": origin,
|
|
118
|
+
"sha256": body_sha,
|
|
119
|
+
"immutable": True,
|
|
120
|
+
}
|
|
121
|
+
if lang:
|
|
122
|
+
meta["language"] = lang
|
|
123
|
+
if document_date:
|
|
124
|
+
meta["document_date"] = document_date
|
|
125
|
+
|
|
126
|
+
note_rel = f"raw/{slug}.md"
|
|
127
|
+
note_path = vault / note_rel
|
|
128
|
+
if note_path.exists():
|
|
129
|
+
# Defense in depth (manifest miss but the target id already exists —
|
|
130
|
+
# e.g. a hand-deleted manifest): same-body -> idempotent no-op,
|
|
131
|
+
# different -> collision, never overwritten. Mirrors pipeline.py.
|
|
132
|
+
from .. import frontmatter as fm
|
|
133
|
+
|
|
134
|
+
existing_meta, _ = fm.parse_text(note_path.read_text(encoding="utf-8"))
|
|
135
|
+
if str(existing_meta.get("sha256", "")) != body_sha:
|
|
136
|
+
return {
|
|
137
|
+
"ok": False, "reason": "note_id_collision",
|
|
138
|
+
"detail": f"raw/{slug}.md already exists with different content",
|
|
139
|
+
}
|
|
140
|
+
manifest[original_sha] = slug
|
|
141
|
+
_pipeline._save_manifest(vault, manifest)
|
|
142
|
+
return {"ok": True, "duplicate": True, "existing_id": slug, "file": str(path)}
|
|
143
|
+
|
|
144
|
+
content = _pipeline._build_frontmatter(meta, text)
|
|
145
|
+
core.write_note(
|
|
146
|
+
note_rel, content,
|
|
147
|
+
reason=f"ingest-transcript {path.name} -> raw/{slug}.md (origin={origin})",
|
|
148
|
+
subtree="raw",
|
|
149
|
+
)
|
|
150
|
+
manifest[original_sha] = slug
|
|
151
|
+
_pipeline._save_manifest(vault, manifest)
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
"ok": True, "duplicate": False, "id": slug, "note": note_rel,
|
|
155
|
+
"archived": str(archive_path.relative_to(vault)),
|
|
156
|
+
"classification": classification, "origin": origin, "language": lang,
|
|
157
|
+
"file": str(path),
|
|
158
|
+
}
|