S19: catalog all 44 subjects.json rows with timeout and filter
Some checks are pending
ci / catalog (push) Waiting to run

pfc-derived regenerated; schema timeout_sec + filter; endpoints RST.
This commit is contained in:
George Lambert 2026-09-15 23:10:17 -04:00
parent 1d0176899f
commit f53386c4cc
6 changed files with 931 additions and 271 deletions

40
MODULE.md Normal file
View file

@ -0,0 +1,40 @@
# MODULE — nats-service-endpoints
Git: https://git.georgelambert.org/marchon/nats-service-endpoints
This is **not** a HIPAA/SOC 2/ISO certificate.
Vocabulary: see `https://git.georgelambert.org/marchon/system-git-sync` `docs/thesaurus.md`.
Catalog: `https://git.georgelambert.org/marchon/nats-service-endpoints`.
## What this module is
Runtime or documentation unit in the Peergos-for-compliance / secure-messaging
set. See this repo `README.md` for the short intro.
## Who calls this module and why
Every service that publishes `verae.*`.
**Callers:** secure-messaging, pfc-py-admin, pfc-repl, pfc-ipfs, sm-leaf.
## Messages — from / to
- **From:** `catalog/endpoints.json` (SM core) + `catalog/pfc-derived.json` (all subjects.json names).
- **To:** Sphinx HTML/PDF on docs.pfc `/nats-service-endpoints/`.
## Filters / security
`reject[]` + `filter` + `timeout_sec`. Forbidden `verae.llm.turn.>`.
## Errors and timeouts
- **Errors:** Unknown subject / missing fields → dead letter for SM; others `dead=none`.
- **Timeouts:** See each row `timeout_sec` (5s request-reply, 4s queue, 30s pin).
## Where data is stored and how others use it
JSON catalog in git.
Walkthroughs and screenshots: `https://git.georgelambert.org/marchon/peergos-compliance-docs` (`source/walkthrough.rst`).

View file

@ -18,76 +18,171 @@
"name": "verae.sm.send", "name": "verae.sm.send",
"pattern": "core", "pattern": "core",
"for": "Deliver a passthrough secure message to a mailbox identity", "for": "Deliver a passthrough secure message to a mailbox identity",
"from": ["console", "go-leaf", "access-api"], "from": [
"to": ["sm-leaf", "npe sidecar"], "console",
"go-leaf",
"access-api"
],
"to": [
"sm-leaf",
"npe sidecar"
],
"in": { "in": {
"header": ["to", "from_lookup_id", "alg", "error_token"], "header": [
"to",
"from_lookup_id",
"alg",
"error_token"
],
"body": "ciphertext (not readable by broker or sender after send)" "body": "ciphertext (not readable by broker or sender after send)"
}, },
"out": {"ack": {"lookup_id": "string", "accepted": true}}, "out": {
"ack": {
"lookup_id": "string",
"accepted": true
}
},
"encryption": "passthrough-full-body", "encryption": "passthrough-full-body",
"reject": ["missing to", "unsigned config", "alg not in signed config", "empty ciphertext when mode!=plain-lab"], "reject": [
"dead": "verae.sm.dead" "missing to",
"unsigned config",
"alg not in signed config",
"empty ciphertext when mode!=plain-lab"
],
"dead": "verae.sm.dead",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
}, },
{ {
"name": "verae.sm.dead", "name": "verae.sm.dead",
"pattern": "core", "pattern": "core",
"for": "Dead-letter failed service requests", "for": "Dead-letter failed service requests",
"from": ["sm-leaf"], "from": [
"to": ["error-handler"], "sm-leaf"
"in": {"header": ["error_code", "lookup_id", "to"], "body": "Network Error Bundle"}, ],
"to": [
"error-handler"
],
"in": {
"header": [
"error_code",
"lookup_id",
"to"
],
"body": "Network Error Bundle"
},
"out": "none", "out": "none",
"encryption": "system-key bundle plus sender-only status", "encryption": "system-key bundle plus sender-only status",
"reject": ["bundle missing ct_system"], "reject": [
"dead": "none" "bundle missing ct_system"
],
"dead": "none",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
}, },
{ {
"name": "verae.sm.error", "name": "verae.sm.error",
"pattern": "core", "pattern": "core",
"for": "Build and emit a Network Error Bundle", "for": "Build and emit a Network Error Bundle",
"from": ["sm-leaf", "pfc-admin"], "from": [
"to": ["sender (ct_sender)", "system logger (ct_system)"], "sm-leaf",
"in": {"error_code": "string", "lookup_id": "string", "dest_class": "mailbox|service"}, "pfc-admin"
"out": {"ct_sender": "box to sender", "ct_system": "box to system public key"}, ],
"to": [
"sender (ct_sender)",
"system logger (ct_system)"
],
"in": {
"error_code": "string",
"lookup_id": "string",
"dest_class": "mailbox|service"
},
"out": {
"ct_sender": "box to sender",
"ct_system": "box to system public key"
},
"encryption": "no recipient payload; bounce metadata only", "encryption": "no recipient payload; bounce metadata only",
"reject": ["unknown error_code"], "reject": [
"dead": "verae.sm.log.summary" "unknown error_code"
],
"dead": "verae.sm.log.summary",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
}, },
{ {
"name": "verae.sm.log.summary", "name": "verae.sm.log.summary",
"pattern": "core", "pattern": "core",
"for": "Central log summaries of system failures (no message bodies)", "for": "Central log summaries of system failures (no message bodies)",
"from": ["sm-leaf", "pfc-admin"], "from": [
"to": ["central-log"], "sm-leaf",
"in": {"code": "string", "lookup_id": "string", "dest_class": "string"}, "pfc-admin"
],
"to": [
"central-log"
],
"in": {
"code": "string",
"lookup_id": "string",
"dest_class": "string"
},
"out": "ack", "out": "ack",
"encryption": "summary plaintext allowed; never ciphertext of mail", "encryption": "summary plaintext allowed; never ciphertext of mail",
"reject": ["body-like fields present"], "reject": [
"dead": "none" "body-like fields present"
],
"dead": "none",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
}, },
{ {
"name": "verae.admin.config.sign", "name": "verae.admin.config.sign",
"pattern": "core", "pattern": "core",
"for": "Sign a new configuration payload; reject unsigned files at load", "for": "Sign a new configuration payload; reject unsigned files at load",
"from": ["pfc-console", "pfc-config TUI"], "from": [
"to": ["admin-history cube"], "pfc-console",
"in": {"payload": "object", "prev_signed": "object|null"}, "pfc-config TUI"
],
"to": [
"admin-history cube"
],
"in": {
"payload": "object",
"prev_signed": "object|null"
},
"out": "signed wrapper", "out": "signed wrapper",
"encryption": "Ed25519 signature; payload may be lab-clear", "encryption": "Ed25519 signature; payload may be lab-clear",
"reject": ["bad key_id", "canonical JSON mismatch"], "reject": [
"dead": "verae.sm.dead" "bad key_id",
"canonical JSON mismatch"
],
"dead": "verae.sm.dead",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
}, },
{ {
"name": "verae.admin.history.append", "name": "verae.admin.history.append",
"pattern": "core", "pattern": "core",
"for": "Append prev file, new file, and unified diff to DataCube admin-history", "for": "Append prev file, new file, and unified diff to DataCube admin-history",
"from": ["verae.admin.config.sign"], "from": [
"to": ["pfc CubeStore kind=admin-history"], "verae.admin.config.sign"
"in": {"prev": "string", "new": "string", "diff": "string", "actor": "string"}, ],
"to": [
"pfc CubeStore kind=admin-history"
],
"in": {
"prev": "string",
"new": "string",
"diff": "string",
"actor": "string"
},
"out": "chain row", "out": "chain row",
"encryption": "chain hashes; not NPE (admin audit)", "encryption": "chain hashes; not NPE (admin audit)",
"reject": ["empty actor"], "reject": [
"dead": "none" "empty actor"
],
"dead": "none",
"timeout_sec": 5.0,
"filter": "passthrough dest/subject clear; reject missing to, empty ct, plaintext body"
} }
] ]
} }

File diff suppressed because it is too large Load diff

View file

@ -20,7 +20,9 @@
"out": {}, "out": {},
"encryption": {"type": "string"}, "encryption": {"type": "string"},
"reject": {"type": "array", "items": {"type": "string"}}, "reject": {"type": "array", "items": {"type": "string"}},
"dead": {"type": "string"} "dead": {"type": "string"},
"timeout_sec": {"type": "number"},
"filter": {"type": "string"}
} }
} }
} }

66
scripts/import_pfc_subjects.py Normal file → Executable file
View file

@ -1,5 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Merge peergos-for-compliance subjects.json into catalog/pfc-derived.json.""" """Merge peergos-for-compliance subjects.json into catalog/pfc-derived.json.
Each row has from/to/in/out/encryption/reject/dead/timeout/filter.
"""
from __future__ import annotations from __future__ import annotations
@ -10,23 +13,66 @@ ROOT = Path(__file__).resolve().parents[1]
PFC = Path("/Users/marchon/research/peergos-for-compliance/schemas/subjects.json") PFC = Path("/Users/marchon/research/peergos-for-compliance/schemas/subjects.json")
OUT = ROOT / "catalog" / "pfc-derived.json" OUT = ROOT / "catalog" / "pfc-derived.json"
TIMEOUT = {
"request-reply": 5.0,
"queue": 4.0,
"pub": 0.0,
"core": 5.0,
}
FOR = {
"verae.sm.send": "Deliver a passthrough secure message (dest in the clear, body ciphertext)",
"verae.sm.dead": "Dead-letter failed service requests",
"verae.sm.error": "Emit a Network Error Bundle (ct_sender + ct_system)",
"verae.sm.log.summary": "Central log summaries (codes only, never ciphertext)",
"verae.admin.config.sign": "Sign a configuration payload (Ed25519 wrapper)",
"verae.admin.history.append": "Append prev + new + unified diff to admin-history cube",
"verae.storage.pin": "Pin object bytes via IPFS pin API / Kubo localhost",
"verae.storage.replicate": "Replicate bytes to min_ok replica ingest subjects",
"verae.pfc.health": "Loopback health for PFC services",
"verae.inspect.open": "Start k-of-n inspect; log-before-reveal",
}
def timeout_for(pattern: str, name: str) -> float:
if name.startswith("verae.storage.pin"):
return 30.0
return TIMEOUT.get(pattern or "request-reply", 5.0)
def filter_for(name: str) -> str:
if name.startswith("verae.sm."):
return "passthrough dest/subject clear; reject missing to, empty ct, plaintext body, body-like log fields"
if name.startswith("verae.inspect."):
return "k-of-n officers; author cannot be officer; TOTP session; log-before-reveal"
if name.startswith("verae.admin."):
return "unsigned wrappers rejected; empty actor rejected"
if name.startswith("verae.storage."):
return "Kubo localhost only; no WAN 5001; hash must match bytes"
return "unknown subject rejected; required payload fields; no verae.llm.turn.>; no plaintext PHI"
def main() -> None: def main() -> None:
src = json.loads(PFC.read_text()) src = json.loads(PFC.read_text())
rows = [] rows = []
for s in src.get("subjects") or []: for s in src.get("subjects") or []:
name = s["name"]
pattern = s.get("pattern") or "request-reply"
owner = s.get("owner") or "unknown"
rows.append( rows.append(
{ {
"name": s["name"], "name": name,
"pattern": s.get("pattern"), "pattern": pattern,
"for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", "for": FOR.get(name, "PFC/Verae subject — see peergos-for-compliance/docs/nats-addresses.md"),
"from": ["pfc services", "connectors"], "from": ["pfc-py-admin", "sm-leaf", "connectors", "pfc-repl", "pfc-ipfs"],
"to": [s.get("owner") or "unknown"], "to": [owner],
"in": {"fields": s.get("payload") or []}, "in": {"fields": s.get("payload") or []},
"out": "service-specific", "out": "ack or service JSON (never recipient mail plaintext on error subjects)",
"encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", "encryption": "passthrough dest-in-clear; body pfc-lab-xor or NPE; Pattern A apps never publish",
"reject": ["unknown subject", "missing required fields"], "reject": ["unknown subject", "missing required fields", "plaintext PHI", "verae.llm.turn.>"],
"dead": "none", "dead": "verae.sm.dead" if name.startswith("verae.sm.") else "none",
"timeout_sec": timeout_for(pattern, name),
"filter": filter_for(name),
"git": "https://git.georgelambert.org/marchon/peergos-for-compliance", "git": "https://git.georgelambert.org/marchon/peergos-for-compliance",
} }
) )

View file

@ -15,3 +15,11 @@ Secure-messaging subjects
* ``verae.sm.log.summary`` -- central summaries (codes, lookup_id, dest_class). * ``verae.sm.log.summary`` -- central summaries (codes, lookup_id, dest_class).
* ``verae.admin.config.sign`` -- Ed25519 wrap; unsigned files rejected. * ``verae.admin.config.sign`` -- Ed25519 wrap; unsigned files rejected.
* ``verae.admin.history.append`` -- prev, new, unified diff on DataCube chain. * ``verae.admin.history.append`` -- prev, new, unified diff on DataCube chain.
Timeouts and filters
--------------------
Each derived row in ``catalog/pfc-derived.json`` has ``timeout_sec`` and
``filter``. Request-reply defaults to 5s, replica ingest 4s, pin 30s.
SM send rejects missing ``to``, empty ciphertext (unless ``plain-lab``),
plaintext ``body``, and summary records that contain ``ct``.