lifeline-context 0.1.0__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.
- lifeline_context-0.1.0/LICENSE +21 -0
- lifeline_context-0.1.0/PKG-INFO +241 -0
- lifeline_context-0.1.0/README.md +208 -0
- lifeline_context-0.1.0/lifeline/__init__.py +17 -0
- lifeline_context-0.1.0/lifeline/__main__.py +3 -0
- lifeline_context-0.1.0/lifeline/cli.py +447 -0
- lifeline_context-0.1.0/lifeline/cloud.py +184 -0
- lifeline_context-0.1.0/lifeline/context.py +107 -0
- lifeline_context-0.1.0/lifeline/entry.py +65 -0
- lifeline_context-0.1.0/lifeline/ingest.py +82 -0
- lifeline_context-0.1.0/lifeline/mcp_server.py +247 -0
- lifeline_context-0.1.0/lifeline/projection.py +37 -0
- lifeline_context-0.1.0/lifeline/recall.py +82 -0
- lifeline_context-0.1.0/lifeline/staging.py +94 -0
- lifeline_context-0.1.0/lifeline/state.py +80 -0
- lifeline_context-0.1.0/lifeline/store.py +127 -0
- lifeline_context-0.1.0/lifeline/sync.py +40 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/PKG-INFO +241 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/SOURCES.txt +34 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/dependency_links.txt +1 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/entry_points.txt +4 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/requires.txt +10 -0
- lifeline_context-0.1.0/lifeline_context.egg-info/top_level.txt +1 -0
- lifeline_context-0.1.0/pyproject.toml +55 -0
- lifeline_context-0.1.0/setup.cfg +4 -0
- lifeline_context-0.1.0/tests/test_cli.py +96 -0
- lifeline_context-0.1.0/tests/test_context.py +89 -0
- lifeline_context-0.1.0/tests/test_entry.py +58 -0
- lifeline_context-0.1.0/tests/test_mcp.py +128 -0
- lifeline_context-0.1.0/tests/test_projection.py +80 -0
- lifeline_context-0.1.0/tests/test_recall.py +68 -0
- lifeline_context-0.1.0/tests/test_staging.py +61 -0
- lifeline_context-0.1.0/tests/test_state.py +93 -0
- lifeline_context-0.1.0/tests/test_store.py +71 -0
- lifeline_context-0.1.0/tests/test_supabase.py +293 -0
- lifeline_context-0.1.0/tests/test_sync.py +67 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jessi (jessianjmb@gmail.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lifeline-context
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Runtime de contexto para desenvolvimento com IA — o projeto guarda por que ele é o que é; qualquer IA conecta e já sabe.
|
|
5
|
+
Author: jessianmart
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jessianmart/lifeline
|
|
8
|
+
Project-URL: Repository, https://github.com/jessianmart/lifeline
|
|
9
|
+
Project-URL: Issues, https://github.com/jessianmart/lifeline/issues
|
|
10
|
+
Keywords: mcp,ai,llm,context,memory,ledger,agents,claude,provenance
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: aiosqlite>=0.19
|
|
26
|
+
Requires-Dist: mcp>=1.0
|
|
27
|
+
Requires-Dist: httpx>=0.27
|
|
28
|
+
Provides-Extra: cloud
|
|
29
|
+
Requires-Dist: httpx>=0.27; extra == "cloud"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Lifeline
|
|
35
|
+
|
|
36
|
+
> **A context runtime for AI-assisted development.** The project stores *why* it is what it
|
|
37
|
+
> is — and any AI connects and **already knows**, with no human re-explaining.
|
|
38
|
+
|
|
39
|
+
🌐 **English** · [Português](README.pt-BR.md)
|
|
40
|
+
|
|
41
|
+
   
|
|
42
|
+
|
|
43
|
+
In one line, it's **"git for reasoning"**: just as git versions *what* changed in the code,
|
|
44
|
+
Lifeline versions *why* — decisions, reversals, incidents, the current state — in an
|
|
45
|
+
append-only, content-addressed ledger that lives inside the project. Any model (Claude, GPT,
|
|
46
|
+
Gemini), in any session, reconstructs the context the moment it connects via MCP.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## The problem
|
|
51
|
+
|
|
52
|
+
AI assistants are **stateless across sessions**. With every new session, agent, or provider,
|
|
53
|
+
the human becomes the memory bus — re-explaining decisions that already existed. The naive
|
|
54
|
+
fix (a living markdown log) works until it blows past the context window. "Memory" tools
|
|
55
|
+
store text/vectors with no provenance → hallucinated recall.
|
|
56
|
+
|
|
57
|
+
## The idea
|
|
58
|
+
|
|
59
|
+
The **north star** is a single metric — **Time-to-Context (TTC) → 0** — operationalized by an
|
|
60
|
+
acceptance test:
|
|
61
|
+
|
|
62
|
+
> A fresh AI connects, **with no human in the loop**, and correctly answers:
|
|
63
|
+
> **what / why / what's decided / what's next?**
|
|
64
|
+
|
|
65
|
+
Lifeline keeps the project's "lifeline" (the `LIFELINE.md`) and makes it **queryable,
|
|
66
|
+
compressible, and anchored** — so it never overflows the window and never hallucinates.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install lifeline-context # once published to PyPI
|
|
74
|
+
pip install -e . # or, from the repo root (dev) → installs lifeline, lifeline-mcp, lifeline-mcp-remote
|
|
75
|
+
pip install -e ".[cloud]" # optional: cloud mode (Supabase) — pulls httpx explicitly
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Dependencies: `pydantic`, `aiosqlite`, `mcp`, `httpx`. Python ≥ 3.10.
|
|
79
|
+
|
|
80
|
+
## Quickstart (CLI)
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# In ANY of your projects — each gets its own .lifeline/ledger.db:
|
|
84
|
+
lifeline log --kind bootstrap --summary "Bootstrap project X" --body "Multi-tenant billing API."
|
|
85
|
+
lifeline log --kind decision --summary "DB: PostgreSQL" --body "ACID required by audit."
|
|
86
|
+
|
|
87
|
+
lifeline context # prints the assembled current truth (what an AI reads)
|
|
88
|
+
lifeline context --query "database" # prioritizes what's relevant to the task (Layer 3)
|
|
89
|
+
lifeline verify # checks the chain's integrity
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`LIFELINE.md` regenerates on every `log` — **don't hand-edit it**. On a fresh clone without
|
|
93
|
+
`.lifeline/`, rebuild the cache with `lifeline migrate --from LIFELINE.md`.
|
|
94
|
+
|
|
95
|
+
## Connect it to your AI (zero config in Claude Code)
|
|
96
|
+
|
|
97
|
+
Lifeline ships a local **MCP server** (`lifeline-mcp`, stdio). On connect, the AI gets the
|
|
98
|
+
`lifeline://project/context` resource + tools (`lifeline_recall`, and write tools that are
|
|
99
|
+
**HITL** — they *propose*; the human approves). Server config is in [`.mcp.json`](.mcp.json):
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{ "mcpServers": { "lifeline": {
|
|
103
|
+
"command": "lifeline-mcp", "args": [],
|
|
104
|
+
"env": { "LIFELINE_DB": ".lifeline/ledger.db" } } } }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **Claude Code** reads `.mcp.json` **automatically**.
|
|
108
|
+
- **Cursor / Claude Desktop / Gemini CLI:** copy-paste snippets in [`docs/INTEGRATION.md`](docs/INTEGRATION.md).
|
|
109
|
+
- **Web chat apps** (claude.ai, ChatGPT) need a remote server + OAuth — see [`docs/MCP_REMOTE.md`](docs/MCP_REMOTE.md).
|
|
110
|
+
|
|
111
|
+
## Quickstart (Python SDK)
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import asyncio
|
|
115
|
+
from lifeline import Entry, SQLiteEventStore, StateEngine, ContextAssembler, SemanticRecall
|
|
116
|
+
|
|
117
|
+
async def main():
|
|
118
|
+
store = SQLiteEventStore(".lifeline/ledger.db")
|
|
119
|
+
await store.initialize()
|
|
120
|
+
await store.append(Entry(kind="decision", author="me",
|
|
121
|
+
summary="DB: PostgreSQL", body="ACID for audit."))
|
|
122
|
+
ctx = await ContextAssembler(StateEngine(store)).assemble() # ready to inject into a prompt
|
|
123
|
+
print(ctx)
|
|
124
|
+
hits = await SemanticRecall(store).search("which database", k=3) # anchored relevance
|
|
125
|
+
|
|
126
|
+
asyncio.run(main())
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## The loop (do both sides)
|
|
132
|
+
|
|
133
|
+
- **On connect:** load the context (`lifeline context` or the MCP resource) before acting.
|
|
134
|
+
- **While working:** on each decision/feature/fix/incident, **append** (`lifeline log` or
|
|
135
|
+
`lifeline_append`). Reversed something? `lifeline_recontextualize` (supersede by id).
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
CONNECT (read) WRITE (append)
|
|
139
|
+
lifeline context ┌─────────────┐ reduce ┌──────────┐ rank+ lifeline log
|
|
140
|
+
MCP resource ──────────▶│ Layer 1 │─────────▶│ Layer 2 │ budget lifeline_append
|
|
141
|
+
lifeline://…/context │ Ledger │ │ State │────────▶ (HITL: propose)
|
|
142
|
+
Layer 3 (recall) ──────▶│ (immutable │ │ (current │
|
|
143
|
+
anchored relevance │ DAG) │ │ truth) │
|
|
144
|
+
└──────┬──────┘ └────┬─────┘
|
|
145
|
+
│ projection (store → markdown) ▼
|
|
146
|
+
└──────────────▶ LIFELINE.md (generated view, git-diffable)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Core concepts
|
|
150
|
+
|
|
151
|
+
- **Entry** — the atomic unit. Content-addressed: `id = sha256(kind, author, agent, provider,
|
|
152
|
+
model, summary, body, sorted-parents)`. `ts` and `dedup_key` are **outside** the hash → the
|
|
153
|
+
same content yields the same `id` on any machine (the basis for dedup and sync).
|
|
154
|
+
- **3 memory layers** (all anchored to the immutable ledger): **Ledger** (hashed append-only
|
|
155
|
+
DAG, source of truth) · **State** (current truth reduced via reducers; status is a
|
|
156
|
+
projection, not a state machine) · **Recall** (relevance search; every hit anchored to its
|
|
157
|
+
source event).
|
|
158
|
+
- **Supersession** — a `correction` referencing another entry's `id` removes it from the
|
|
159
|
+
current truth (reverted decision, closed thread). Append-only: the past is never edited.
|
|
160
|
+
- **Anti-hallucination anchor** — every item the AI reads carries its source event's hash.
|
|
161
|
+
No anchor, no entry.
|
|
162
|
+
|
|
163
|
+
Full detail in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
|
|
164
|
+
|
|
165
|
+
## CLI reference
|
|
166
|
+
|
|
167
|
+
| Command | What it does |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `lifeline log --kind … --summary … [--body … --parents id,…]` | **human:** append directly to the line (you're the approver) + regenerate the view |
|
|
170
|
+
| `lifeline propose --kind … --summary … --body …` | propose an entry (**HITL**) — stays pending, not in the line |
|
|
171
|
+
| `lifeline review` · `approve <pid\|all>` · `reject <pid\|all>` | HITL curation: list / seal / discard |
|
|
172
|
+
| `lifeline context [--query "…"] [--budget N]` | print the assembled current truth (relevance if `--query`) |
|
|
173
|
+
| `lifeline verify` | check that every `id` matches its content |
|
|
174
|
+
| `lifeline rebuild` · `migrate --from LIFELINE.md` | regenerate the view / rebuild the `.db` from markdown |
|
|
175
|
+
| `lifeline lines` | list the project's lines (`.lifeline/*.db`) |
|
|
176
|
+
| `lifeline push` · `pull` · `clone <url> <dir>` | **git sync** (Tier 0, zero cost): the text view syncs; the `.db` rebuilds |
|
|
177
|
+
|
|
178
|
+
**Write tiering (like approving a shell command):** the human's `log` commits directly (they're
|
|
179
|
+
the approver); the **AI via MCP `propose`** enters as a **pending** proposal (HITL), and a human
|
|
180
|
+
**approves** before it becomes truth. Write-time anti-junk requires the *why*; junk never enters.
|
|
181
|
+
|
|
182
|
+
Globals: `--db` (default `.lifeline/ledger.db`) · **`--line <name>`** maps a named *line* —
|
|
183
|
+
ledger **and** view together (`.lifeline/<name>.db` + `LIFELINE.<name>.md`), no collisions.
|
|
184
|
+
A **line** = one reasoning ledger (code *or* conversation); a project has 1 by default, supports N.
|
|
185
|
+
|
|
186
|
+
## Local → cloud (graduation)
|
|
187
|
+
|
|
188
|
+
Everything is content-addressed → **pushing a local line to the cloud is lossless and
|
|
189
|
+
idempotent**: same ids, re-seed dedupes itself.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
lifeline --store supabase migrate --from LIFELINE.md # seed (repeatable — no dupes)
|
|
193
|
+
lifeline --store supabase context # now operate against the cloud
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Just share the *text* (no cloud)? `lifeline push` (Tier 0 — git). Cloud setup + auth:
|
|
197
|
+
[`docs/M3_TIER1_SUPABASE.md`](docs/M3_TIER1_SUPABASE.md) · `.env.example`.
|
|
198
|
+
|
|
199
|
+
## The 7 laws (the constitution)
|
|
200
|
+
|
|
201
|
+
1. **No memory without an immutable anchor** (anti-hallucination). 2. **Append-only** (corrections
|
|
202
|
+
are new entries). 3. **Deterministic content-addressing.** 4. **Provider-agnostic storage; deliver
|
|
203
|
+
in the provider's format.** 5. **The *why* outweighs the *what*.** 6. **Budget is first-class**
|
|
204
|
+
(truncation always explicit). 7. **MCP-native.**
|
|
205
|
+
|
|
206
|
+
**Non-goals:** Lifeline is NOT a cognitive OS, MMU, agent orchestrator/sandbox, workflow engine,
|
|
207
|
+
a git replacement, an executor/curator (self-healing), or a trainer (fine-tuning). **It records
|
|
208
|
+
reasoning, not execution.**
|
|
209
|
+
|
|
210
|
+
## Status & roadmap
|
|
211
|
+
|
|
212
|
+
**Alpha.** Solid, proven **local single-user** core — correctness locked by tests (determinism,
|
|
213
|
+
anti-tamper, supersession, round-trip fixed-point). **Cloud (M3) functional and live-validated.**
|
|
214
|
+
75 tests green; CI on GitHub Actions.
|
|
215
|
+
|
|
216
|
+
| Milestone | State |
|
|
217
|
+
|---|---|
|
|
218
|
+
| **M1 / M1.5** — the loop (ledger→state→assembly→MCP), authorship, recall, CLI, store-is-source | ✅ done |
|
|
219
|
+
| **M3 Tier 0** — git sync | ✅ done |
|
|
220
|
+
| **M3 Tier 1** — Supabase store + append-only RLS + cloud HITL | ✅ live-validated |
|
|
221
|
+
| **M3** — remote MCP (HTTP/SSE) + OAuth **Resource Server** (multi-tenant) | ✅ done |
|
|
222
|
+
| **M2** — dense semantic embedder (default is lexical) | open (#0029) |
|
|
223
|
+
| **OAuth Authorization Server** (DCR/auth-code for hosted connectors) | open (#0049) |
|
|
224
|
+
| **M4** — multi-user (concurrent DAG merge) / hub | planned |
|
|
225
|
+
|
|
226
|
+
**Honest limits today:** recall is lexical (keywords, not meaning — #0029); a hosted **paid**
|
|
227
|
+
cloud needs the AS + billing (#0049) — today it's **local OSS + bring-your-own-Supabase**; no
|
|
228
|
+
retry/backoff in the cloud adapter yet (log+raise only).
|
|
229
|
+
|
|
230
|
+
## Built by dogfooding
|
|
231
|
+
|
|
232
|
+
Lifeline was rebuilt **using itself from entry #0001**: every decision became an anchored entry
|
|
233
|
+
in `LIFELINE.md`. The process surfaced **real bugs in actual use** that unit tests missed
|
|
234
|
+
(taxonomy, encoding, false relevance) — all recorded. The proof it works is that the repo needs
|
|
235
|
+
no one to explain it.
|
|
236
|
+
|
|
237
|
+
## Contributing & license
|
|
238
|
+
|
|
239
|
+
The rule is the constitution: **if you touched it, append to the line.** See
|
|
240
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md) · [`AGENTS.md`](AGENTS.md) · [`llms.txt`](llms.txt).
|
|
241
|
+
Licensed [MIT](LICENSE) — open-source core; cloud mode is open-core.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Lifeline
|
|
2
|
+
|
|
3
|
+
> **A context runtime for AI-assisted development.** The project stores *why* it is what it
|
|
4
|
+
> is — and any AI connects and **already knows**, with no human re-explaining.
|
|
5
|
+
|
|
6
|
+
🌐 **English** · [Português](README.pt-BR.md)
|
|
7
|
+
|
|
8
|
+
   
|
|
9
|
+
|
|
10
|
+
In one line, it's **"git for reasoning"**: just as git versions *what* changed in the code,
|
|
11
|
+
Lifeline versions *why* — decisions, reversals, incidents, the current state — in an
|
|
12
|
+
append-only, content-addressed ledger that lives inside the project. Any model (Claude, GPT,
|
|
13
|
+
Gemini), in any session, reconstructs the context the moment it connects via MCP.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## The problem
|
|
18
|
+
|
|
19
|
+
AI assistants are **stateless across sessions**. With every new session, agent, or provider,
|
|
20
|
+
the human becomes the memory bus — re-explaining decisions that already existed. The naive
|
|
21
|
+
fix (a living markdown log) works until it blows past the context window. "Memory" tools
|
|
22
|
+
store text/vectors with no provenance → hallucinated recall.
|
|
23
|
+
|
|
24
|
+
## The idea
|
|
25
|
+
|
|
26
|
+
The **north star** is a single metric — **Time-to-Context (TTC) → 0** — operationalized by an
|
|
27
|
+
acceptance test:
|
|
28
|
+
|
|
29
|
+
> A fresh AI connects, **with no human in the loop**, and correctly answers:
|
|
30
|
+
> **what / why / what's decided / what's next?**
|
|
31
|
+
|
|
32
|
+
Lifeline keeps the project's "lifeline" (the `LIFELINE.md`) and makes it **queryable,
|
|
33
|
+
compressible, and anchored** — so it never overflows the window and never hallucinates.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install lifeline-context # once published to PyPI
|
|
41
|
+
pip install -e . # or, from the repo root (dev) → installs lifeline, lifeline-mcp, lifeline-mcp-remote
|
|
42
|
+
pip install -e ".[cloud]" # optional: cloud mode (Supabase) — pulls httpx explicitly
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Dependencies: `pydantic`, `aiosqlite`, `mcp`, `httpx`. Python ≥ 3.10.
|
|
46
|
+
|
|
47
|
+
## Quickstart (CLI)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# In ANY of your projects — each gets its own .lifeline/ledger.db:
|
|
51
|
+
lifeline log --kind bootstrap --summary "Bootstrap project X" --body "Multi-tenant billing API."
|
|
52
|
+
lifeline log --kind decision --summary "DB: PostgreSQL" --body "ACID required by audit."
|
|
53
|
+
|
|
54
|
+
lifeline context # prints the assembled current truth (what an AI reads)
|
|
55
|
+
lifeline context --query "database" # prioritizes what's relevant to the task (Layer 3)
|
|
56
|
+
lifeline verify # checks the chain's integrity
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`LIFELINE.md` regenerates on every `log` — **don't hand-edit it**. On a fresh clone without
|
|
60
|
+
`.lifeline/`, rebuild the cache with `lifeline migrate --from LIFELINE.md`.
|
|
61
|
+
|
|
62
|
+
## Connect it to your AI (zero config in Claude Code)
|
|
63
|
+
|
|
64
|
+
Lifeline ships a local **MCP server** (`lifeline-mcp`, stdio). On connect, the AI gets the
|
|
65
|
+
`lifeline://project/context` resource + tools (`lifeline_recall`, and write tools that are
|
|
66
|
+
**HITL** — they *propose*; the human approves). Server config is in [`.mcp.json`](.mcp.json):
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{ "mcpServers": { "lifeline": {
|
|
70
|
+
"command": "lifeline-mcp", "args": [],
|
|
71
|
+
"env": { "LIFELINE_DB": ".lifeline/ledger.db" } } } }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- **Claude Code** reads `.mcp.json` **automatically**.
|
|
75
|
+
- **Cursor / Claude Desktop / Gemini CLI:** copy-paste snippets in [`docs/INTEGRATION.md`](docs/INTEGRATION.md).
|
|
76
|
+
- **Web chat apps** (claude.ai, ChatGPT) need a remote server + OAuth — see [`docs/MCP_REMOTE.md`](docs/MCP_REMOTE.md).
|
|
77
|
+
|
|
78
|
+
## Quickstart (Python SDK)
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import asyncio
|
|
82
|
+
from lifeline import Entry, SQLiteEventStore, StateEngine, ContextAssembler, SemanticRecall
|
|
83
|
+
|
|
84
|
+
async def main():
|
|
85
|
+
store = SQLiteEventStore(".lifeline/ledger.db")
|
|
86
|
+
await store.initialize()
|
|
87
|
+
await store.append(Entry(kind="decision", author="me",
|
|
88
|
+
summary="DB: PostgreSQL", body="ACID for audit."))
|
|
89
|
+
ctx = await ContextAssembler(StateEngine(store)).assemble() # ready to inject into a prompt
|
|
90
|
+
print(ctx)
|
|
91
|
+
hits = await SemanticRecall(store).search("which database", k=3) # anchored relevance
|
|
92
|
+
|
|
93
|
+
asyncio.run(main())
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## The loop (do both sides)
|
|
99
|
+
|
|
100
|
+
- **On connect:** load the context (`lifeline context` or the MCP resource) before acting.
|
|
101
|
+
- **While working:** on each decision/feature/fix/incident, **append** (`lifeline log` or
|
|
102
|
+
`lifeline_append`). Reversed something? `lifeline_recontextualize` (supersede by id).
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
CONNECT (read) WRITE (append)
|
|
106
|
+
lifeline context ┌─────────────┐ reduce ┌──────────┐ rank+ lifeline log
|
|
107
|
+
MCP resource ──────────▶│ Layer 1 │─────────▶│ Layer 2 │ budget lifeline_append
|
|
108
|
+
lifeline://…/context │ Ledger │ │ State │────────▶ (HITL: propose)
|
|
109
|
+
Layer 3 (recall) ──────▶│ (immutable │ │ (current │
|
|
110
|
+
anchored relevance │ DAG) │ │ truth) │
|
|
111
|
+
└──────┬──────┘ └────┬─────┘
|
|
112
|
+
│ projection (store → markdown) ▼
|
|
113
|
+
└──────────────▶ LIFELINE.md (generated view, git-diffable)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Core concepts
|
|
117
|
+
|
|
118
|
+
- **Entry** — the atomic unit. Content-addressed: `id = sha256(kind, author, agent, provider,
|
|
119
|
+
model, summary, body, sorted-parents)`. `ts` and `dedup_key` are **outside** the hash → the
|
|
120
|
+
same content yields the same `id` on any machine (the basis for dedup and sync).
|
|
121
|
+
- **3 memory layers** (all anchored to the immutable ledger): **Ledger** (hashed append-only
|
|
122
|
+
DAG, source of truth) · **State** (current truth reduced via reducers; status is a
|
|
123
|
+
projection, not a state machine) · **Recall** (relevance search; every hit anchored to its
|
|
124
|
+
source event).
|
|
125
|
+
- **Supersession** — a `correction` referencing another entry's `id` removes it from the
|
|
126
|
+
current truth (reverted decision, closed thread). Append-only: the past is never edited.
|
|
127
|
+
- **Anti-hallucination anchor** — every item the AI reads carries its source event's hash.
|
|
128
|
+
No anchor, no entry.
|
|
129
|
+
|
|
130
|
+
Full detail in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
|
|
131
|
+
|
|
132
|
+
## CLI reference
|
|
133
|
+
|
|
134
|
+
| Command | What it does |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `lifeline log --kind … --summary … [--body … --parents id,…]` | **human:** append directly to the line (you're the approver) + regenerate the view |
|
|
137
|
+
| `lifeline propose --kind … --summary … --body …` | propose an entry (**HITL**) — stays pending, not in the line |
|
|
138
|
+
| `lifeline review` · `approve <pid\|all>` · `reject <pid\|all>` | HITL curation: list / seal / discard |
|
|
139
|
+
| `lifeline context [--query "…"] [--budget N]` | print the assembled current truth (relevance if `--query`) |
|
|
140
|
+
| `lifeline verify` | check that every `id` matches its content |
|
|
141
|
+
| `lifeline rebuild` · `migrate --from LIFELINE.md` | regenerate the view / rebuild the `.db` from markdown |
|
|
142
|
+
| `lifeline lines` | list the project's lines (`.lifeline/*.db`) |
|
|
143
|
+
| `lifeline push` · `pull` · `clone <url> <dir>` | **git sync** (Tier 0, zero cost): the text view syncs; the `.db` rebuilds |
|
|
144
|
+
|
|
145
|
+
**Write tiering (like approving a shell command):** the human's `log` commits directly (they're
|
|
146
|
+
the approver); the **AI via MCP `propose`** enters as a **pending** proposal (HITL), and a human
|
|
147
|
+
**approves** before it becomes truth. Write-time anti-junk requires the *why*; junk never enters.
|
|
148
|
+
|
|
149
|
+
Globals: `--db` (default `.lifeline/ledger.db`) · **`--line <name>`** maps a named *line* —
|
|
150
|
+
ledger **and** view together (`.lifeline/<name>.db` + `LIFELINE.<name>.md`), no collisions.
|
|
151
|
+
A **line** = one reasoning ledger (code *or* conversation); a project has 1 by default, supports N.
|
|
152
|
+
|
|
153
|
+
## Local → cloud (graduation)
|
|
154
|
+
|
|
155
|
+
Everything is content-addressed → **pushing a local line to the cloud is lossless and
|
|
156
|
+
idempotent**: same ids, re-seed dedupes itself.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
lifeline --store supabase migrate --from LIFELINE.md # seed (repeatable — no dupes)
|
|
160
|
+
lifeline --store supabase context # now operate against the cloud
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Just share the *text* (no cloud)? `lifeline push` (Tier 0 — git). Cloud setup + auth:
|
|
164
|
+
[`docs/M3_TIER1_SUPABASE.md`](docs/M3_TIER1_SUPABASE.md) · `.env.example`.
|
|
165
|
+
|
|
166
|
+
## The 7 laws (the constitution)
|
|
167
|
+
|
|
168
|
+
1. **No memory without an immutable anchor** (anti-hallucination). 2. **Append-only** (corrections
|
|
169
|
+
are new entries). 3. **Deterministic content-addressing.** 4. **Provider-agnostic storage; deliver
|
|
170
|
+
in the provider's format.** 5. **The *why* outweighs the *what*.** 6. **Budget is first-class**
|
|
171
|
+
(truncation always explicit). 7. **MCP-native.**
|
|
172
|
+
|
|
173
|
+
**Non-goals:** Lifeline is NOT a cognitive OS, MMU, agent orchestrator/sandbox, workflow engine,
|
|
174
|
+
a git replacement, an executor/curator (self-healing), or a trainer (fine-tuning). **It records
|
|
175
|
+
reasoning, not execution.**
|
|
176
|
+
|
|
177
|
+
## Status & roadmap
|
|
178
|
+
|
|
179
|
+
**Alpha.** Solid, proven **local single-user** core — correctness locked by tests (determinism,
|
|
180
|
+
anti-tamper, supersession, round-trip fixed-point). **Cloud (M3) functional and live-validated.**
|
|
181
|
+
75 tests green; CI on GitHub Actions.
|
|
182
|
+
|
|
183
|
+
| Milestone | State |
|
|
184
|
+
|---|---|
|
|
185
|
+
| **M1 / M1.5** — the loop (ledger→state→assembly→MCP), authorship, recall, CLI, store-is-source | ✅ done |
|
|
186
|
+
| **M3 Tier 0** — git sync | ✅ done |
|
|
187
|
+
| **M3 Tier 1** — Supabase store + append-only RLS + cloud HITL | ✅ live-validated |
|
|
188
|
+
| **M3** — remote MCP (HTTP/SSE) + OAuth **Resource Server** (multi-tenant) | ✅ done |
|
|
189
|
+
| **M2** — dense semantic embedder (default is lexical) | open (#0029) |
|
|
190
|
+
| **OAuth Authorization Server** (DCR/auth-code for hosted connectors) | open (#0049) |
|
|
191
|
+
| **M4** — multi-user (concurrent DAG merge) / hub | planned |
|
|
192
|
+
|
|
193
|
+
**Honest limits today:** recall is lexical (keywords, not meaning — #0029); a hosted **paid**
|
|
194
|
+
cloud needs the AS + billing (#0049) — today it's **local OSS + bring-your-own-Supabase**; no
|
|
195
|
+
retry/backoff in the cloud adapter yet (log+raise only).
|
|
196
|
+
|
|
197
|
+
## Built by dogfooding
|
|
198
|
+
|
|
199
|
+
Lifeline was rebuilt **using itself from entry #0001**: every decision became an anchored entry
|
|
200
|
+
in `LIFELINE.md`. The process surfaced **real bugs in actual use** that unit tests missed
|
|
201
|
+
(taxonomy, encoding, false relevance) — all recorded. The proof it works is that the repo needs
|
|
202
|
+
no one to explain it.
|
|
203
|
+
|
|
204
|
+
## Contributing & license
|
|
205
|
+
|
|
206
|
+
The rule is the constitution: **if you touched it, append to the line.** See
|
|
207
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md) · [`AGENTS.md`](AGENTS.md) · [`llms.txt`](llms.txt).
|
|
208
|
+
Licensed [MIT](LICENSE) — open-source core; cloud mode is open-core.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Lifeline — runtime de contexto. O projeto guarda *por que* ele é o que é."""
|
|
2
|
+
from lifeline.entry import Entry, GENESIS
|
|
3
|
+
from lifeline.store import EventStore, SQLiteEventStore
|
|
4
|
+
from lifeline.state import StateEngine, ledger_projection
|
|
5
|
+
from lifeline.context import ContextAssembler
|
|
6
|
+
from lifeline.recall import Embedder, LexicalEmbedder, SemanticRecall
|
|
7
|
+
from lifeline.staging import StagingStore, SQLiteStagingStore
|
|
8
|
+
|
|
9
|
+
__version__ = "0.1.0"
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Entry", "GENESIS",
|
|
12
|
+
"EventStore", "SQLiteEventStore",
|
|
13
|
+
"StateEngine", "ledger_projection",
|
|
14
|
+
"ContextAssembler",
|
|
15
|
+
"Embedder", "LexicalEmbedder", "SemanticRecall",
|
|
16
|
+
"StagingStore", "SQLiteStagingStore",
|
|
17
|
+
]
|