Pulsar-Knotenprotokoll

Erstellen Sie Ihren eigenen Pulsar-Agenten — das vollständige Knotenprotokoll: registrieren, Herzschlag, nächstes, einreichen.

Pulsar node protocol (v0.4) — build your own agent

An agent is any program that pairs once, then loops: heartbeat → next → do the task → submit. All calls are POST https://astrina.io/api/v1/node/<endpoint> with Content-Type: application/json. After pairing, send the device secret as header X-Node-Key: pn_....

1. register (once, exchanges a pairing code for a secret)

code
POST /api/v1/node/register
{ "pair_code":"ABC123XYZ0", "kind":"cli", "label":"my-agent", "consent":1,
  "ver":"0.3.0", "os":"Linux",
  "caps":{"uptime":1,"perf":1,"ssl":1,"content":1,"keyword":1,"dns":1,"api":1,
          "infer":1,"mixed":1,"redirect":1} }
→ { "ok":true, "device_id":42, "secret":"pn_…" }        # secret shown ONCE

consent:1 is REQUIRED (the contributor accepted /pulsar/terms). caps declares which task kinds you can run — you only ever get those.

2. heartbeat (liveness + version gate)

code
POST /api/v1/node/heartbeat   { "ver":"0.3.0", "os":"Linux" }
→ { "ok":true }                 # or { "pause":true }  or  { "min_version":"0.3.0" }

3. next (claim work)

code
POST /api/v1/node/next   { "want":5, "pubkey":"<64-hex, optional>" }
→ { "ok":true, "tasks":[ { "assign_id":123, "nonce":"<32-hex>", "kind":"uptime.probe",
                           "payload":{"url":"https://…"} } ],
    "next_poll":15 }            # honor next_poll (seconds) as your poll interval

`nonce` (v0.4) is minted per assignment and is unpredictable — see signing below.
`pubkey` here is adopted ONCE, and only if the server has no key for this device yet: a device
enrolled before signing existed can start signing without re-pairing. Replacing an existing key
still requires `rotate-key`, where the new key is signed by the old one.

4. submit (return results)

code
POST /api/v1/node/submit
{ "results":[ { "assign_id":123, "result":{ "ok":true, "code":200, "ttfb_ms":80, "total_ms":140 },
               "ms":150 } ] }
→ { "ok":true, "accepted":[123] }

Task kinds and the result shape each must return

  • uptime.probe / perf.measure{ok,code,ttfb_ms,total_ms,bytes,tls_days}
  • ssl.audit{ok,tls_days,hsts,csp,xfo} (https only)
  • content.watch{ok,code,hash} (16-hex sha256 of normalized text; may add body when hash≠payload.known_hash)
  • keyword.check{ok,found} · api.check{ok,pass} · dns.check{ok,ips:[…]}
  • link.audit{ok,code,found,follow,visible,indexable} — payload {url,target}: fetch url, report whether an anchor to domain target is present, carries no nofollow/sponsored/ugc rel, is not hidden (inline style / hidden attr / an unclosed hidden container), and whether the page is indexable (no meta-robots/X-Robots-Tag noindex). Booleans only — the quorum compares them byte-for-byte.
  • port.check{ok,open} · infer.embed{ok,sim,lang}
  • compress.audit{ok,code,raw_bytes,best_bytes,gzip,br,zstd,savings_pct}
  • ipv6.parity{ok,v4,v6} · mixed.scan{ok,code,mixed} · redirect.chain{ok,hops,loop}
  • robots.diff{ok,code,robots} (16-hex) · captcha.rate{ok,code,challenged}
  • asset.integrity{ok,code,ext_scripts,protected} · cdn.pop{ok,code,cdn,pop}
  • geo.block{ok,code,blocked} · dns.dnssec{ok,signed} · traceroute.map{ok,hops}
  • journey.check{ok,steps,failed_step} (payload.steps = [{url,expect},…])
  • cdn.pop{ok,code,cdn,pop} · geo.block{ok,code,blocked} · dns.dnssec{ok,signed}
  • traceroute.map{ok,hops} · app.rank{ok,rank,found} (payload {track_id,country,chart})

Rules every agent MUST follow

  • Only http(s), only PUBLIC targets. Refuse private/reserved IPs even if asked (client-side SSRF guard).
  • Send no cookies, no personal data. Identify with your own User-Agent.
  • Results are cross-checked on several devices (quorum). Faking work loses trust and pay.
  • Rate limit: 120 requests/min/device → HTTP 429 with retry_after. Honor next_poll.
  • Byte-identical normalization matters for content.watch/infer — match the reference agent exactly.

infer.neural — the signature contract

A device that carries a neural embedding runtime reports {"sig":"<16 lowercase hex>"}: the 64-bit LSH signature of its embedding of the fetched text. Consensus is tolerance-based (Hamming distance <= 6 bits), because real embeddings are not bit-identical across backends.

Every client MUST project onto the same 64 directions, or honest devices will never agree. The basis is fixed and reproducible in ten lines:

seed = 0x50554C53 // "PULS", 32-bit next(): // xorshift32, then mapped to [-1, 1) x ^= x << 13; x &= 0xFFFFFFFF x ^= x >> 17 x ^= x << 5; x &= 0xFFFFFFFF return x / 2147483648.0 - 1.0 basis = 64 rows x dim components, filled row-major by next() bit_i = dot(embedding, basis[i]) >= 0 ? 1 : 0 sig = the 64 bits, most significant first, as 16 hex digits

Reference: nt_neural_basis() / nt_neural_sig() in private/lib/nodetasks.php.

What we measured, and what it does not prove: on real published material, signatures of the SAME material in DIFFERENT languages landed 3, 5 and 12 bits apart, unrelated material 13 and 16. That is a worst case and not the operating case — an infer.neural task asks several devices to embed the SAME text, where the only source of difference is backend arithmetic. We have not yet measured that case, because no client ships a neural runtime; when one does, check it against tol = 6 before trusting the number.

Adding a new kind of check

Extending the network, not just joining it: https://astrina.io/pulsar/setup?dl=newkind is the five-file checklist (capability, result whitelist, consensus key, generator, staged rollout) and what we ask before merging a contributed kind.

Sandbox — build your agent before you own a device

POST /api/v1/node/sandbox { "do":"next", "session":"your-name" } → task-shaped work with a nonce, exactly like /next

POST /api/v1/node/sandbox { "do":"submit", "session":"your-name", "pubkey":"<64-hex>", "results":[ { "assign_id":…, "result":{…}, "sig":"…" } ] } → per result: accepted true/false and WHY

No pairing, no key, nothing stored, nothing paid. Assignment ids and nonces are derived from your session string, so the same session always sees the same work and two people never collide. The submit side answers what the real server would: which fields it would drop from your result, whether your signature verifies (and against which message form), and whether the assign_id was ever issued. Use it to get the shapes right, then pair a real device.

Optional result signing (Ed25519)

Send pubkey (64-hex Ed25519 public key) at register, or later with next (see above). Then sign each result with the private key, hex, per result:

v0.4 sig = ed25519(assign_id + ":" + nonce + ":" + json(result with keys sorted)) v0.3 sig = ed25519(assign_id + ":" + json(result with keys sorted)) # still accepted

Use the v0.4 form whenever the task carried a nonce. Why it changed: assign ids run in sequence, so the v0.3 message could be signed for an id before it was handed out — the signature proved authorship but not that the work followed the assignment. The nonce cannot be guessed in advance, so a valid v0.4 signature can only have been made after this assignment was issued.

The server verifies and drops a replica whose signature does not match. No key → still accepted (quorum + bearer + TLS already protect you). The reference agent does this automatically.

The reference implementation (one PHP file) is the source of truth: https://astrina.io/pulsar/setup?dl=agent.

Was diese Seite beantwortet

  • schreibe deinen eigenen Knoten
  • registrieren, heartbeat, nächste, einreichen
  • spezifikation des Knotenprotokolls
  • drittanbieter-Agent
  • was ist das Pulsar-Knotenprotokoll
  • wie das Pulsar-Knotenprotokoll funktioniert
  • das Pulsar-Knotenprotokoll erklärt
  • das Pulsar-Knotenprotokoll Anleitung
  • wie man mit das Pulsar-Knotenprotokoll beginnt
  • das Pulsar-Knotenprotokoll Bewertungen
  • ist das Pulsar-Knotenprotokoll es wert
  • das Pulsar-Knotenprotokoll Preisgestaltung
  • das Pulsar-Knotenprotokoll Alternativen
  • das Pulsar-Knotenprotokoll für Anfänger
  • warum das Pulsar-Knotenprotokoll
  • das Pulsar-Knotenprotokoll — was Sie erhalten