fireweed-mcp 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.
Files changed (48) hide show
  1. fireweed_mcp-0.1.0/.github/workflows/publish.yml +67 -0
  2. fireweed_mcp-0.1.0/.gitignore +7 -0
  3. fireweed_mcp-0.1.0/LICENSE.md +105 -0
  4. fireweed_mcp-0.1.0/PKG-INFO +222 -0
  5. fireweed_mcp-0.1.0/README.md +99 -0
  6. fireweed_mcp-0.1.0/open_format/SPEC.md +114 -0
  7. fireweed_mcp-0.1.0/open_format/conformance.py +159 -0
  8. fireweed_mcp-0.1.0/open_format/reference_reader.py +168 -0
  9. fireweed_mcp-0.1.0/open_format/verify_bundle.py +110 -0
  10. fireweed_mcp-0.1.0/pyproject.toml +39 -0
  11. fireweed_mcp-0.1.0/src/fireweed/__init__.py +16 -0
  12. fireweed_mcp-0.1.0/src/fireweed/claim.py +47 -0
  13. fireweed_mcp-0.1.0/src/fireweed/consolidation_ops.py +460 -0
  14. fireweed_mcp-0.1.0/src/fireweed/consolidator.py +284 -0
  15. fireweed_mcp-0.1.0/src/fireweed/constants.py +261 -0
  16. fireweed_mcp-0.1.0/src/fireweed/constitutional.py +68 -0
  17. fireweed_mcp-0.1.0/src/fireweed/coreference.py +60 -0
  18. fireweed_mcp-0.1.0/src/fireweed/crypto.py +166 -0
  19. fireweed_mcp-0.1.0/src/fireweed/decay.py +215 -0
  20. fireweed_mcp-0.1.0/src/fireweed/domain_classifier.py +104 -0
  21. fireweed_mcp-0.1.0/src/fireweed/entity_linker.py +390 -0
  22. fireweed_mcp-0.1.0/src/fireweed/erasure.py +274 -0
  23. fireweed_mcp-0.1.0/src/fireweed/extractor.py +139 -0
  24. fireweed_mcp-0.1.0/src/fireweed/fabric.py +292 -0
  25. fireweed_mcp-0.1.0/src/fireweed/field_edges.py +177 -0
  26. fireweed_mcp-0.1.0/src/fireweed/firewall.py +115 -0
  27. fireweed_mcp-0.1.0/src/fireweed/graph.py +562 -0
  28. fireweed_mcp-0.1.0/src/fireweed/grounding.py +292 -0
  29. fireweed_mcp-0.1.0/src/fireweed/ledger.py +241 -0
  30. fireweed_mcp-0.1.0/src/fireweed/ledger_sqlite.py +134 -0
  31. fireweed_mcp-0.1.0/src/fireweed/perceiver.py +329 -0
  32. fireweed_mcp-0.1.0/src/fireweed/percept_buffer.py +258 -0
  33. fireweed_mcp-0.1.0/src/fireweed/pipeline.py +306 -0
  34. fireweed_mcp-0.1.0/src/fireweed/query_parser.py +143 -0
  35. fireweed_mcp-0.1.0/src/fireweed/read_gate.py +404 -0
  36. fireweed_mcp-0.1.0/src/fireweed/reader.py +266 -0
  37. fireweed_mcp-0.1.0/src/fireweed/receipts.py +115 -0
  38. fireweed_mcp-0.1.0/src/fireweed/reinforcement.py +73 -0
  39. fireweed_mcp-0.1.0/src/fireweed/resolver.py +600 -0
  40. fireweed_mcp-0.1.0/src/fireweed/retrieval.py +463 -0
  41. fireweed_mcp-0.1.0/src/fireweed/scoring.py +212 -0
  42. fireweed_mcp-0.1.0/src/fireweed/self_model.py +158 -0
  43. fireweed_mcp-0.1.0/src/fireweed/semantic_encoder.py +89 -0
  44. fireweed_mcp-0.1.0/src/fireweed/significance.py +254 -0
  45. fireweed_mcp-0.1.0/src/fireweed/speaker.py +36 -0
  46. fireweed_mcp-0.1.0/src/fireweed_mcp/__init__.py +2 -0
  47. fireweed_mcp-0.1.0/src/fireweed_mcp/server.py +385 -0
  48. fireweed_mcp-0.1.0/tests/test_mcp_server.py +161 -0
@@ -0,0 +1,67 @@
1
+ # Publish fireweed-mcp to PyPI via Trusted Publishing (OIDC) — no API token stored anywhere.
2
+ #
3
+ # PyPI publisher configuration this must match EXACTLY:
4
+ # PyPI Project Name : fireweed-mcp
5
+ # Owner : Starksood
6
+ # Repository name : fireweed-mcp
7
+ # Workflow name : publish.yml
8
+ # Environment name : pypi
9
+ #
10
+ # Triggered by publishing a GitHub Release, so a push to main can never ship a version by accident.
11
+ name: publish
12
+
13
+ on:
14
+ release:
15
+ types: [published]
16
+ workflow_dispatch: # manual re-run if a publish fails after the release is cut
17
+
18
+ jobs:
19
+ test:
20
+ runs-on: ubuntu-latest
21
+ strategy:
22
+ matrix:
23
+ python-version: ["3.9", "3.12"] # 3.9 is the floor the engine actually runs on
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: ${{ matrix.python-version }}
29
+ - run: pip install pytest
30
+ - run: PYTHONPATH=src python -m pytest -q tests/
31
+
32
+ build:
33
+ needs: test
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: actions/setup-python@v5
38
+ with:
39
+ python-version: "3.12"
40
+ - run: pip install build
41
+ - run: python -m build
42
+ # Fail the release rather than ship a package that installs but cannot import — the exact
43
+ # failure this project shipped once already and caught only by installing the wheel.
44
+ - name: smoke-test the built wheel in a clean venv
45
+ run: |
46
+ python -m venv /tmp/smoke
47
+ /tmp/smoke/bin/pip install dist/*.whl
48
+ /tmp/smoke/bin/python -c "import fireweed, fireweed_mcp.server as s; assert s.TOOLS; print('import-ok')"
49
+ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' \
50
+ | /tmp/smoke/bin/fireweed-mcp | grep -q '"serverInfo"' && echo "protocol-ok"
51
+ - uses: actions/upload-artifact@v4
52
+ with:
53
+ name: dist
54
+ path: dist/
55
+
56
+ publish:
57
+ needs: build
58
+ runs-on: ubuntu-latest
59
+ environment: pypi # must match the Environment name in the PyPI publisher
60
+ permissions:
61
+ id-token: write # required for Trusted Publishing; no token secret needed
62
+ steps:
63
+ - uses: actions/download-artifact@v4
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .venv/
@@ -0,0 +1,105 @@
1
+ # Functional Source License, Version 1.1, ALv2 Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-ALv2
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Sanyam Sood
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the Apache License, Version 2.0 that is effective on the second anniversary of
91
+ the date we make the Software available. On or after that date, you may use the
92
+ Software under the Apache License, Version 2.0, in which case the following
93
+ will apply:
94
+
95
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
96
+ this file except in compliance with the License.
97
+
98
+ You may obtain a copy of the License at
99
+
100
+ http://www.apache.org/licenses/LICENSE-2.0
101
+
102
+ Unless required by applicable law or agreed to in writing, software distributed
103
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
104
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
105
+ specific language governing permissions and limitations under the License.
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.5
2
+ Name: fireweed-mcp
3
+ Version: 0.1.0
4
+ Summary: Agent memory where every fact carries a receipt — a deterministic gate decides what is remembered, and erasure issues a signed certificate.
5
+ Project-URL: Homepage, https://github.com/Starksood/fireweed-mcp
6
+ Project-URL: Source, https://github.com/Starksood/fireweed-mcp
7
+ Author: Sanyam Sood
8
+ License: # Functional Source License, Version 1.1, ALv2 Future License
9
+
10
+ ## Abbreviation
11
+
12
+ FSL-1.1-ALv2
13
+
14
+ ## Notice
15
+
16
+ Copyright 2026 Sanyam Sood
17
+
18
+ ## Terms and Conditions
19
+
20
+ ### Licensor ("We")
21
+
22
+ The party offering the Software under these Terms and Conditions.
23
+
24
+ ### The Software
25
+
26
+ The "Software" is each version of the software that we make available under
27
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
28
+ Conditions with the Software.
29
+
30
+ ### License Grant
31
+
32
+ Subject to your compliance with this License Grant and the Patents,
33
+ Redistribution and Trademark clauses below, we hereby grant you the right to
34
+ use, copy, modify, create derivative works, publicly perform, publicly display
35
+ and redistribute the Software for any Permitted Purpose identified below.
36
+
37
+ ### Permitted Purpose
38
+
39
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
40
+ means making the Software available to others in a commercial product or
41
+ service that:
42
+
43
+ 1. substitutes for the Software;
44
+
45
+ 2. substitutes for any other product or service we offer using the Software
46
+ that exists as of the date we make the Software available; or
47
+
48
+ 3. offers the same or substantially similar functionality as the Software.
49
+
50
+ Permitted Purposes specifically include using the Software:
51
+
52
+ 1. for your internal use and access;
53
+
54
+ 2. for non-commercial education;
55
+
56
+ 3. for non-commercial research; and
57
+
58
+ 4. in connection with professional services that you provide to a licensee
59
+ using the Software in accordance with these Terms and Conditions.
60
+
61
+ ### Patents
62
+
63
+ To the extent your use for a Permitted Purpose would necessarily infringe our
64
+ patents, the license grant above includes a license under our patents. If you
65
+ make a claim against any party that the Software infringes or contributes to
66
+ the infringement of any patent, then your patent license to the Software ends
67
+ immediately.
68
+
69
+ ### Redistribution
70
+
71
+ The Terms and Conditions apply to all copies, modifications and derivatives of
72
+ the Software.
73
+
74
+ If you redistribute any copies, modifications or derivatives of the Software,
75
+ you must include a copy of or a link to these Terms and Conditions and not
76
+ remove any copyright notices provided in or with the Software.
77
+
78
+ ### Disclaimer
79
+
80
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
81
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
82
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
83
+
84
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
85
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
86
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
87
+
88
+ ### Trademarks
89
+
90
+ Except for displaying the License Details and identifying us as the origin of
91
+ the Software, you have no right under these Terms and Conditions to use our
92
+ trademarks, trade names, service marks or product names.
93
+
94
+ ## Grant of Future License
95
+
96
+ We hereby irrevocably grant you an additional license to use the Software under
97
+ the Apache License, Version 2.0 that is effective on the second anniversary of
98
+ the date we make the Software available. On or after that date, you may use the
99
+ Software under the Apache License, Version 2.0, in which case the following
100
+ will apply:
101
+
102
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
103
+ this file except in compliance with the License.
104
+
105
+ You may obtain a copy of the License at
106
+
107
+ http://www.apache.org/licenses/LICENSE-2.0
108
+
109
+ Unless required by applicable law or agreed to in writing, software distributed
110
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
111
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
112
+ specific language governing permissions and limitations under the License.
113
+ License-File: LICENSE.md
114
+ Keywords: agent-memory,audit,erasure,gdpr,llm,mcp,model-context-protocol,provenance
115
+ Classifier: Development Status :: 4 - Beta
116
+ Classifier: Intended Audience :: Developers
117
+ Classifier: Programming Language :: Python :: 3
118
+ Classifier: Topic :: Software Development :: Libraries
119
+ Requires-Python: >=3.9
120
+ Provides-Extra: semantic
121
+ Requires-Dist: sentence-transformers>=3.0; extra == 'semantic'
122
+ Description-Content-Type: text/markdown
123
+
124
+ # fireweed-mcp
125
+
126
+ Agent memory where every fact carries a receipt.
127
+
128
+ ```
129
+ remember(claim = "Priya joined Acme in 2019 under duress.",
130
+ evidence = "Priya Raman joined Acme in 2019 as a logistics analyst.")
131
+
132
+ REFUSED (asserts_more_than_evidence) — the claim adds something the evidence does not say.
133
+ claim : Priya joined Acme in 2019 under duress.
134
+ evidence: Priya Raman joined Acme in 2019 as a logistics analyst.
135
+ ```
136
+
137
+ ```
138
+ recall("Priya's salary")
139
+
140
+ ABSTAINED (unknown_predicate) — no claims ground "salary"; 1 claim about Priya Raman exists
141
+ This is a refusal, not an empty result.
142
+ ```
143
+
144
+ ```
145
+ forget("Priya")
146
+
147
+ ERASED Priya Raman — certificate issued
148
+ signature : hmac-sha256:f4d0768ef3b0fec624afec12f25bfd91…
149
+ nodes in closure : 1
150
+ every probe abstains : True
151
+ bystanders surviving : 1
152
+ ```
153
+
154
+ That last one is the artifact behind *"delete me from your agent's memory — and prove it."*
155
+
156
+ ## Install
157
+
158
+ ```bash
159
+ uvx fireweed-mcp # try it
160
+ pip install fireweed-mcp # keep it
161
+ ```
162
+
163
+ ```bash
164
+ claude mcp add fireweed -- uvx fireweed-mcp
165
+ ```
166
+
167
+ No dependencies. No API keys. No model — nothing in this server calls an LLM.
168
+
169
+ ## What it does
170
+
171
+ | tool | |
172
+ |---|---|
173
+ | `remember` | admits a claim **only if the evidence you cite supports it**. Refusals are typed and say what to fix. |
174
+ | `recall` | grounded claims **with the byte range they came from**; abstains and names the term it could not ground |
175
+ | `verify_receipts` | re-hash every source, re-slice every range — **tamper-evident** |
176
+ | `forget` | erasure with exact closure and a **signed certificate**; bystanders survive |
177
+ | `export_memory` | the whole substrate as a portable open-format blob |
178
+
179
+ ## Why the refusals are the point
180
+
181
+ Most memory servers store what the model says and return what's nearest. This one **adjudicates**.
182
+
183
+ The rule is *the model proposes, deterministic code decides.* Across an RPC boundary that stops
184
+ being a slogan: **your agent is the proposer**, and it cannot talk its way past the gate, because
185
+ the gate is not a prompt. Pass a claim and the text you're quoting; pure functions check that the
186
+ evidence names the subject, preserves the relation, invents no numbers, and asserts nothing the
187
+ span doesn't say. What survives is stored with a byte range into the source.
188
+
189
+ Then anyone can check it afterwards — including someone who trusts neither your agent nor this
190
+ server. That is the whole product.
191
+
192
+ ## What it does NOT do
193
+
194
+ Stated up front, because this project's last headline number turned out to be measuring nothing
195
+ (see [the retraction](https://github.com/Starksood/Fireweed_Fabric/blob/main/RETRACTION.md), which
196
+ ships with a script that proves it):
197
+
198
+ - **It does not extract memories from free text.** You supply the claim and the evidence.
199
+ Automatic extraction needs a perceiver model; this server deliberately has none.
200
+ - **It does not make an LLM truthful.** It governs what enters the *record* and what can be proven
201
+ about it. Your model can still say whatever it likes in its own prose.
202
+ - **Conversational recall is weak, and measured.** On a 1,200-item adversarial corpus the retrieval
203
+ gate abstains on only **40%** of questions whose answer is genuinely absent — it checks that the
204
+ question's *topic* is grounded, not that the asked-for *value* exists. The write path, receipts
205
+ and erasure are unaffected and are the parts to rely on.
206
+
207
+ ## Your data
208
+
209
+ `~/.fireweed/mcp/` (`FIREWEED_MCP_STORE` to change). The substrate is an open format — see
210
+ [`open_format/SPEC.md`](open_format/SPEC.md) — and `open_format/reference_reader.py` reads it with
211
+ the standard library alone. Your memory outlives this server, this engine, and any model. A test
212
+ asserts that round trip.
213
+
214
+ Optional: `pip install "fireweed-mcp[semantic]"` enables paraphrase matching in `recall`. Without
215
+ it the gate refuses *more* — the safe direction — and `memory_stats` tells you which mode you're in.
216
+
217
+ ## License
218
+
219
+ **FSL-1.1-ALv2** — source-available. Free for everything except building a competing product;
220
+ converts to **Apache 2.0 on 2028-01-01**. Full text in [`LICENSE.md`](LICENSE.md).
221
+
222
+ Want to use Fireweed in a commercial product or competing service? → **snymsood@icloud.com**
@@ -0,0 +1,99 @@
1
+ # fireweed-mcp
2
+
3
+ Agent memory where every fact carries a receipt.
4
+
5
+ ```
6
+ remember(claim = "Priya joined Acme in 2019 under duress.",
7
+ evidence = "Priya Raman joined Acme in 2019 as a logistics analyst.")
8
+
9
+ REFUSED (asserts_more_than_evidence) — the claim adds something the evidence does not say.
10
+ claim : Priya joined Acme in 2019 under duress.
11
+ evidence: Priya Raman joined Acme in 2019 as a logistics analyst.
12
+ ```
13
+
14
+ ```
15
+ recall("Priya's salary")
16
+
17
+ ABSTAINED (unknown_predicate) — no claims ground "salary"; 1 claim about Priya Raman exists
18
+ This is a refusal, not an empty result.
19
+ ```
20
+
21
+ ```
22
+ forget("Priya")
23
+
24
+ ERASED Priya Raman — certificate issued
25
+ signature : hmac-sha256:f4d0768ef3b0fec624afec12f25bfd91…
26
+ nodes in closure : 1
27
+ every probe abstains : True
28
+ bystanders surviving : 1
29
+ ```
30
+
31
+ That last one is the artifact behind *"delete me from your agent's memory — and prove it."*
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ uvx fireweed-mcp # try it
37
+ pip install fireweed-mcp # keep it
38
+ ```
39
+
40
+ ```bash
41
+ claude mcp add fireweed -- uvx fireweed-mcp
42
+ ```
43
+
44
+ No dependencies. No API keys. No model — nothing in this server calls an LLM.
45
+
46
+ ## What it does
47
+
48
+ | tool | |
49
+ |---|---|
50
+ | `remember` | admits a claim **only if the evidence you cite supports it**. Refusals are typed and say what to fix. |
51
+ | `recall` | grounded claims **with the byte range they came from**; abstains and names the term it could not ground |
52
+ | `verify_receipts` | re-hash every source, re-slice every range — **tamper-evident** |
53
+ | `forget` | erasure with exact closure and a **signed certificate**; bystanders survive |
54
+ | `export_memory` | the whole substrate as a portable open-format blob |
55
+
56
+ ## Why the refusals are the point
57
+
58
+ Most memory servers store what the model says and return what's nearest. This one **adjudicates**.
59
+
60
+ The rule is *the model proposes, deterministic code decides.* Across an RPC boundary that stops
61
+ being a slogan: **your agent is the proposer**, and it cannot talk its way past the gate, because
62
+ the gate is not a prompt. Pass a claim and the text you're quoting; pure functions check that the
63
+ evidence names the subject, preserves the relation, invents no numbers, and asserts nothing the
64
+ span doesn't say. What survives is stored with a byte range into the source.
65
+
66
+ Then anyone can check it afterwards — including someone who trusts neither your agent nor this
67
+ server. That is the whole product.
68
+
69
+ ## What it does NOT do
70
+
71
+ Stated up front, because this project's last headline number turned out to be measuring nothing
72
+ (see [the retraction](https://github.com/Starksood/Fireweed_Fabric/blob/main/RETRACTION.md), which
73
+ ships with a script that proves it):
74
+
75
+ - **It does not extract memories from free text.** You supply the claim and the evidence.
76
+ Automatic extraction needs a perceiver model; this server deliberately has none.
77
+ - **It does not make an LLM truthful.** It governs what enters the *record* and what can be proven
78
+ about it. Your model can still say whatever it likes in its own prose.
79
+ - **Conversational recall is weak, and measured.** On a 1,200-item adversarial corpus the retrieval
80
+ gate abstains on only **40%** of questions whose answer is genuinely absent — it checks that the
81
+ question's *topic* is grounded, not that the asked-for *value* exists. The write path, receipts
82
+ and erasure are unaffected and are the parts to rely on.
83
+
84
+ ## Your data
85
+
86
+ `~/.fireweed/mcp/` (`FIREWEED_MCP_STORE` to change). The substrate is an open format — see
87
+ [`open_format/SPEC.md`](open_format/SPEC.md) — and `open_format/reference_reader.py` reads it with
88
+ the standard library alone. Your memory outlives this server, this engine, and any model. A test
89
+ asserts that round trip.
90
+
91
+ Optional: `pip install "fireweed-mcp[semantic]"` enables paraphrase matching in `recall`. Without
92
+ it the gate refuses *more* — the safe direction — and `memory_stats` tells you which mode you're in.
93
+
94
+ ## License
95
+
96
+ **FSL-1.1-ALv2** — source-available. Free for everything except building a competing product;
97
+ converts to **Apache 2.0 on 2028-01-01**. Full text in [`LICENSE.md`](LICENSE.md).
98
+
99
+ Want to use Fireweed in a commercial product or competing service? → **snymsood@icloud.com**
@@ -0,0 +1,114 @@
1
+ # The Fireweed Memory Protocol (FMP) — normalization spec v1
2
+
3
+ **Status:** the open half of the open-core boundary. This document, `reference_reader.py`,
4
+ `conformance.py` and the trap corpus are permanently open; the engine that DECIDES what enters a
5
+ substrate is not. The split is exact: **everything that describes is here, everything that
6
+ adjudicates is private.**
7
+
8
+ **Why it exists:** weights obsolesce in a decade. A record that can only be read by the vendor that
9
+ wrote it is not a record, it is a rental. An FMP snapshot must stay readable with nothing but a JSON
10
+ parser and this document — which is why the reference reader imports only the standard library, and
11
+ why that constraint is a conformance check rather than a preference.
12
+
13
+ ---
14
+
15
+ ## 1. Container
16
+
17
+ A snapshot is one UTF-8 JSON object. Top level:
18
+
19
+ | field | type | meaning |
20
+ |---|---|---|
21
+ | `snapshot_version` | int | format version. **2** is current. A reader MUST refuse a version it does not know. |
22
+ | `fireweed_version` | string | the writer's engine version. Informational; never load-bearing. |
23
+ | `nodes` | array | the claims. §2 |
24
+ | `entities` | array | the things claims are about. §3 |
25
+ | `relations` | array | typed edges. §4 |
26
+ | `sessions_seen`, `total_sessions`, `seen_domains`, `session_timestamp`, `session_anchor`, `ingested_session_ids` | — | writer bookkeeping. A reader MAY ignore all of it. |
27
+
28
+ **Refusing is mandatory, not optional.** A reader that silently reads an unknown version is how a
29
+ format rots: it will misinterpret fields that changed meaning and report the result as fact.
30
+
31
+ ## 2. Nodes (claims)
32
+
33
+ Required: `node_id` (unique), `claim`. Load-bearing optional fields:
34
+
35
+ | field | meaning |
36
+ |---|---|
37
+ | `normalized_claim` | canonical form used for matching. Derived; never authoritative over `claim`. |
38
+ | `node_type` | `fact` \| `event` \| `state` \| `preference` \| `constraint` \| `inference` \| `reflection` \| `summary` |
39
+ | `status.memory_state` | `active` \| `disputed` \| `superseded` \| `quarantined` \| `frozen` |
40
+ | `entities[].entity_id` | references §3 |
41
+ | `domains` | topical tags, unordered |
42
+ | `provenance` | §5 |
43
+
44
+ **The memory-state contract.**
45
+
46
+ - `active` and `disputed` are both READABLE. A `disputed` node is held in standing contradiction,
47
+ not retired: both sides of an unresolved conflict stay answerable, because silently picking a
48
+ winner is a decision the format must not make on the reader's behalf.
49
+ - `superseded` nodes are **retained in the file, never deleted.** A reader can always reconstruct
50
+ what was once believed and when it stopped being believed. Belief revision is part of the record.
51
+ - Erasure is the one exception: erased content is genuinely gone, replaced by a tombstone. That is a
52
+ deliberate asymmetry — supersession is history, erasure is a promise.
53
+
54
+ ## 3. Entities
55
+
56
+ `entity_id` (unique), `canonical_name`, `entity_type`
57
+ (`person` \| `place` \| `organization` \| `object` \| `concept` \| `event`), `aliases`.
58
+
59
+ > **Known defect, stated rather than hidden:** writers at time of writing emit `person` for nearly
60
+ > every entity, including organizations and objects. `entity_type` is therefore NOT yet trustworthy
61
+ > and a reader must not build behaviour on it. Tracked in `docs/DESIGN_read_gate.md` §5, where it is
62
+ > the blocker for object typing.
63
+
64
+ ## 4. Relations
65
+
66
+ `relation_id`, `relation_type`, `source_id`, `target_id`.
67
+
68
+ **The list is heterogeneous, and the endpoint domain depends on the type.** This is the one place a
69
+ naive reader will get it wrong — the first run of the conformance suite reported four "dangling"
70
+ relations that were simply entity edges:
71
+
72
+ | relation_type | `source_id` / `target_id` refer to |
73
+ |---|---|
74
+ | `supersedes`, `contradicts`, `supports`, `derived_from`, `causes`, `motivates`, `before` | **node** ids |
75
+ | `co_occurs` | **entity** ids |
76
+
77
+ A reader MUST resolve endpoints in the domain the type declares.
78
+
79
+ ## 5. Provenance and receipts
80
+
81
+ | field | meaning |
82
+ |---|---|
83
+ | `source_turn_id` | the turn or document-derived id the claim came from |
84
+ | `source_span` | the **verbatim** evidence the claim was admitted on |
85
+ | `confidence` | the proposer's confidence. Never a gate; informational only. |
86
+ | `grounding_class` | `grounded_verbatim` (subject named in the cited span) or `grounded_resolved` (subject resolved from outside it) |
87
+ | `doc_hash`, `byte_start`, `byte_end` | the receipt coordinate, when the claim is document-bound |
88
+
89
+ **A receipt exists only when `doc_hash`, `byte_start` and `byte_end` are ALL present.** A partial
90
+ coordinate is not a weak receipt — it is no receipt. Reporting one would be exactly the fabrication
91
+ the format exists to prevent, and the conformance suite checks it.
92
+
93
+ **Verification** is two steps, and both must pass:
94
+
95
+ 1. `"sha256:" + sha256(document)` equals `doc_hash`
96
+ 2. `document[byte_start:byte_end]` decodes to `source_span`
97
+
98
+ Change any byte of the source and one of the two fails. That is the whole provenance guarantee, and
99
+ it is checkable by anyone holding the document — no engine, no network, no trust.
100
+
101
+ ## 6. Conformance
102
+
103
+ python open_format/conformance.py <snapshot.json>
104
+
105
+ 20 checks. It does not trust the reference reader: it states properties of the FORMAT and runs them
106
+ against whatever reader it is handed, so passing with your own implementation means yours conforms.
107
+ Three of the checks assert the reader REFUSES malformed input, and two assert receipts FAIL on a
108
+ tampered source — a suite that can only pass is not evidence.
109
+
110
+ ## 7. Stability
111
+
112
+ Within a major version: fields may be ADDED; existing field meanings never change. A reader must
113
+ ignore fields it does not recognise. Removing or repurposing a field requires a version bump, which
114
+ existing readers are required to refuse.