@muretai/agent-entry 1.6.1 → 1.6.3
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 +36 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -104,14 +104,17 @@ answers questions and hands off nothing, is a signed claim you cannot keep.
|
|
|
104
104
|
| option | default | what it does |
|
|
105
105
|
|---|---|---|
|
|
106
106
|
| `skills` | `[]` | the menu above — what a visitor learns before knocking |
|
|
107
|
-
| `openDoor` | `true` | publishes `
|
|
107
|
+
| `openDoor` | `true` | publishes `agentEntry.open_door`: the field that tells a visiting agent it may message you with no introduction. The same fact is emitted under the older `muretai.open_door` spelling beside it — read either, write the neutral one |
|
|
108
108
|
| `anonymousLane` | `false` | also answer **unsigned** inquiries. They create no account row, and the lane is capped entry-wide — an unauthenticated caller must never become an unmetered signing oracle |
|
|
109
|
-
| `anonRatePerMin` | `30` | anonymous replies per minute, entry-wide
|
|
109
|
+
| `anonRatePerMin` | `30` | anonymous replies per minute, entry-wide |
|
|
110
|
+
| `signedRatePerMin` | `60` | signed replies per minute **per account**, ON by default. Attribution is not scarcity: a `did:key` costs nothing to mint, so being in your ledger was never a bound |
|
|
111
|
+
| `signedRatePerMinTotal` | `600` | signed replies per minute for the **whole entry**. Free identity defeats per-identity metering by definition, so only the aggregate resists a flood |
|
|
112
|
+
| `guest` | `false` | put the door on a path of its own and leave `GET /` alone entirely — for a site that is keeping its front page. A `GET` on a guest mount answers **405 with `Allow: POST, OPTIONS`**, never 404: the address is signed into a public card, and hiding a published address conceals nothing |
|
|
110
113
|
| `maxAccounts` | `50000` | how many accounts the in-process ledger holds |
|
|
111
114
|
| `domains` | none | the domains this entry speaks for (see below) |
|
|
112
115
|
| `basePath` | from `baseUrl` | the path this entry answers at, derived rather than set beside it |
|
|
113
116
|
| `wbaVerifiers` | none | a JWKS document (`{"keys":[…]}`) of Ed25519 keys whose holders this entry should **recognise** on inbound signed requests (Web Bot Auth / RFC 9421 — see *Who is knocking*). Recognition only adds `env.wba_did` and a visit count; it never changes a verdict |
|
|
114
|
-
| `observer` | none | called once per message with the same envelope your responder gets, **after** the verdict — for counting, logging, analytics. It cannot matter: its return is discarded, a throw is swallowed, a promise is never awaited, so a slow or broken watcher cannot delay or change one byte of the signed reply. See [Counting visits](#counting-visits-without-handing-over-
|
|
117
|
+
| `observer` | none | called once per message with the same envelope your responder gets, **after** the verdict — for counting, logging, analytics. It cannot matter: its return is discarded, a throw is swallowed, a promise is never awaited, so a slow or broken watcher cannot delay or change one byte of the signed reply. See [Counting visits](#counting-visits-without-handing-over-your-customer-list) |
|
|
115
118
|
| `howToUrl` | none | a page a keyless visitor is pointed at as a worked example. **Empty means omitted** — the refusal already teaches the whole recipe without it, and a reference implementation must not stamp somebody else's docs host into every door built from it. Only set it to a URL you operate, and only after checking it resolves |
|
|
116
119
|
| `name`, `description`, `version` | — | the card's own words. `description` is the line a person reads in a directory listing — and the right place to say what you record about visitors, since it is fetched **before** the knock |
|
|
117
120
|
|
|
@@ -498,8 +501,10 @@ navigator.modelContext.registerTool({
|
|
|
498
501
|
```
|
|
499
502
|
|
|
500
503
|
`MY_DID` is the DID your Agent Entry prints at startup — **the same one**, from the same seed.
|
|
501
|
-
That is the only rule when running both
|
|
502
|
-
|
|
504
|
+
That is the only rule when running both, and **nothing here enforces it** — this package never
|
|
505
|
+
sees your in-page handoff. A mismatch is a site publishing two different identities for one
|
|
506
|
+
origin, which a careful visitor may notice and a careless one will not, so treat it as your
|
|
507
|
+
invariant to keep rather than a guard you are behind.
|
|
503
508
|
|
|
504
509
|
What the shop gets out of it: the moment that signed message arrives, an account exists. No
|
|
505
510
|
signup form, no password, nothing to reset — the sender's key is the account. Come back
|
|
@@ -529,8 +534,8 @@ and it is not one. It is the upgrade path:
|
|
|
529
534
|
ledger back to gate, greet or rate-limit, so a fire-and-forget sink records visiting
|
|
530
535
|
agents with no database anywhere. Use `observer` for it, never your responder: watching
|
|
531
536
|
a visit should not be an edit to the code that decides what to say. See
|
|
532
|
-
[Counting visits](#counting-visits-without-handing-over-
|
|
533
|
-
whole pattern, including the one rule that shapes it — **a DID is not a
|
|
537
|
+
[Counting visits](#counting-visits-without-handing-over-your-customer-list) below for the
|
|
538
|
+
whole pattern, including the one rule that shapes it — **a DID is not a cookie**,
|
|
534
539
|
so what leaves your box is a salted digest, never the identifier itself. A sink cannot
|
|
535
540
|
be read back during a request: it counts customers, it cannot recognise one. It
|
|
536
541
|
replaces a log line, not the store above — none of the recommended features stand
|
|
@@ -560,7 +565,7 @@ What the entry now handles for you at the HTTP layer, so you do not have to:
|
|
|
560
565
|
which says a server must accept the absolute form: this endpoint answers exactly the
|
|
561
566
|
address its card names, and the refusal says so.
|
|
562
567
|
|
|
563
|
-
## Counting visits without handing over
|
|
568
|
+
## Counting visits without handing over your customer list
|
|
564
569
|
|
|
565
570
|
You will want to know how many agents knocked, how many came back, and what they asked. All
|
|
566
571
|
three are answerable — and how you answer them decides whether you are counting your visitors
|
|
@@ -571,11 +576,18 @@ envelope, after the verdict, so watching a visit stops being an edit to the code
|
|
|
571
576
|
what to say. It cannot matter: its return is discarded, a throw is swallowed, a promise is
|
|
572
577
|
never awaited — a slow or broken watcher cannot delay or change one byte of the signed reply.
|
|
573
578
|
|
|
574
|
-
**The rule that shapes everything else: a DID is not a
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
a
|
|
578
|
-
|
|
579
|
+
**The rule that shapes everything else: a DID is not a cookie, and it is not a throwaway
|
|
580
|
+
either.** Nobody imposed it — the visitor read your card *before* knocking, and an owner who
|
|
581
|
+
wanted this conversation kept apart would have sent a different agent, because an owner runs
|
|
582
|
+
several and each is a distinct agent with its own lasting identity. But the one that did knock
|
|
583
|
+
means to keep the key it used: that is how it gets recognised, introduced and trusted anywhere on
|
|
584
|
+
the network, so it is closer to a professional's name than to a tracking cookie.
|
|
585
|
+
|
|
586
|
+
Which is exactly why the raw value should not travel onward. **The DID is genuinely durable, and
|
|
587
|
+
you were given it so that YOU could reach them again.** Widen that purpose and nothing happens to
|
|
588
|
+
you legally, which is the part worth understanding: the owner simply stops sending that agent to
|
|
589
|
+
you. Silently, at no cost, and you never learn you lost them — not one data point, the whole
|
|
590
|
+
relationship. So split it:
|
|
579
591
|
|
|
580
592
|
- **What leaves** — a salted digest and a few shape facts. Never the DID, never the text.
|
|
581
593
|
- **What stays** — the relationship (who, how many, first and last seen) in your own store,
|
|
@@ -642,7 +654,7 @@ in the same breath, in plain words.
|
|
|
642
654
|
|
|
643
655
|
This module is not alone. A Python reference implements the same contract, and the two are
|
|
644
656
|
held to **identical verdicts** by an acceptance suite: it runs the same attack battery
|
|
645
|
-
against both, drives this module against
|
|
657
|
+
against both, drives this module against the same wire vectors byte for byte, posts
|
|
646
658
|
identical bytes to each over real sockets — down to the HTTP framing — and requires the same
|
|
647
659
|
status, the same account outcome and the same signed reply from both. If you write a third
|
|
648
660
|
implementation, that suite is the gate.
|
|
@@ -671,9 +683,16 @@ because a shared library would only ever have covered the parts they happen to s
|
|
|
671
683
|
suite posts identical bytes to both, down to the HTTP framing, and requires the same status,
|
|
672
684
|
the same account outcome and the same signed reply.
|
|
673
685
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
686
|
+
**The part of that gate you can run here ships in this package.** `npm test` executes
|
|
687
|
+
`conformance/run.mjs` against `conformance/vectors.json` — the canonical JSON, the signing
|
|
688
|
+
payloads, the card envelopes and the `did:key` round-trips this module must reproduce byte
|
|
689
|
+
for byte. No network, no checkout of ours, nothing to ask us for:
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
npm test
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Write a third implementation and point it at the same vectors.
|
|
677
696
|
|
|
678
697
|
## What this is part of
|
|
679
698
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muretai/agent-entry",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"description": "Make your website answer AI agents: an A2A agent endpoint that verifies who is knocking, opens an account for them and replies signed, in one HTTP round trip. Zero dependencies. Pairs with llms.txt and WebMCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "muretai-agent-entry.mjs",
|