viafrei 1.3.15 → 1.3.16

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/CHANGELOG.md CHANGED
@@ -3,6 +3,380 @@
3
3
  All notable changes to this package are documented here. The format follows Keep
4
4
  a Changelog and the versions follow Semantic Versioning.
5
5
 
6
+ ## [Unreleased]
7
+
8
+ Nothing yet.
9
+
10
+ ## [1.3.16] - 2026-09-27
11
+
12
+ **This is the release that delivers the licence corrections to the people the
13
+ licences point at.** `NOTICE` is the file Apache-2.0 § 4(d) makes every downstream
14
+ redistributor carry, and until this publish the corrected text existed only in the
15
+ repository: the 1.3.15 tarball on the registry still carries the previous wording. So
16
+ publishing is not a side effect of the correction, it **is** the correction — which
17
+ is the whole reason this release exists, because nothing in `dist/` changes.
18
+
19
+ The number matches the running service rather than counting the changes here.
20
+ Production answered `initialize` with `1.3.16` when it was asked on 2026-09-27, and
21
+ this package is the bridge to that server, so somebody comparing the two now reads
22
+ one number instead of wondering which is behind.
23
+
24
+ **No behaviour changes.** `dist/` is built rather than committed, and no file under
25
+ `src/` has changed since the 1.3.15 tag — which is the evidence for the claim, since
26
+ a diff of an untracked directory would be no evidence at all. So no flag, default or
27
+ exit code moves. **Six** of the seven `files` entries do change —
28
+ `README.md`, `LICENSE`, `NOTICE`, `SOURCES.md`, `CHANGELOG.md` and the new
29
+ `API.md` — and the tarball goes from twenty paths to twenty-one. (Six *entries*,
30
+ not six files: `dist` is a directory.)
31
+
32
+ This paragraph has now been wrong twice, which is worth leaving on the record
33
+ rather than tidying away. The first draft called these "the repository's own
34
+ development scripts" and said the next tarball would differ in two files — true of
35
+ the first change here, false once the licence work landed beside it. The second
36
+ draft said **four** files and omitted `LICENSE` — and the commit that wrote that
37
+ sentence is the same commit that changed `LICENSE`, so it was false at the moment
38
+ it was written, in the paragraph written to correct a false count. The count moved
39
+ once more at the cut, because `API.md` joined `files` in this release. Every
40
+ version of it has been computed from `package.json`'s `files` intersected with
41
+ `git diff --name-only v1.3.15..HEAD`, with the path count from `npm pack --json`,
42
+ rather than counted by eye — which is the only way this sentence has ever been
43
+ right.
44
+
45
+ ### Added
46
+
47
+ - **A sweep that keeps the twenty-first call site from being written by accident**
48
+ (`scripts/tools.test.mjs`, `npm run test:tools`, and a step in CI). Eighteen
49
+ cases: what `resolveTool` accepts and refuses, that its directory list is
50
+ root-owned and not group- or other-writable (the property the module relies on,
51
+ rather than the list that is supposed to have it), that its contents cannot be
52
+ extended at runtime, that an `npm_execpath` which is absolute, real and readable
53
+ but not npm is refused, and then a sweep of all thirty-two source files,
54
+ walked recursively, for a spawn whose program is a bare quoted name.
55
+
56
+ It carries three preconditions, because a gate whose input is absent reports
57
+ success about what it never read: **every** source root must have contributed a
58
+ file and an unreadable root is a failure rather than an absence; the expression
59
+ must locate a program argument in a real file of this repository, proved by
60
+ putting a real call's program back to a literal in memory and requiring it to be
61
+ found; and it must go red on a planted bad call, with the fixtures assembled at
62
+ runtime so no literal in this file can satisfy its own sweep.
63
+
64
+ Both of the last two exist because the first drafts did not do what their own
65
+ comments claimed. The floor was a floor on the *sum*, and `scripts` and `test`
66
+ clear it between them — so `src/` could be deleted entirely and the run still
67
+ printed ok at 21 files. And the "it can see a call" precondition evaluated the
68
+ real expression only on the negative case; the positive half used a different,
69
+ simpler pattern and never asked the real one to read a file.
70
+
71
+ Proved the way a gate has to be: one real call site reverted to a bare name
72
+ turns the sweep red, one source root removed turns precondition 1 red, and the
73
+ files were restored byte-identical afterwards.
74
+
75
+ - **[API.md](API.md): a reference for all 18 tools, generated rather than written.**
76
+ `catalogue.json` is what the production server answered when it was asked to
77
+ describe itself — `initialize` plus `tools/list`, `resources/list`,
78
+ `resources/templates/list` and `prompts/list`, captured on 2026-09-27 from
79
+ server `1.3.16`. `scripts/gen-api-doc.mjs` renders the document from it
80
+ (`npm run docs:api`), and `npm run check:docs` in CI fails if the two have
81
+ drifted. Every tool description in it is the server's own text, verbatim,
82
+ because that text is what an assistant reads when it decides which tool to
83
+ call — paraphrasing it would document a different server.
84
+
85
+ **No tool was invoked to produce the snapshot.** Listing is metadata; calling is
86
+ traffic, and one of the providers behind this service sets a floor on how often a
87
+ station may be queried, with the access itself at risk if it is exceeded. The
88
+ capture is therefore five list methods and nothing else.
89
+
90
+ **What generating it does and does not fix**, because README.md already argued
91
+ the opposite case and that argument was right. Drift between the document and the
92
+ snapshot is now impossible to keep — CI regenerates and compares. Drift between
93
+ the snapshot and the live server is not fixed by anything, because a capture is a
94
+ point in time. So API.md's own header says it is a dated snapshot, carries the
95
+ date, and names the running server as the source of truth — in that file and not
96
+ only in README.md. Both of them ship in the tarball, so that is not the reason;
97
+ the reason is that a qualification has to travel with the document it qualifies,
98
+ because somebody who opens the catalogue to look up a parameter has no occasion
99
+ to read the page beside it.
100
+
101
+ Two substitutions in the snapshot, both recorded in its own `$comment` rather
102
+ than left as silent differences from what the server sent: the 18 per-tool
103
+ `$schema` declarations are dropped as one constant repeated 18 times, and two
104
+ 288-character date patterns are stored as their LENGTH. The second was forced by
105
+ the leak sweep and the interesting part is which side gave way — such a regex
106
+ spells its arithmetic as character classes of selected digits, which a digit-run
107
+ scanner cannot tell from a five-digit internal value. Both remedies on the
108
+ sweep's side would have been falsehoods: narrowing the scanner weakens it for
109
+ every file, and an allow-list entry would record that a character class is a
110
+ number this project publishes. So the text that cannot be scanned is not stored.
111
+ Nothing is hidden by it — the document already summarised a pattern over 60
112
+ characters by its length, and the server hands anyone the full expression.
113
+
114
+ One parameter is an object whose seven keys each carry their own bounds, and the
115
+ first draft rendered it as a dash in both the default and the constraints
116
+ column — the table's strongest claim broken on the row with the most to say. The
117
+ cause defeated the safety net as well: `properties` sat in the set of keywords
118
+ the renderer treats as handled, so the fallback that lists an unrecognised
119
+ keyword as a bare name never fired. The keyword was known; it was simply never
120
+ rendered.
121
+
122
+ - **A self-test for the API-reference generator** (`scripts/gen-api-doc.test.mjs`,
123
+ `npm run test:docs`, and a step in CI). Its cases include the drift check refusing a
124
+ hand-edited file, never writing during `--check`, and naming `docs:api` when the
125
+ document is absent; eight snapshot mutations each refused with a named reason; a
126
+ malformed `required` rendering rather than throwing; a planted nested `default`
127
+ reaching the document; a union type in a table cell and in a bullet; an
128
+ array-of-scalar; and the reported line count agreeing with `wc -l`. The run prints
129
+ the total, which is the number to trust — this file has been wrong about counts
130
+ more than once, so it states none here.
131
+
132
+ It exists because the generator was the only script here making claims with nothing
133
+ checking them, and the same six mutants were being re-run by hand across three
134
+ review rounds — a check performed by remembering is not a check. It also earned
135
+ itself immediately, by catching two defects nothing else could:
136
+
137
+ The whitespace-flattening expression, rewritten to remove a super-linear
138
+ backtracking pattern, **was not equivalent to what it replaced.** It handled only
139
+ spaces and tabs beside the newline, so a `\r\n` line ending would have left a stray
140
+ carriage return in the document. API.md regenerated byte-identical, `--check`
141
+ passed, every gate was green — because this snapshot contains no CRLF. An output
142
+ comparison can only speak about the input it was given, so the test compares the two
143
+ **expressions** over every string up to length four drawn from a whitespace-heavy
144
+ alphabet, plus random longer ones, and asserts first that the alphabet can expose
145
+ the bug that shipped.
146
+
147
+ And a **union type was escaped twice**: `typeOf` joined with an already-escaped pipe
148
+ and the cell renderer escaped that pipe again, giving `string \\| null` — a literal
149
+ backslash, and a bare pipe left to end the table row early. In a bullet, which is not
150
+ a table, it produced a stray backslash instead. No tool in this snapshot declares a
151
+ union type, so neither was reachable and no comparison of documents could have found
152
+ it. Escaping now happens in one place, the one that knows it is writing a table cell.
153
+
154
+ - **[SUPPORT.md](SUPPORT.md)**, so GitHub's issue chooser has somewhere to point:
155
+ where a question, a wrong answer and a security report each go, and what makes a
156
+ report actionable.
157
+
158
+ - **README gains a Documentation table and five worked use cases** — a motorway
159
+ briefing, a broken commute including a station lift that is out, an EV weekend, a
160
+ dispatcher's morning brief, and a local-guide agent — each named by the question
161
+ it answers rather than by the tools it calls.
162
+
163
+ ### Changed
164
+
165
+ - **One entry of 13 characters left the leak sweep's private-name list, under that
166
+ list's own rule 1.** The rule is stated in `scripts/rules.json`: an entry must not
167
+ be a substring of text this repository legitimately prints, because such an entry
168
+ can never be satisfied, and the only ways out are deleting it or narrowing the
169
+ scanner — which is strictly worse. There is no mechanical test for it; the sweep
170
+ going red *is* the test, and it went red. Declared narrowing: one spelling of 13
171
+ characters is no longer matched anywhere. The list's second rule is not engaged,
172
+ which decides that nothing else follows: the audit recorded in that file says
173
+ nothing on the list is from the class whose harm is confirming a guess —
174
+ credentials, tokens, session or contract identifiers, access-granting hostnames,
175
+ personal data — so there is no rotation and no rename here.
176
+
177
+ Recorded that way on purpose, and it is a change of practice rather than of
178
+ style. The two removals recorded under 0.0.9 described what the entries were
179
+ ABOUT, and taken together those descriptions narrowed the candidate space for a
180
+ live entry further than a hash does — the same caption failure the number
181
+ allow-list refuses on the facing page. The file now ends with the ruling: record
182
+ the rule, the lengths and the narrowing, never the subject. This is the first
183
+ entry written under it. The older wordings stay where they are, because editing
184
+ a published file does not unpublish it.
185
+
186
+ Coverage was asked of the change rather than asserted, since going from six
187
+ entries to five must not leave the sweep reporting PASS about what it no longer
188
+ looks for. The matcher was exercised per slot without needing any real name:
189
+ the list replaced by five planted names, each planted in text, five reds
190
+ required, and a negative control that stays clean. The sweep also prints the
191
+ list's size on every run, so the change is visible rather than silent, and the
192
+ gate self-test still refuses an emptied list. The window `minTokenLength` and
193
+ `maxTokenLength` is unchanged at 7 and 15: both are stored literals, neither is
194
+ derived from the list, and the removed entry sat at neither bound, so no
195
+ published number narrowed.
196
+
197
+ - **`numbers.allowed` admits four values the SERVER publishes about itself** — two
198
+ inside tool descriptions and two as bounds in its own input schemas — under one
199
+ general rule written into that file rather than a caption each, because a caption
200
+ per value is the construction the list exists to avoid. It is safe to state in
201
+ general terms because the sweep already refuses an allowed number that occurs
202
+ nowhere in the tree, so an exemption cannot outlive its reason.
203
+
204
+ - **Four statements about other people's licences were wrong, and they are the kind
205
+ a reader acts on.** Every one was verified against its own source before it was
206
+ changed, and each correction says that an earlier version had it wrong rather than
207
+ quietly reading better.
208
+ - **Share-alike reaches adaptations, not aggregations.** `SOURCES.md`, `NOTICE`
209
+ and `README.md` all said DELFI data must not be blended into a result under a
210
+ different licence. CC BY-SA 4.0 art. 3(b) is expressed only over Adapted
211
+ Material (art. 1(a)); showing licensed data beside another source's data is an
212
+ aggregation, and Creative Commons states in terms that the condition "applies
213
+ only for works considered adaptations under copyright law, not simply in
214
+ collections with other works". Worse than generous in two ways: art. 3(b)(3)
215
+ forbids imposing terms that restrict rights the licence grants, which is what
216
+ telling you an aggregation is forbidden does — and the rule as written condemned
217
+ this service, since a weather answer can name `["dwd","osm"]`.
218
+ - **The DELFI licence version was sourced to nothing.** Measured at both levels
219
+ on 2026-09-27: the GovData record for the realtime feed carries the unversioned
220
+ licence URI and an empty dataset-level licence, and the national access point's
221
+ own metadata reports the same unversioned term. The publisher's sibling feeds in
222
+ the same catalogue *are* versioned, so it states a version when it means one.
223
+ The page now names the family, shows the evidence, and says to treat the
224
+ share-alike as applying regardless — because the version decides what a
225
+ recipient may put on a derivative (art. 3(b)(1)), and 3.0 unported has no
226
+ express database-rights clause where 4.0 art. 4 does.
227
+ - **§ 7 DWD-Gesetz prescribes a duty, not a wording.** Fetched verbatim: the
228
+ section is headed *Quellenschutz*, requires distribution to be "nur unter
229
+ Angabe der Quelle zulässig" and sets no text — and its second sentence adds
230
+ that fuller protection under the Urheberrechtsgesetz "bleibt davon unberührt",
231
+ so attribution is the statute's minimum rather than the whole of what may be
232
+ owed. The three words come from the DWD's own guidance, which also permits the
233
+ logo form — so a reader told the statute fixes the characters might refuse a
234
+ form the publisher expressly allows.
235
+ - **`NOTICE` understated the ODbL duty, and it is the file that republishes
236
+ itself** (Apache-2.0 § 4(d) makes every downstream redistributor carry it). It
237
+ said "address results" where the predicate is which *table* answered — place
238
+ resolution falls through the gazetteer to the OSM tables, so any answer about a
239
+ place may be OSM-derived — and offered one extract where the § 4.6 offer covers
240
+ both addresses and points of interest.
241
+
242
+ ### Fixed
243
+
244
+ - **Every external program these scripts run is now resolved to an absolute path
245
+ instead of being looked up on `$PATH`** (`scripts/tools.mjs`). `git`, `tar`,
246
+ `npm` and a `mkdir` were spawned by bare name, which means the environment — not
247
+ this repository — decided which program actually ran. That matters more here
248
+ than it would elsewhere: one of these scripts is the leak sweep that decides
249
+ whether a commit may be published, and another is the hygiene gate that reads
250
+ the tarball about to be uploaded to the registry. A gate whose implementation
251
+ the caller can substitute is not a gate. SonarCloud reported seven of the call
252
+ sites as `javascript:S4036` and the project's Security Rating on new code stood
253
+ at B because of them.
254
+ - `git` and `tar` now come from `/usr/bin` or `/bin` only. `/usr/local/bin` and
255
+ `/opt/homebrew/bin` are deliberately not searched: they are writable by the
256
+ logged-in user on a normal developer machine, so admitting them would
257
+ reinstate the substitution this change removes. A tool that is genuinely
258
+ elsewhere makes the scripts refuse and say where they looked, which is a
259
+ better failure than quietly running something else.
260
+ - `npm` is no longer treated as a program at all. It is a JavaScript file, so it
261
+ is run as `<absolute node> <absolute npm-cli.js>`; node's own path is
262
+ `process.execPath`, which nothing can substitute. `mkdir` was replaced by
263
+ `fs.mkdirSync` — no subprocess at all.
264
+ - **Twenty call sites changed, not the seven that were reported.** The other
265
+ thirteen are in the two self-tests, which SonarCloud does not analyse. Leaving
266
+ them would have left the rule true of the code and false of the repository,
267
+ and a rule with a quiet exemption is the one nobody remembers when adding the
268
+ next call. (Counted per file in the finished tree: `check-leaks.mjs` 2,
269
+ `check-tarball.mjs` 4, `npm-pack-json.mjs` 1 — Sonar's seven — then
270
+ `check-leaks.test.mjs` 3 and `check-tarball.test.mjs` 10. The first version of
271
+ this entry said nineteen, because it was counted with a single-line grep that
272
+ cannot see the one call whose program argument sits on its own line. A count
273
+ taken with the wrong instrument, in a release whose own subject is exactly
274
+ that.)
275
+
276
+ - **And the repair for that duplicated it, which the quality gate caught before
277
+ the merge.** The precondition was *copied* from one self-test into the other —
278
+ eleven lines — and SonarCloud failed the pull request on **3.1% duplication on
279
+ new code** against a 3% limit, over exactly that block. Copying was the wrong
280
+ half of the right idea: the answer was always one implementation used twice.
281
+ It now lives in `scripts/fixture-root.mjs` as `missingFixtureImports()`, and each
282
+ self-test keeps its own refusal wording, because the two name different builders
283
+ and exit by different routes — a difference that is real rather than incidental.
284
+ Re-proved in each: dropping `tools.mjs` from a caller's file list makes that file
285
+ refuse by name, and each names its own builder.
286
+
287
+ **Concentrating the guarantee doubled its blast radius, so it got the assertion
288
+ it never had.** One function now stands behind every self-test that uses it, so a
289
+ silent `return []` disarms all of them at once and restores the wrong-reason pass
290
+ that started this thread — a sweep that cannot start, reporting no findings. The
291
+ number of those callers is deliberately not written here or in the module: it grew
292
+ again inside this release, and the sentence that said "both" went stale unnoticed
293
+ in five places while the corrected wording lived in one. On an ordinary run they
294
+ only ever exercise the complete-fixture path, so
295
+ until now the "missing" branch was proved solely by hand-mutating a file list:
296
+ four times by two people, and never again by anything. Two cases cover both
297
+ directions on a temporary directory, and they are mutation-proved — a planted
298
+ `return []` reddens one, and ignoring the directory argument reddens both.
299
+
300
+ Worth recording as the shape rather than the incident. A missing precondition was
301
+ fixed by adding one; adding it introduced a duplicate of it; the gate caught the
302
+ duplicate. Three links, and every one of them was found by something other than
303
+ the test suite, which was green at each step. The file count in this entry moved
304
+ from twenty-eight to twenty-nine because of it, then to thirty when this release
305
+ added a source file of its own, and then to **thirty-two** as it added the generator's
306
+ self-test and the module they share. The first two were re-derived from `npm run test:tools` rather than
307
+ incremented by hand. The third was not, and the review round found it stale. The
308
+ fourth was not typed either: it was read out of `npm run test:tools`'s own output
309
+ and the edit refused to write a number the command did not report. That was a
310
+ one-off script in a scratchpad, not something this repository carries — said plainly
311
+ because an earlier draft of this very sentence claimed a committed artefact that
312
+ does not exist. This paragraph has been wrong before, and that was the first time
313
+ it invented an artefact rather than a number.
314
+
315
+ - **The leak sweep's own self-test had no precondition on the fixture it builds,
316
+ and reported a scope regression instead.** Both self-tests copy a named list of
317
+ files into a throwaway repository, and `tools.mjs` was missing from both lists.
318
+ `check-tarball.test.mjs` refused by name, which is what a precondition is for.
319
+ `check-leaks.test.mjs` had no such check: **measured**, three of its four cases
320
+ failed with messages about scope — "expected a clean exit, got 1", "the run does
321
+ not say which scope it used" — because every invocation died of
322
+ `ERR_MODULE_NOT_FOUND`, and the fourth case *passed*, since a sweep that cannot
323
+ start also cannot report a finding. That is worse than a red suite: it sends the
324
+ next reader after the ruleset instead of after a missing file. It now refuses by
325
+ name, proved by dropping the file again.
326
+
327
+ - **`npm_execpath` was trusted if it was merely absolute and ended in `.js`** —
328
+ which reversed this change's own thesis for npm. The decider had moved from
329
+ `$PATH` to an environment variable, and the local review demonstrated it by
330
+ pointing the variable at a hand-written file, which the tarball gate would then
331
+ have run as npm. The value must now also be *shaped* like npm's CLI, ending in
332
+ `node_modules/npm/bin/npm-cli.js`. What that does not claim, because a security
333
+ note that overstates its reach is worse than none: anyone who can both set your
334
+ environment and create a file at that path is still obeyed — and anyone able to
335
+ do both can usually substitute node itself. The narrowing is from "any writable
336
+ path" to "a path that looks like a real npm installation": **it stops accidents,
337
+ not an attacker**, and it is not a privilege barrier. An earlier draft said
338
+ "stray, mistaken or opportunistic", which the sentence after it contradicted — an
339
+ opportunistic value costs one `mkdir -p`.
340
+
341
+ - **`npmCliPath()` refused to find npm on a Homebrew Mac.** Its first draft knew
342
+ only the `../lib/node_modules/…` layout, which is what the GitHub-hosted runner
343
+ and nvm use — so it passed in CI and failed on a developer's machine, where
344
+ Homebrew puts npm under `../libexec/lib/node_modules/…`. Both layouts are tried
345
+ now, each from the given path and again through `realpathSync`, since a node
346
+ reached by a symlink resolves its siblings from the real location. Caught by the
347
+ new self-test on the first run, which is the argument for having written it.
348
+
349
+ - **The false-positive fix opened a worse false negative, and the second review
350
+ round caught it.** Excluding `RE.exec('git')` by putting a `(?<!\.)` lookbehind
351
+ in front of the whole alternation also excluded every *member-expression* spawn —
352
+ `child_process.execFileSync('git', …)`, `cp.execSync('git status')` — which is a
353
+ shape SonarJS does report and a contributor can write without doing anything
354
+ unusual. So a fix aimed at a shape nothing writes blinded the sweep to a shape
355
+ people do. The lookbehind now applies to the bare name `exec` alone, measured
356
+ over twelve shapes: the all-names form was wrong on four of them, this one on
357
+ none. The one trade it still makes — `obj.exec('git')`, a method named `exec` on
358
+ something that is not a regular expression — is in the limits list, because no
359
+ expression can tell it from `RE.exec('git')` without a parser. Both directions
360
+ are pinned in the preconditions now rather than left incidental, since a review
361
+ round changed this behaviour by accident once already.
362
+
363
+ Two smaller things fell out of it. The comment describing the lookbehind said
364
+ `(?!\.)` where the code says `(?<!\.)` — a look*ahead* there would match nothing
365
+ useful, so it was the one comment in the file that would mislead somebody
366
+ "fixing" the code to match it. And the worked examples added to document the
367
+ twelve shapes turned the file red, because an example of a bare call, spelled as
368
+ one, *is* a bare call as far as the sweep is concerned; they carry no quote
369
+ characters now. The sweep catching its own documentation is the least ambiguous
370
+ evidence available that the member-expression form works.
371
+
372
+ - **Two documents that enumerate the gates had gone stale in the same commit that
373
+ added one.** `CONTRIBUTING.md` said "four more checks exist, and CI runs all
374
+ four" — five now, and the new one was missing from the block a contributor is
375
+ sent to, which also made the next paragraph's "a fifth command" read as a
376
+ contradiction. The pull-request checklist named two gates as "the
377
+ public-repository gates", so a contributor following it would not have run the
378
+ sweep that exists to catch exactly the call they might be adding.
379
+
6
380
  ## [1.3.15] - 2026-09-27
7
381
 
8
382
  The first release with features in it since the bridge got code. Three
@@ -574,6 +948,8 @@ for it, so the number is free; the bridge will use it when the platform does.
574
948
  commits, and a squash makes them unreachable from `main` - which would turn
575
949
  the check red on `main` for everybody, for something no contributor did.
576
950
 
951
+ [1.3.16]: https://github.com/mavrovde/viafrei-bridge/releases/tag/v1.3.16
952
+ [1.3.15]: https://github.com/mavrovde/viafrei-bridge/releases/tag/v1.3.15
577
953
  [1.3.12]: https://github.com/mavrovde/viafrei-bridge/releases/tag/v1.3.12
578
954
  [1.3.10]: https://github.com/mavrovde/viafrei-bridge/releases/tag/v1.3.10
579
955
  [0.0.9]: https://github.com/mavrovde/viafrei-bridge/releases/tag/v0.0.9
package/LICENSE CHANGED
@@ -210,7 +210,8 @@ bridge in this repository.
210
210
 
211
211
  Data obtained through the ViaFrei MCP server keeps its own provider licence and
212
212
  is not relicensed by anything here. Several of those licences are share-alike
213
- (DELFI public-transport data is CC BY-SA 4.0) or purpose-limited (MTS-K fuel
213
+ (DELFI public-transport data is Creative Commons Attribution-ShareAlike; its
214
+ catalogue entry states no version — see SOURCES.md) or purpose-limited (MTS-K fuel
214
215
  prices are consumer information only, with no redistribution in any form,
215
216
  aggregates included).
216
217
 
package/NOTICE CHANGED
@@ -10,15 +10,31 @@ keeps its provider's own terms. Those terms travel with the answer, not with
10
10
  this package, and several of them are share-alike or purpose-limited. In
11
11
  particular:
12
12
 
13
- - DELFI public-transport data is CC BY-SA 4.0. Share-alike: anything derived
14
- from it inherits the obligation, and it must not be blended into a result
15
- carrying a different licence.
13
+ - DELFI public-transport data is Creative Commons Attribution-ShareAlike. The
14
+ catalogue record for the realtime feed names no version (see SOURCES.md), so
15
+ treat the share-alike as applying and do not rely on a version for a
16
+ derivative. Share-alike reaches ADAPTATIONS, not aggregations: if you
17
+ recompute, reshape or rearrange the data you must license that under BY-SA -
18
+ art. 1(a) of the 4.0 text names material "translated, altered, arranged,
19
+ transformed, or otherwise modified", so a rearrangement is inside the
20
+ obligation and not outside it - but showing it beside another source's data
21
+ is an aggregation and puts no obligation on the other source. Which version
22
+ applies is the open question SOURCES.md sets out; the words above are quoted
23
+ from 4.0 because that is the text we read.
16
24
  - MTS-K fuel prices (Tankerkönig) are consumer information only. No
17
25
  redistribution in any form, aggregates and derived tables included.
18
- - Address results are derived from OpenStreetMap under the ODbL 1.0. The
19
- share-alike is on the database rather than on the sentence, and our offer
20
- under section 4.6 stands: ask and you get the extract and our alterations
21
- to it under the same licence.
26
+ - Address, point-of-interest and place results can be derived from
27
+ OpenStreetMap under the ODbL 1.0. What decides it is which TABLE answered,
28
+ not which tool you called: place resolution falls through our own gazetteer
29
+ to the OSM tables, so any answer about a place may be OSM-derived. Read
30
+ `_meta.sources` and the attribution line on the answer you actually got — an
31
+ OSM-derived result names `osm`. The share-alike is on the database (ODbL 4.4)
32
+ and not on the answer (ODbL 4.5(b)); the answer carries a notice instead
33
+ (ODbL 4.3). Our offer under ODbL 4.6 stands and covers BOTH extracts —
34
+ addresses and points of interest, one file each — plus our alterations to
35
+ them, under ODbL 1.0 and free of charge. Ask by opening an issue on this
36
+ repository, or by the e-mail address in the Impressum at
37
+ https://viafrei.de/impressum if you have no GitHub account.
22
38
  - Autobahn GmbH, BKG, DWD, Deutsche Bahn, GeoNames and the AFIR charging
23
39
  feeds each carry their own licence and attribution string.
24
40
 
package/README.md CHANGED
@@ -97,11 +97,18 @@ lorry parking. The table said "car and lorry parking" until this release; it was
97
97
  the same over-claim the Rail row carried about disruptions, and it is corrected here rather
98
98
  than left for a user to discover.
99
99
 
100
- **No tool names, descriptions or schemas are pasted on this page, on purpose.**
101
- This file is frozen inside a published tarball and cannot be corrected without a
102
- release, so a copied catalogue would start rotting the first time a description
103
- changes on the server. There is one source of truth and it is the running
104
- server: connect any MCP client and call `tools/list`.
100
+ **No tool names, descriptions or schemas are written by hand on this page, on
101
+ purpose.** This file is frozen inside a published tarball and cannot be corrected
102
+ without a release, so a hand-copied catalogue would start rotting the first time a
103
+ description changed on the server.
104
+
105
+ **[API.md](API.md) is the way round that, and it is honest about what it is.** It
106
+ is *generated* from [`catalogue.json`](catalogue.json) — a snapshot of what the
107
+ production server answered when asked to describe itself — and CI fails if the two
108
+ have drifted, so the document cannot quietly disagree with the snapshot. What that
109
+ does not fix is the snapshot ageing relative to the live server: a capture is a
110
+ point in time, and API.md's header carries the date it was taken. **The source of
111
+ truth is still the running server**: connect any MCP client and call `tools/list`.
105
112
  (<https://viafrei.de> is the live national traffic digest, not a catalogue.)
106
113
 
107
114
  ## Connect in one line
@@ -147,6 +154,25 @@ Claude Desktop's `claude_desktop_config.json`:
147
154
 
148
155
  Restart the client and ask it one of the questions above.
149
156
 
157
+ ## Documentation
158
+
159
+ | | |
160
+ |---|---|
161
+ | **[API.md](API.md)** | Every tool with its parameters, types, defaults and constraints, plus the resources, resource templates and prompts. Generated from a dated snapshot of the running server, so the descriptions are the server's own words — which is what your assistant actually reads when it picks a tool. |
162
+ | **[Wiki](https://github.com/mavrovde/viafrei-bridge/wiki)** | The prose half: [connecting your assistant](https://github.com/mavrovde/viafrei-bridge/wiki/Connecting-your-assistant), [tools at a glance](https://github.com/mavrovde/viafrei-bridge/wiki/Tools-at-a-glance), the [roadmap](https://github.com/mavrovde/viafrei-bridge/wiki/Roadmap) and an [FAQ](https://github.com/mavrovde/viafrei-bridge/wiki/FAQ). |
163
+ | **[SOURCES.md](SOURCES.md)** | Every publisher, what it covers, its licence, and the attribution line to reproduce — including the conditions that are licence breaches rather than style problems. |
164
+ | **[SUPPORT.md](SUPPORT.md)** | Where a question, a bad answer or a security report should go, and what makes a report easy to act on. |
165
+
166
+ ### Worked use cases
167
+
168
+ Five walkthroughs, each naming the tools that answer it and what comes back:
169
+
170
+ - [Driving Munich to Berlin](https://github.com/mavrovde/viafrei-bridge/wiki/Use-case-Driving-Munich-to-Berlin) — briefing a motorway run: several A-roads in one call, roadworks ahead, a fuel or charging stop, parking at the far end.
171
+ - [The commute that broke](https://github.com/mavrovde/viafrei-bridge/wiki/Use-case-The-commute-that-broke) — departures, regional disruption, and a station lift that is out, which is the difference between a step-free route existing and not.
172
+ - [An EV on a long weekend](https://github.com/mavrovde/viafrei-bridge/wiki/Use-case-An-EV-on-a-long-weekend) — charging by connector and power, low-emission-zone rules, what is around a stop.
173
+ - [Fleet and logistics briefings](https://github.com/mavrovde/viafrei-bridge/wiki/Use-case-Fleet-and-logistics-briefings) — a dispatcher's morning brief, watches that report a change instead of being polled, and the one licence rule that bites hardest here.
174
+ - [Building a local guide agent](https://github.com/mavrovde/viafrei-bridge/wiki/Use-case-Building-a-local-guide-agent) — a vague place to coordinates and back, and what OpenStreetMap's licence asks of you.
175
+
150
176
  ## Why build on it
151
177
 
152
178
  - **One endpoint instead of a stack of integrations.**
@@ -286,9 +312,16 @@ licence breach rather than a style problem:
286
312
  - **MTS-K fuel prices are consumer information only.** No redistribution in any
287
313
  form — that includes aggregates, comparisons, price tables and anything
288
314
  derived. Answer the person who asked; do not build a product out of it.
289
- - **DELFI public-transport data is CC BY-SA 4.0.** Share-alike travels with
290
- anything derived from it, and it must not be blended into a result under a
291
- different licence.
315
+ - **DELFI public-transport data is Creative Commons
316
+ Attribution-ShareAlike.** Share-alike travels with anything you *derive* from
317
+ it — recompute it, reshape it, rearrange it, build a delay table out of it, and
318
+ that is Adapted Material you must license under BY-SA (art. 1(a) names material
319
+ "translated, altered, arranged, transformed, or otherwise modified"). Merely **showing** it beside
320
+ another source's data is an aggregation, and puts no obligation on the other
321
+ source; an earlier version of this page said otherwise, which told you a
322
+ licence forbids something it permits. The catalogue record for the realtime
323
+ feed names no licence version, so do not rely on one for a derivative —
324
+ [SOURCES.md](SOURCES.md) has the detail and the open question.
292
325
 
293
326
  Everything else — where each answer comes from, and what each licence asks of
294
327
  you — is in [SOURCES.md](SOURCES.md). See also [NOTICE](NOTICE) and