@333eco/corpus 2.3.4 → 2.4.0
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.
- package/README.md +61 -17
- package/dist/corpus.json +1618 -293
- package/package.json +1 -1
- package/src/base-tools.mjs +7 -3
- package/src/envelope.mjs +64 -0
- package/src/read-tools.mjs +210 -0
- package/src/resources.mjs +16 -3
- package/src/server.mjs +35 -67
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ So the check moves into the response:
|
|
|
33
33
|
"doi": "10.5281/zenodo.22217516",
|
|
34
34
|
"opentimestamps": true,
|
|
35
35
|
"deposited_matches_current": true,
|
|
36
|
+
"hostile_review": null,
|
|
36
37
|
"verify": {
|
|
37
38
|
"sha256": "printf '%s' \"$(cat <file>)\" | shasum -a 256 # compare to provenance.sha256",
|
|
38
39
|
"doi": "https://doi.org/10.5281/zenodo.22217516",
|
|
@@ -44,6 +45,11 @@ So the check moves into the response:
|
|
|
44
45
|
The `verify` block is an instruction, not a promise — it tells you exactly what
|
|
45
46
|
to run, so you do not have to trust this sentence either.
|
|
46
47
|
|
|
48
|
+
`hostile_review` is the date of the latest ruled review by an outside reader chosen as
|
|
49
|
+
the one most likely to find the document wrong, whose section structure still matches
|
|
50
|
+
the text served — or `null`, stated rather than omitted. It is derived from the corpus's
|
|
51
|
+
public `reviews.json` (roles only, never names), and a structural revision resets it.
|
|
52
|
+
|
|
47
53
|
⭐ **The demonstration is the contribution.** Anyone can propose provenance-carrying
|
|
48
54
|
retrieval. Serving it over a corpus where the anchors are already years deep in
|
|
49
55
|
the Bitcoin blockchain is a different claim, and it is not one that can be
|
|
@@ -54,6 +60,12 @@ manufactured on a schedule.
|
|
|
54
60
|
| Tool | Returns |
|
|
55
61
|
| --- | --- |
|
|
56
62
|
| `search_corpus` | matching documents, provenance envelope, and an excerpt around each match |
|
|
63
|
+
| `get_document` | one document in full — canonical text, never a summary |
|
|
64
|
+
| `read_documents` | whole documents — a shelf (the `list_documents` filters) or a list of slugs — one content block each, paged by size |
|
|
65
|
+
| `list_documents` | slugs, titles, genres, licences, provenance summaries, **sizes**, and the manifest's completeness counts |
|
|
66
|
+
| `list_predictions` | the research program's pre-registered predictions, with falsifiers and status |
|
|
67
|
+
| `get_prediction` | one prediction, plus the provenance envelope of the paper that registered it |
|
|
68
|
+
| `get_program` | the program's hard core, chapters, stopping rule and count reconciliation, verbatim |
|
|
57
69
|
|
|
58
70
|
⭐ **`search_corpus` matches the phrase first, then all terms.** An exact substring hit
|
|
59
71
|
always wins and ranks above everything else — which keeps `B-Heart` and `Re-Tip` precise,
|
|
@@ -70,11 +82,43 @@ verbatim. **A zero result was recording the matcher's limits while being read as
|
|
|
70
82
|
|
|
71
83
|
⭐ On a zero result the response now names **which terms appear in no document at all**
|
|
72
84
|
(`absent_terms`), so a dead end says something instead of nothing.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
|
|
86
|
+
### Reading a whole shelf
|
|
87
|
+
|
|
88
|
+
⭐ **Search answers from excerpts, and a model answers from what it opened.** A frontier
|
|
89
|
+
model connected to this server gave answers that were accurate but incomplete: it searched,
|
|
90
|
+
opened a few documents and stopped. The fix is not a bigger context window — a shelf of this
|
|
91
|
+
corpus already fits one — but a way to read the shelf.
|
|
92
|
+
|
|
93
|
+
- **`list_documents` reports `bytes` and `words`** per document and `total_bytes` /
|
|
94
|
+
`total_words` for the filtered set, so a caller can see whether a slice fits before reading
|
|
95
|
+
it. ⛔ **Never tokens:** a token count is true for one tokenizer and wrong for every other
|
|
96
|
+
model family; bytes and words are checkable.
|
|
97
|
+
- **`read_documents`** takes the same filters as `list_documents` — or `slugs` — and returns
|
|
98
|
+
every matching document in full, **one content block per document**, each behind its
|
|
99
|
+
provenance header, so each still verifies on its own. ⛔ Never a concatenation and never a
|
|
100
|
+
summary.
|
|
101
|
+
- **Paged by size.** `max_bytes` defaults to 90,000 (under the 25,000-token point at which
|
|
102
|
+
Claude Code moves a tool result into a file) and may go to 400,000. **A document is never
|
|
103
|
+
split** — half a document verifies nothing — so one larger than the page arrives alone and
|
|
104
|
+
says `over_budget`. Follow `next_cursor`; a cursor from a different corpus version is refused
|
|
105
|
+
rather than serving page 2 of another corpus.
|
|
106
|
+
|
|
107
|
+
⭐ **Every document ends with an `[END OF DOCUMENT — <slug> · <n> words]` line**, by every
|
|
108
|
+
route. The server never cuts a document, but a client may, and a cut document reads as a
|
|
109
|
+
complete one. The end is stated in the text, where a cut removes it — not in a field that would
|
|
110
|
+
survive the cut and assert a completeness the text no longer has.
|
|
111
|
+
|
|
112
|
+
### Nothing silently missing
|
|
113
|
+
|
|
114
|
+
The envelope proves each served document authentic; nothing used to prove that none was
|
|
115
|
+
**dropped**. The build now writes a **manifest** — every file it considered, and what became of
|
|
116
|
+
it — and refuses to finish unless `candidates = served + excluded + held`. Both surfaces refuse
|
|
117
|
+
to serve a corpus whose documents do not match its manifest, and two files claiming one slug
|
|
118
|
+
fail the build rather than leaving one listed and unreadable. The counts, and the reason for
|
|
119
|
+
every exclusion or hold, arrive in `list_documents` under `completeness`; the full manifest is at
|
|
120
|
+
`https://corpus.333.eco/manifest.json`. ⚠️ **It detects omission, not tampering** — each
|
|
121
|
+
document's sha256 is the other half.
|
|
78
122
|
|
|
79
123
|
⭐ **The three program tools return the STATING PAPER's envelope, not the register's.**
|
|
80
124
|
That is the register's own instruction rather than a design flourish: *"verify the
|
|
@@ -86,7 +130,7 @@ and the build refuses to emit one that is not — a field must match a *complete
|
|
|
86
130
|
cell of its source, because a fragment of a cell is still a substring of it.
|
|
87
131
|
|
|
88
132
|
The program tools appear only when the index carries a program block. An index
|
|
89
|
-
built over a corpus without one advertises
|
|
133
|
+
built over a corpus without one advertises four tools, not seven.
|
|
90
134
|
|
|
91
135
|
## Resources
|
|
92
136
|
|
|
@@ -100,7 +144,8 @@ resource is consumed differently: clients hand its contents straight to a model
|
|
|
100
144
|
context, and a `mimeType` field does not travel with a quotation. So every read
|
|
101
145
|
returns a `[PROVENANCE — corpus.333.eco]` header — licence and whom to attribute,
|
|
102
146
|
sha256 and **what it does not cover**, both DOIs, the OpenTimestamps command, and
|
|
103
|
-
the one-line `curl … | shasum` check — followed by the document verbatim
|
|
147
|
+
the one-line `curl … | shasum` check — followed by the document verbatim and its
|
|
148
|
+
`[END OF DOCUMENT]` line.
|
|
104
149
|
|
|
105
150
|
This is the letters' rule applied a second time. Voice in the letters is marked
|
|
106
151
|
inline rather than in metadata because *with a field an agent must LOOK to know;
|
|
@@ -126,13 +171,11 @@ actively strip.
|
|
|
126
171
|
|
|
127
172
|
## Attribution is a build-time property
|
|
128
173
|
|
|
129
|
-
|
|
174
|
+
Most documents are CC0 and the rest CC-BY (counted in the licence table below). A CC-BY document that names no author
|
|
130
175
|
hands every consumer an obligation nobody can discharge, so **the build fails**
|
|
131
176
|
rather than serving it — the same reasoning as the licence gate: a property, not a
|
|
132
177
|
rule someone has to remember.
|
|
133
178
|
|
|
134
|
-
| `list_predictions` | the research program's pre-registered predictions, with falsifiers and status |
|
|
135
|
-
|
|
136
179
|
**Results are structured.** Every tool returns `structuredContent` — the typed
|
|
137
180
|
object — and uses `content` for the human form: the document text with its
|
|
138
181
|
provenance header for `get_document`, readable excerpts for `search_corpus`, a
|
|
@@ -164,11 +207,11 @@ only if its own source declares a licence this corpus publishes under. There is
|
|
|
164
207
|
no glob and no directory allowlist, because the source repositories are **not**
|
|
165
208
|
uniformly licensed and never were:
|
|
166
209
|
|
|
167
|
-
- `TH/publications` —
|
|
210
|
+
- `TH/publications` — CC0, plus the **CC-BY author-voice essays**
|
|
168
211
|
- `TH/film` — rights-reserved, a separate repository *by licence*. Never served.
|
|
169
212
|
- `333.eco` — the namespace policy is commercial and explicitly unpublished.
|
|
170
213
|
|
|
171
|
-
A glob would have relicensed
|
|
214
|
+
A glob would have relicensed the author-voice essays by publication. A file with **no**
|
|
172
215
|
declaration is excluded and reported, never assumed CC0 — the default-open
|
|
173
216
|
failure is the one nobody can undo after somebody builds on it.
|
|
174
217
|
|
|
@@ -271,6 +314,7 @@ per isolate and memoises it.
|
|
|
271
314
|
Transport is **Streamable HTTP**, not the superseded HTTP+SSE pair. The server is
|
|
272
315
|
stateless and read-only, so it never opens a stream: `POST /mcp` for JSON-RPC,
|
|
273
316
|
`GET /mcp` returns 405 rather than holding open a stream that would carry nothing.
|
|
317
|
+
`GET /manifest.json` returns the served corpus's manifest.
|
|
274
318
|
|
|
275
319
|
```sh
|
|
276
320
|
cd worker
|
|
@@ -360,11 +404,11 @@ because there is no enforcer.
|
|
|
360
404
|
|
|
361
405
|
⛔ **Not one beacon per tool call.** An agent working through the corpus fires
|
|
362
406
|
dozens of calls in seconds, and a notification channel that reports each of them
|
|
363
|
-
is a channel nobody reads. The beacon fires on the *handshake*,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
and silence is the wrong default for an outage.
|
|
407
|
+
is a channel nobody reads. The beacon fires on the *handshake*, once per
|
|
408
|
+
connection. What the receiving function does with it is its own setting: since
|
|
409
|
+
2026-09-09 it pushes one notification per handshake, and a flag restores
|
|
410
|
+
*first sighting of a client label only*. `corpus_error` always pushes: it is rare by
|
|
411
|
+
construction, and silence is the wrong default for an outage.
|
|
368
412
|
|
|
369
413
|
⚠️ **A dead beacon must not look like a quiet one.** If the receiving allowlist
|
|
370
414
|
changes, the POST 403s and the pushes simply stop — indistinguishable from *no new
|