-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
141 lines (133 loc) · 8.05 KB
/
Copy pathpyproject.toml
File metadata and controls
141 lines (133 loc) · 8.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
[build-system]
requires = ["setuptools>=77"]
build-backend = "setuptools.build_meta"
[project]
name = "levain"
version = "0.4.8.dev0"
description = "A portable cognitive-partnership memory + methodology kit. Ship the seed that grows a practice, not the practice."
readme = "README.md"
requires-python = ">=3.12"
license = "Apache-2.0"
license-files = ["LICENSE", "NOTICE"]
authors = [{ name = "Phill Clapham" }]
keywords = [
"agent",
"ai",
"anneal-memory",
"claude-code",
"codex",
"cognitive-partnership",
"memory",
"methodology",
]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Libraries",
]
dependencies = [
# Partnership seed needs the 0.8.x stack: spores (0.4.0), schema-aware
# budget (0.4.2), `init --schema partnership` (0.4.4 — AM-INITSCHEMA), the
# crystallized-pattern tier (0.6.0 store + 0.7.0 opt-in / `crystal index`+
# `recall` / `retrieve_patterns`), the AM-CRYSTAL-RECALL associative
# (Hebbian) backend (0.8.0) that makes crystallized recall fire by meaning,
# AND the AM-CONTLOCK shared `continuity_lock` (0.9.0) the governed State /
# undo writes take to serialize against the anneal consolidate cross-process.
# The prior `<0.8` ceiling capped adopters out of the 0.8.x crystal-recall
# tier (spore-060); `<0.5` before that predated crystals entirely. (0.9.0
# ships with anneal Slice C — main carries this pin ahead of the PyPI publish,
# per the coordinated shadow-ship plan.) `>=0.9.1` is REQUIRED: Slice-3b's Tray
# write seam calls the SporeStore disposition passthrough + the expect_disposition
# CAS, both added in 0.9.1 — an older 0.9.0 would TypeError at runtime, not refuse
# cleanly [codex L3 HIGH], so the API contract is version-gated, not feature-detected.
# `>=0.9.4` (AM-SPORE-CAS): the KEEP-NOTE LIFECYCLE's `_apply_spore_verb` ascend guard now
# passes `expect_disposition` to `SporeStore.ascend` (the ascend CAS added in 0.9.4) — same
# version-gated contract: an older anneal lacks the param and would TypeError, not refuse.
# `>=0.9.5` (AM-SPORE-CAS-DESCEND, spore-173): `_apply_spore_verb`'s descend branch now passes
# `expect_disposition` to `SporeStore.descend` (the descend CAS added in 0.9.5). Same contract —
# 0.9.4's `descend` has no such param, so the first compost/dismiss/remove would TypeError, not
# refuse cleanly. (The tier CAS rides `update`'s expect_disposition, present since 0.9.1.)
# `>=0.9.8` (AM-MCP-WRAPCANCEL): a real API contract gate, not a lockstep bump.
# The hook's `[wrap blocked]` line names the `wrap_cancel` MCP tool as the way out
# of a stuck wrap, and that tool does not exist before anneal 0.9.8 — against 0.9.7
# the advice would name a tool the agent cannot call, which is the very defect
# (a message pointing at an unreachable path) this pair of releases exists to fix.
# `>=0.9.6` (spore-225 — the Chris release bundle): a RELEASE-GATE lockstep bump, NOT a new-API
# contract gate. The compat-manifest's `pip_floor_verdict` release-gate requires this floor ==
# `manifest.KNOWN_GOOD_ANNEAL`, so they move together or `levain doctor`'s `compat: pip-pin`
# check flags the skew.
#
# ⛔ 0.9.7 IS A CORRECTNESS FLOOR, NOT A HOUSEKEEPING BUMP (AM-LEVELCAP, 2026-08-14). Every
# anneal through 0.9.6 capped Proven-tier at 2x/3x in BOTH `_GRADUATION_RE` and
# `CrystalStore._validate_level`, so a pattern at 4x or higher was SILENTLY invisible to
# graduation validation — no validation, no demotion, no counter, and (because co-citation is
# extracted inside the graduation path) ZERO Hebbian links — while also being impossible to
# crystallize OUT. An entity whose practice counts past 3x loses its association graph with no
# error and no warning. Levain's methodology-core USED TO TEACH 1x->2x->3x-then-crystallize, so a
# seed-following entity never produced an affected line — which is exactly why this survived to
# 0.9.6 unnoticed, and why the floor moved on 2026-08-14 while the templates did not.
#
# ⚠ THAT CLAUSE IS NOW HISTORY, NOT CURRENT STATE (2026-08-31, spore-535). The seed's
# `memory.md` taught a ladder terminating at 3x for seventeen days after the library removed
# the cap, so every Levain entity was taught a practice that structurally could not reach 4x —
# SAFE (no adopter was ever broken, which is what made TEMPLATES_RECONCILED_ANNEAL = 0.9.7 an
# honest ack) but never CURRENT. The seed now teaches the uncapped ladder and the
# level-vs-recency split. Do not cite this comment as evidence that the templates still cap.
#
# levain calls no 0.9.7-only API. `MIN_PROVEN_LEVEL` is new public surface in 0.9.7 but
# levain does not import it. (Both clauses are scoped to 0.9.7 and are true as history. The
# sentence that stood here — "the floor is the published-known-good, not a runtime
# requirement" — was a generalisation over a MOVING value: "the floor" is a definite
# reference to the specifier below, and the comment at the head of this block states that
# floor IS a contract gate. Two answers in one file, the wrong one sitting last before the
# specifier. Deleted rather than re-worded.)
#
# `>=0.9.10` (2026-09-14, spore-1022): a CORRECTNESS floor, not an API gate; levain calls no
# 0.9.10-only API. Per anneal's own 0.9.10 CHANGELOG, both defects reproduced on tag v0.9.9:
# `verify()` returned `valid=True` with no entries once the sealed file its manifest names and
# the active file were deleted (total audit loss read as a clean empty trail), and
# `anneal-memory audit` could omit a whole sealed week while reporting `anchor_trusted: true`.
# A levain install must not resolve to the anneal that reads a destroyed history as healthy.
"anneal-memory>=0.9.10,<0.10",
]
[project.optional-dependencies]
# The MCP-App in-host dashboard server (`levain serve-app`). Optional so the
# core install + `levain dashboard` CLI stay lean; only pulled when an operator
# wants the in-host render. The UI loads its client lib from a CDN — no Node.
app = ["mcp>=1.27,<2"]
# The OpenHands firing + presence adapter (`levain.firing.openhands`) — the runnable-entity
# executor. Self-contained after the vagus→Levain fold-in: the firing contract + AnnealFiring +
# the OpenHands condensers now live in `levain.firing`, so this extra needs ONLY openhands-sdk (+
# the base `anneal-memory` dep for the real recall/capture). NO vagus dependency. The
# harness-neutral seam `levain.firing` imports NO OpenHands, so a plain `pip install levain` never
# pulls any of this (the leaf stays isolated; the adapter loads only on `import levain.firing.openhands`).
openhands = ["openhands-sdk==1.26.0", "openhands-tools==1.26.0"]
dev = ["pytest>=7.4", "mcp>=1.27,<2"]
[project.scripts]
levain = "levain.cli:main"
[project.urls]
Homepage = "https://levainhq.com"
Repository = "https://github.com/levainhq/levain"
[tool.setuptools.packages.find]
where = ["."]
include = ["levain*"]
[tool.setuptools.package-data]
levain = ["templates/**/*"]
# Never ship compiled bytecode in the wheel: the `templates/**/*` glob above would
# otherwise pull in any `__pycache__/*.pyc` left in the working tree (cross-version
# bytecode, e.g. cpython-314, to every adopter regardless of their interpreter).
# `levain init` already strips these on copy, but the artifact itself must be clean.
# Scoped GLOBALLY (not just under templates/) so a `__pycache__` at the package root
# or in any subpackage can't leak into the wheel either — the sdist's MANIFEST.in
# `global-exclude` covers the same, keeping wheel and sdist symmetric (L3 MED-3).
[tool.setuptools.exclude-package-data]
levain = ["**/__pycache__/*", "**/*.pyc", "**/*.pyo"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra --strict-markers"