@333eco/corpus 2.3.5 → 2.4.1
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 +74 -17
- package/dist/corpus.json +1326 -147
- package/package.json +1 -1
- package/src/base-tools.mjs +10 -6
- package/src/envelope.mjs +64 -0
- package/src/read-tools.mjs +228 -0
- package/src/resources.mjs +16 -3
- package/src/search.mjs +92 -7
- package/src/server.mjs +41 -97
package/README.md
CHANGED
|
@@ -60,6 +60,12 @@ manufactured on a schedule.
|
|
|
60
60
|
| Tool | Returns |
|
|
61
61
|
| --- | --- |
|
|
62
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 |
|
|
63
69
|
|
|
64
70
|
⭐ **`search_corpus` matches the phrase first, then all terms.** An exact substring hit
|
|
65
71
|
always wins and ranks above everything else — which keeps `B-Heart` and `Re-Tip` precise,
|
|
@@ -76,11 +82,62 @@ verbatim. **A zero result was recording the matcher's limits while being read as
|
|
|
76
82
|
|
|
77
83
|
⭐ On a zero result the response now names **which terms appear in no document at all**
|
|
78
84
|
(`absent_terms`), so a dead end says something instead of nothing.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
|
|
86
|
+
⭐ **Diacritics are optional.** `metta` finds what `mettā` finds, and `Tonle Sap` reaches the
|
|
87
|
+
text that writes `Tonlé Sap` — before 2.4.1 a plain-ASCII query found 6 documents where the
|
|
88
|
+
marked one found 20. ⛔ **Fold to match, serve verbatim:** the fold touches only what is
|
|
89
|
+
compared, and every excerpt carries the corpus's own spelling, because a Pāli or Sanskrit
|
|
90
|
+
spelling is a tradition marker rather than a typo. Only Latin combining diacritics are folded;
|
|
91
|
+
Khmer and Burmese vowel signs are marks too, and are left exactly as written.
|
|
92
|
+
|
|
93
|
+
⭐ **Every result says it is an excerpt.** The text ends with a line naming how many of the
|
|
94
|
+
matches it shows and the `read_documents` call that reads those documents in full. It sits in
|
|
95
|
+
the result rather than only in the server's instructions, because a result reaches the model in
|
|
96
|
+
every client, at the moment it decides whether to keep reading.
|
|
97
|
+
|
|
98
|
+
### Reading a whole shelf
|
|
99
|
+
|
|
100
|
+
⭐ **Search answers from excerpts, and a model answers from what it opened.** A frontier
|
|
101
|
+
model connected to this server gave answers that were accurate but incomplete: it searched,
|
|
102
|
+
opened a few documents and stopped. The fix is not a bigger context window — a shelf of this
|
|
103
|
+
corpus already fits one — but a way to read the shelf.
|
|
104
|
+
|
|
105
|
+
- **`list_documents` reports `bytes` and `words`** per document and `total_bytes` /
|
|
106
|
+
`total_words` for the filtered set, so a caller can see whether a slice fits before reading
|
|
107
|
+
it. ⛔ **Never tokens:** a token count is true for one tokenizer and wrong for every other
|
|
108
|
+
model family; bytes and words are checkable.
|
|
109
|
+
- **`read_documents`** takes the same filters as `list_documents` — or `slugs` — and returns
|
|
110
|
+
every matching document in full, **one content block per document**, each behind its
|
|
111
|
+
provenance header, so each still verifies on its own. ⛔ Never a concatenation and never a
|
|
112
|
+
summary.
|
|
113
|
+
- **Paged by size.** `max_bytes` defaults to 90,000 (under the 25,000-token point at which
|
|
114
|
+
Claude Code moves a tool result into a file) and may go to 400,000. **A document is never
|
|
115
|
+
split** — half a document verifies nothing — so one larger than the page arrives alone and
|
|
116
|
+
says `over_budget`. Follow `next_cursor`; a cursor from a different corpus version is refused
|
|
117
|
+
rather than serving page 2 of another corpus.
|
|
118
|
+
- **`list_documents` says how to read what it listed:** `read_with` carries the same filters as
|
|
119
|
+
`read_documents` arguments.
|
|
120
|
+
|
|
121
|
+
⚠️ **The server can point; it cannot make a model read.** Its instructions say *for a broad
|
|
122
|
+
question, read the relevant shelf in full* — deliberately conditional, because a whole shelf read
|
|
123
|
+
to answer a one-fact question is slower, costlier and often worse. Clients differ in whether they
|
|
124
|
+
show server instructions at all, which is why the pointers also live in the results.
|
|
125
|
+
|
|
126
|
+
⭐ **Every document ends with an `[END OF DOCUMENT — <slug> · <n> words]` line**, by every
|
|
127
|
+
route. The server never cuts a document, but a client may, and a cut document reads as a
|
|
128
|
+
complete one. The end is stated in the text, where a cut removes it — not in a field that would
|
|
129
|
+
survive the cut and assert a completeness the text no longer has.
|
|
130
|
+
|
|
131
|
+
### Nothing silently missing
|
|
132
|
+
|
|
133
|
+
The envelope proves each served document authentic; nothing used to prove that none was
|
|
134
|
+
**dropped**. The build now writes a **manifest** — every file it considered, and what became of
|
|
135
|
+
it — and refuses to finish unless `candidates = served + excluded + held`. Both surfaces refuse
|
|
136
|
+
to serve a corpus whose documents do not match its manifest, and two files claiming one slug
|
|
137
|
+
fail the build rather than leaving one listed and unreadable. The counts, and the reason for
|
|
138
|
+
every exclusion or hold, arrive in `list_documents` under `completeness`; the full manifest is at
|
|
139
|
+
`https://corpus.333.eco/manifest.json`. ⚠️ **It detects omission, not tampering** — each
|
|
140
|
+
document's sha256 is the other half.
|
|
84
141
|
|
|
85
142
|
⭐ **The three program tools return the STATING PAPER's envelope, not the register's.**
|
|
86
143
|
That is the register's own instruction rather than a design flourish: *"verify the
|
|
@@ -92,7 +149,7 @@ and the build refuses to emit one that is not — a field must match a *complete
|
|
|
92
149
|
cell of its source, because a fragment of a cell is still a substring of it.
|
|
93
150
|
|
|
94
151
|
The program tools appear only when the index carries a program block. An index
|
|
95
|
-
built over a corpus without one advertises
|
|
152
|
+
built over a corpus without one advertises four tools, not seven.
|
|
96
153
|
|
|
97
154
|
## Resources
|
|
98
155
|
|
|
@@ -106,7 +163,8 @@ resource is consumed differently: clients hand its contents straight to a model
|
|
|
106
163
|
context, and a `mimeType` field does not travel with a quotation. So every read
|
|
107
164
|
returns a `[PROVENANCE — corpus.333.eco]` header — licence and whom to attribute,
|
|
108
165
|
sha256 and **what it does not cover**, both DOIs, the OpenTimestamps command, and
|
|
109
|
-
the one-line `curl … | shasum` check — followed by the document verbatim
|
|
166
|
+
the one-line `curl … | shasum` check — followed by the document verbatim and its
|
|
167
|
+
`[END OF DOCUMENT]` line.
|
|
110
168
|
|
|
111
169
|
This is the letters' rule applied a second time. Voice in the letters is marked
|
|
112
170
|
inline rather than in metadata because *with a field an agent must LOOK to know;
|
|
@@ -132,13 +190,11 @@ actively strip.
|
|
|
132
190
|
|
|
133
191
|
## Attribution is a build-time property
|
|
134
192
|
|
|
135
|
-
|
|
193
|
+
Most documents are CC0 and the rest CC-BY (counted in the licence table below). A CC-BY document that names no author
|
|
136
194
|
hands every consumer an obligation nobody can discharge, so **the build fails**
|
|
137
195
|
rather than serving it — the same reasoning as the licence gate: a property, not a
|
|
138
196
|
rule someone has to remember.
|
|
139
197
|
|
|
140
|
-
| `list_predictions` | the research program's pre-registered predictions, with falsifiers and status |
|
|
141
|
-
|
|
142
198
|
**Results are structured.** Every tool returns `structuredContent` — the typed
|
|
143
199
|
object — and uses `content` for the human form: the document text with its
|
|
144
200
|
provenance header for `get_document`, readable excerpts for `search_corpus`, a
|
|
@@ -170,11 +226,11 @@ only if its own source declares a licence this corpus publishes under. There is
|
|
|
170
226
|
no glob and no directory allowlist, because the source repositories are **not**
|
|
171
227
|
uniformly licensed and never were:
|
|
172
228
|
|
|
173
|
-
- `TH/publications` —
|
|
229
|
+
- `TH/publications` — CC0, plus the **CC-BY author-voice essays**
|
|
174
230
|
- `TH/film` — rights-reserved, a separate repository *by licence*. Never served.
|
|
175
231
|
- `333.eco` — the namespace policy is commercial and explicitly unpublished.
|
|
176
232
|
|
|
177
|
-
A glob would have relicensed
|
|
233
|
+
A glob would have relicensed the author-voice essays by publication. A file with **no**
|
|
178
234
|
declaration is excluded and reported, never assumed CC0 — the default-open
|
|
179
235
|
failure is the one nobody can undo after somebody builds on it.
|
|
180
236
|
|
|
@@ -277,6 +333,7 @@ per isolate and memoises it.
|
|
|
277
333
|
Transport is **Streamable HTTP**, not the superseded HTTP+SSE pair. The server is
|
|
278
334
|
stateless and read-only, so it never opens a stream: `POST /mcp` for JSON-RPC,
|
|
279
335
|
`GET /mcp` returns 405 rather than holding open a stream that would carry nothing.
|
|
336
|
+
`GET /manifest.json` returns the served corpus's manifest.
|
|
280
337
|
|
|
281
338
|
```sh
|
|
282
339
|
cd worker
|
|
@@ -366,11 +423,11 @@ because there is no enforcer.
|
|
|
366
423
|
|
|
367
424
|
⛔ **Not one beacon per tool call.** An agent working through the corpus fires
|
|
368
425
|
dozens of calls in seconds, and a notification channel that reports each of them
|
|
369
|
-
is a channel nobody reads. The beacon fires on the *handshake*,
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
and silence is the wrong default for an outage.
|
|
426
|
+
is a channel nobody reads. The beacon fires on the *handshake*, once per
|
|
427
|
+
connection. What the receiving function does with it is its own setting: since
|
|
428
|
+
2026-09-09 it pushes one notification per handshake, and a flag restores
|
|
429
|
+
*first sighting of a client label only*. `corpus_error` always pushes: it is rare by
|
|
430
|
+
construction, and silence is the wrong default for an outage.
|
|
374
431
|
|
|
375
432
|
⚠️ **A dead beacon must not look like a quiet one.** If the receiving allowlist
|
|
376
433
|
changes, the POST 403s and the pushes simply stop — indistinguishable from *no new
|