daimon-briefing 0.3.1__tar.gz → 0.3.3__tar.gz
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.
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/PKG-INFO +2 -2
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/carry.py +40 -7
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/pyproject.toml +2 -2
- daimon_briefing-0.3.3/skills/daimon-briefing/SKILL.md +75 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_carry.py +70 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/uv.lock +1 -1
- daimon_briefing-0.3.1/skills/daimon-briefing/SKILL.md +0 -49
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/.gitignore +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/README.md +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/__init__.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/anchor.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/briefing.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/cli.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/config.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/configure.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/harvest.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/hooks.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/llm.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/recall.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/render.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/scoring.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/serializer.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/store.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/teamsync.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/daimon_briefing/transcript.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/skills/daimon-end/SKILL.md +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/__init__.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/conftest.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/fixtures/sample_transcript.md +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_anchor.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_briefing.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_claude_hooks.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_cli.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_codex_hooks.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_config.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_configure.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_gemini_hooks.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_harvest.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_hooks.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_isolation.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_llm.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_recall.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_render.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_scoring.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_serializer.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_store.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_teamsync.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_transcript.py +0 -0
- {daimon_briefing-0.3.1 → daimon_briefing-0.3.3}/tests/test_version.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: daimon-briefing
|
|
3
|
-
Version: 0.3.
|
|
4
|
-
Summary: Dream-briefing
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: Dream-briefing for AI coding agents: writes a cognitive checkpoint at session end and shows a 'while you were away' briefing at session start. Self-contained, stdlib-only.
|
|
5
5
|
Author: Daily-Nerd / Daimon
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Requires-Python: >=3.10
|
|
@@ -9,6 +9,7 @@ caller injects clock and knobs (scar: a default wall-clock anywhere silently
|
|
|
9
9
|
freezes time math under simulation)."""
|
|
10
10
|
|
|
11
11
|
import copy
|
|
12
|
+
from collections import Counter
|
|
12
13
|
|
|
13
14
|
from . import recall, scoring, store
|
|
14
15
|
|
|
@@ -22,16 +23,41 @@ _CARRIED_KINDS = (
|
|
|
22
23
|
|
|
23
24
|
_MIN_SHARED = 3 # shared salient terms for same-item
|
|
24
25
|
_MIN_RATIO = 0.6 # or this fraction of the shorter term list
|
|
26
|
+
_GENERIC_DF = 3 # a term shared by >=3 items of one kind is that kind's
|
|
27
|
+
# vocabulary, not an item's identity. Filtering it out of
|
|
28
|
+
# dedup stops generic overlap (data/field/validation, the
|
|
29
|
+
# #13 live specimen) from forging a false merge. Computed
|
|
30
|
+
# per kind per merge — no static stoplist, so carry stays
|
|
31
|
+
# language-neutral (es i18n just shipped).
|
|
25
32
|
|
|
26
33
|
|
|
27
|
-
def
|
|
34
|
+
def _generic_terms(texts, k: int = _GENERIC_DF) -> frozenset:
|
|
35
|
+
"""Salient terms appearing in >= k DISTINCT texts of one kind — that kind's
|
|
36
|
+
shared vocabulary, which dedup must ignore. Document frequency counts a term
|
|
37
|
+
once per text (set per text), so repetition inside one item can't inflate
|
|
38
|
+
it."""
|
|
39
|
+
df: Counter = Counter()
|
|
40
|
+
for t in texts:
|
|
41
|
+
df.update(set(recall.salient_terms(t)))
|
|
42
|
+
return frozenset(term for term, n in df.items() if n >= k)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _same_item(a_text: str, b_text: str, generic=frozenset()) -> bool:
|
|
28
46
|
"""Term-overlap identity: the serializer rewords constantly (run-01), so
|
|
29
47
|
exact text misses twins. Shared >=3 salient terms, or >=60% of the shorter
|
|
30
|
-
list, means same item
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if
|
|
48
|
+
list, means same item — but only AFTER subtracting `generic` (the kind's
|
|
49
|
+
document-frequent vocabulary), so overlap on common words can't merge
|
|
50
|
+
unrelated items.
|
|
51
|
+
|
|
52
|
+
Floor: if either filtered set has <2 terms, never fuzzy-match. This blocks a
|
|
53
|
+
single surviving shared term from passing the ratio path (1/1 = 1.0). The
|
|
54
|
+
bias is deliberate and asymmetric: a false merge erases a loop and forges
|
|
55
|
+
its birth stamp, while a false non-merge only costs a duplicate item — so
|
|
56
|
+
tie-break toward NOT merging. The exact-text guard still catches identical
|
|
57
|
+
items regardless."""
|
|
58
|
+
a = set(recall.salient_terms(a_text)) - generic
|
|
59
|
+
b = set(recall.salient_terms(b_text)) - generic
|
|
60
|
+
if len(a) < 2 or len(b) < 2:
|
|
35
61
|
return False
|
|
36
62
|
shared = len(a & b)
|
|
37
63
|
return shared >= _MIN_SHARED or shared / min(len(a), len(b)) >= _MIN_RATIO
|
|
@@ -64,6 +90,12 @@ def merge(new_cp: dict, prev_cp: dict | None, now: float,
|
|
|
64
90
|
continue
|
|
65
91
|
prev_items = (prev_cp.get(section) or {}).get(key) or []
|
|
66
92
|
native_texts = {i.get("text") for i in native if isinstance(i, dict)}
|
|
93
|
+
# Generic vocabulary for THIS kind, from the same universe merge iterates
|
|
94
|
+
# (native + prev): terms this common are not identity, so dedup ignores
|
|
95
|
+
# them (#13). Computed once per kind, passed to every _same_item below.
|
|
96
|
+
generic = _generic_terms(
|
|
97
|
+
[str(i.get("text") or "") for i in native if isinstance(i, dict)]
|
|
98
|
+
+ [str(i.get("text") or "") for i in prev_items if isinstance(i, dict)])
|
|
67
99
|
carried = []
|
|
68
100
|
for item in prev_items:
|
|
69
101
|
if not isinstance(item, dict) or not str(item.get("text") or "").strip():
|
|
@@ -72,7 +104,8 @@ def merge(new_cp: dict, prev_cp: dict | None, now: float,
|
|
|
72
104
|
if text in native_texts:
|
|
73
105
|
continue # exact twin already present (idempotency)
|
|
74
106
|
twin = next((n for n in native if isinstance(n, dict)
|
|
75
|
-
and _same_item(text, str(n.get("text") or ""))),
|
|
107
|
+
and _same_item(text, str(n.get("text") or ""), generic)),
|
|
108
|
+
None)
|
|
76
109
|
if twin is not None:
|
|
77
110
|
# Session re-discussed it: the new wording wins, but the item's
|
|
78
111
|
# AGE does not reset (run-01: 8-12 resets/20 cycles killed the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "daimon-briefing"
|
|
3
|
-
version = "0.3.
|
|
4
|
-
description = "Dream-briefing
|
|
3
|
+
version = "0.3.3"
|
|
4
|
+
description = "Dream-briefing for AI coding agents: writes a cognitive checkpoint at session end and shows a 'while you were away' briefing at session start. Self-contained, stdlib-only."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
license = { text = "Apache-2.0" }
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: daimon-briefing
|
|
3
|
+
description: Dream-briefing — surfaces a "while you were away / here's where we left off" briefing at the start of a resumed session, reconstructed from a cognitive checkpoint written at the end of the prior session. Use to recall open loops, decisions, and facts whose state may have changed outside the AI session (e.g. a PR you merged yourself).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Daimon Dream-Briefing
|
|
7
|
+
|
|
8
|
+
This plugin keeps continuity across sessions. At the **end** of each session it
|
|
9
|
+
serializes the transcript into a cognitive checkpoint (open loops, decisions,
|
|
10
|
+
beliefs, with extractively-pinned verbatim quotes). At the **start** of the next
|
|
11
|
+
session it injects a skimmable briefing so you resume from a faithful prior state
|
|
12
|
+
instead of a confident guess.
|
|
13
|
+
|
|
14
|
+
## What it surfaces, in order
|
|
15
|
+
|
|
16
|
+
1. **Verify before trusting** — items whose state may have changed *outside* this
|
|
17
|
+
session (a PR you said you'd merge, a deploy, a file edited elsewhere). These come
|
|
18
|
+
first because they are the gap that produces confident-but-wrong assertions.
|
|
19
|
+
2. **Open loops** — questions left unresolved at the end of last session.
|
|
20
|
+
3. **Decisions made** — explicit choices, including assistant-side fixes/diagnoses.
|
|
21
|
+
4. **Active topic / beliefs / uncertainties.**
|
|
22
|
+
|
|
23
|
+
Each item is marked `✓ verbatim` (pinned to an exact quote — trust it) or
|
|
24
|
+
`~ inferred` (paraphrased — treat with appropriate caution).
|
|
25
|
+
|
|
26
|
+
## Automatic behavior
|
|
27
|
+
|
|
28
|
+
You do not need to invoke anything. The plugin wires the host's native session
|
|
29
|
+
hooks: a checkpoint is written automatically when a session **ends**, and the
|
|
30
|
+
briefing appears automatically at the **start** of the next session if a prior
|
|
31
|
+
checkpoint exists. Between those, a lightweight **proactive recall** watches your
|
|
32
|
+
prompts and surfaces a one-line "you worked on this before" pointer when the
|
|
33
|
+
current prompt overlaps a prior open loop — without re-suggesting anything the
|
|
34
|
+
start-of-session briefing already carried.
|
|
35
|
+
|
|
36
|
+
## Manual trigger
|
|
37
|
+
|
|
38
|
+
To re-read the latest briefing on demand, run the bundled CLI:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
daimon brief
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
See the plugin README. Key knobs: `DAIMON_DISABLE=1` (kill switch),
|
|
47
|
+
`DAIMON_CHECKPOINT_DIR`, `DAIMON_MIN_MESSAGES`, `DAIMON_LLM_*` (falling back to
|
|
48
|
+
`LITELLM_*`), `DAIMON_LLM_BACKEND=command` + `DAIMON_LLM_COMMAND` (headless-CLI fallback).
|
|
49
|
+
|
|
50
|
+
## What ships today
|
|
51
|
+
|
|
52
|
+
Daimon is self-contained and host-agnostic — no server, no external memory
|
|
53
|
+
backend, stdlib-only at runtime. The capabilities behind the briefing:
|
|
54
|
+
|
|
55
|
+
- **Checkpoint → briefing loop.** Session end serializes the transcript into a
|
|
56
|
+
per-project JSON checkpoint; session start reconstructs it into the briefing.
|
|
57
|
+
- **Chunked extraction.** Long transcripts are split into overlapping chunks,
|
|
58
|
+
serialized pass-by-pass, then merged — so recall holds up on long sessions
|
|
59
|
+
instead of degrading as the transcript grows.
|
|
60
|
+
- **Deterministic carry.** Unresolved open loops that still matter are carried
|
|
61
|
+
forward into the next checkpoint by exact term overlap (no LLM in the carry
|
|
62
|
+
step) and marked `[carried]` so you can see a loop survived from an earlier
|
|
63
|
+
session rather than being freshly observed.
|
|
64
|
+
- **Proactive recall.** A per-prompt pointer to prior work when your current
|
|
65
|
+
prompt overlaps an open loop (see *Automatic behavior*).
|
|
66
|
+
- **Trust classing.** Every item is `✓ verbatim` (pinned to an exact quote) or
|
|
67
|
+
`~ inferred` (paraphrased), so you know what to trust literally.
|
|
68
|
+
- **Code-drift detection.** `daimon anchor <file> <symbol>` binds a checkpoint
|
|
69
|
+
item to a code symbol; the briefing flags it under **CODE DRIFT — verify
|
|
70
|
+
before trusting** when that symbol's body changes or disappears (offline,
|
|
71
|
+
stdlib `ast`).
|
|
72
|
+
- **Scars.** An optional session-end pass harvests negative-knowledge signals
|
|
73
|
+
(abandoned approaches, landmines) into the repo's `.scars/` directory.
|
|
74
|
+
- **Status & self-heal.** `daimon status` reports checkpoint/briefing health;
|
|
75
|
+
a failed capture self-heals on the next session start.
|
|
@@ -7,6 +7,18 @@ from daimon_briefing import carry
|
|
|
7
7
|
|
|
8
8
|
NOW = 1_760_000_000.0 # arbitrary fixed epoch
|
|
9
9
|
|
|
10
|
+
# Live false-merge specimen (2026-07-02): two UNRELATED items that matched on
|
|
11
|
+
# exactly the generic terms {data, field, validation}. See #13.
|
|
12
|
+
_SPEC_A = ("First external user validation — the core adoption-arc objective "
|
|
13
|
+
"that unblocks _MIN_OVERLAP field data, DAIMON_TEAM validation, and "
|
|
14
|
+
"teammate-noise research questions")
|
|
15
|
+
_SPEC_B = ("Q-STALE + multi-cycle degradation validation — parked on LLM "
|
|
16
|
+
"budget. Need field data: what do 20 serialize cycles do to a "
|
|
17
|
+
"long-lived open loop, and how does that inform decay tuning?")
|
|
18
|
+
# Sibling native item carrying the same generic vocabulary, so {data, field,
|
|
19
|
+
# validation} each reach document-frequency 3 across the kind (A, sibling, B).
|
|
20
|
+
_SPEC_SIB = "extra validation of the data field mapping"
|
|
21
|
+
|
|
10
22
|
|
|
11
23
|
def _iso(days_before_now):
|
|
12
24
|
import datetime as dt
|
|
@@ -135,6 +147,64 @@ def test_same_item_short_texts_never_fuzzy_match():
|
|
|
135
147
|
assert carry._same_item("ok", "ok go") is False
|
|
136
148
|
|
|
137
149
|
|
|
150
|
+
def test_generic_overlap_does_not_false_merge_specimen():
|
|
151
|
+
# Live #13 specimen: fresh native A and unrelated carried B share only the
|
|
152
|
+
# generic terms {data, field, validation}. B must survive as its OWN item;
|
|
153
|
+
# A must NOT inherit B's older birth stamp.
|
|
154
|
+
new = _cp("S-new", 0, questions=[
|
|
155
|
+
_item(_SPEC_A, days=0), _item(_SPEC_SIB, days=1)])
|
|
156
|
+
prev = _cp("S-prev", 1, questions=[_item(_SPEC_B, imp=7, days=45)])
|
|
157
|
+
out = carry.merge(new, prev, NOW)
|
|
158
|
+
qs = out["working_context"]["open_questions"]
|
|
159
|
+
texts = [q["text"] for q in qs]
|
|
160
|
+
assert _SPEC_B in texts # B kept, not erased
|
|
161
|
+
b_item = next(q for q in qs if q["text"] == _SPEC_B)
|
|
162
|
+
assert b_item["carried_from"] == "S-prev"
|
|
163
|
+
a_item = next(q for q in qs if q["text"] == _SPEC_A)
|
|
164
|
+
assert a_item["first_seen"] == _iso(0) # A did NOT inherit B's stamp
|
|
165
|
+
assert "carried_from" not in a_item
|
|
166
|
+
assert len(qs) == 3
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_same_item_generic_filter_is_the_fix_not_a_threshold():
|
|
170
|
+
generic = frozenset({"data", "field", "validation"})
|
|
171
|
+
assert carry._same_item(_SPEC_A, _SPEC_B, generic) is False
|
|
172
|
+
assert carry._same_item(_SPEC_A, _SPEC_B) is True # unfiltered: the bug
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_specific_twin_still_merges_and_inherits_age():
|
|
176
|
+
# Two rewordings sharing SPECIFIC low-DF terms must still match (run-02
|
|
177
|
+
# behavior): the guard filters vocabulary, not identity.
|
|
178
|
+
old = _item("quorint-ledger reconciliation drops entries when upstream "
|
|
179
|
+
"feed pauses", days=45)
|
|
180
|
+
new_twin = _item("quorint-ledger reconciliation still dropping entries on "
|
|
181
|
+
"feed pauses", days=0)
|
|
182
|
+
prev = _cp("S-prev", 1, questions=[
|
|
183
|
+
old, _item("unrelated gavotte pipeline flaking noise", days=3)])
|
|
184
|
+
new = _cp("S-new", 0, questions=[
|
|
185
|
+
new_twin, _item("tervane cache eviction unclear noise", days=1)])
|
|
186
|
+
out = carry.merge(new, prev, NOW)
|
|
187
|
+
qs = out["working_context"]["open_questions"]
|
|
188
|
+
twin = next(q for q in qs if "still dropping" in q["text"])
|
|
189
|
+
assert twin["first_seen"] == _iso(45) # matched -> age inherited
|
|
190
|
+
assert not any("drops entries" in q["text"] for q in qs) # not duplicated
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_post_filter_floor_blocks_single_shared_term():
|
|
194
|
+
generic = frozenset({"data", "field", "validation"})
|
|
195
|
+
a = "data field validation alpha" # filtered -> {alpha}
|
|
196
|
+
b = "data field validation alpha bravo" # filtered -> {alpha, bravo}
|
|
197
|
+
# ratio would be 1/1 = 1.0 >= _MIN_RATIO without the floor; floor blocks it
|
|
198
|
+
assert carry._same_item(a, b, generic) is False
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def test_generic_terms_df_boundary():
|
|
202
|
+
texts = ["zeta omega alpha", "zeta omega beta", "omega gamma delta"]
|
|
203
|
+
generic = carry._generic_terms(texts) # k defaults to _GENERIC_DF (3)
|
|
204
|
+
assert "omega" in generic # 3 distinct texts -> generic
|
|
205
|
+
assert "zeta" not in generic # exactly 2 distinct texts -> not generic
|
|
206
|
+
|
|
207
|
+
|
|
138
208
|
def test_in_call_duplicate_prev_items_carry_once():
|
|
139
209
|
# Two prev items with IDENTICAL text: native_texts must pick up the first
|
|
140
210
|
# one as it's appended, so the second (an exact twin) is skipped too.
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: daimon-briefing
|
|
3
|
-
description: Dream-briefing — surfaces a "while you were away / here's where we left off" briefing at the start of a resumed session, reconstructed from a cognitive checkpoint written at the end of the prior session. Use to recall open loops, decisions, and facts whose state may have changed outside the AI session (e.g. a PR you merged yourself).
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Daimon Dream-Briefing
|
|
7
|
-
|
|
8
|
-
This plugin keeps continuity across sessions. At the **end** of each session it
|
|
9
|
-
serializes the transcript into a cognitive checkpoint (open loops, decisions,
|
|
10
|
-
beliefs, with extractively-pinned verbatim quotes). At the **start** of the next
|
|
11
|
-
session it injects a skimmable briefing so you resume from a faithful prior state
|
|
12
|
-
instead of a confident guess.
|
|
13
|
-
|
|
14
|
-
## What it surfaces, in order
|
|
15
|
-
|
|
16
|
-
1. **Verify before trusting** — items whose state may have changed *outside* this
|
|
17
|
-
session (a PR you said you'd merge, a deploy, a file edited elsewhere). These come
|
|
18
|
-
first because they are the gap that produces confident-but-wrong assertions.
|
|
19
|
-
2. **Open loops** — questions left unresolved at the end of last session.
|
|
20
|
-
3. **Decisions made** — explicit choices, including assistant-side fixes/diagnoses.
|
|
21
|
-
4. **Active topic / beliefs / uncertainties.**
|
|
22
|
-
|
|
23
|
-
Each item is marked `✓ verbatim` (pinned to an exact quote — trust it) or
|
|
24
|
-
`~ inferred` (paraphrased — treat with appropriate caution).
|
|
25
|
-
|
|
26
|
-
## Automatic behavior
|
|
27
|
-
|
|
28
|
-
You do not need to invoke anything. The briefing appears automatically on the first
|
|
29
|
-
turn of a new session if a prior checkpoint exists. Checkpoints are written
|
|
30
|
-
automatically when a session ends.
|
|
31
|
-
|
|
32
|
-
## Manual trigger
|
|
33
|
-
|
|
34
|
-
To re-read the latest briefing on demand, run the bundled CLI:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
daimon brief
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Configuration
|
|
41
|
-
|
|
42
|
-
See the plugin README. Key knobs: `DAIMON_DISABLE=1` (kill switch),
|
|
43
|
-
`DAIMON_CHECKPOINT_DIR`, `DAIMON_MIN_MESSAGES`, `DAIMON_LLM_*` (falling back to
|
|
44
|
-
`LITELLM_*`), `DAIMON_LLM_BACKEND=command` + `DAIMON_LLM_COMMAND` (headless-CLI fallback).
|
|
45
|
-
|
|
46
|
-
## Scope (Slice 1)
|
|
47
|
-
|
|
48
|
-
Local-file checkpoints, single-pass serialization, no Honcho. Long-transcript recall
|
|
49
|
-
(chunking) is Slice 2; Honcho-backed cross-session recall is Slice 3.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|