{
 "tasks": [
  {
   "artifact_sha": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9289854,
   "depends": [],
   "dispatched_at": 1794629696.006325,
   "error": null,
   "exclude_field": null,
   "exclude_worker": null,
   "field": "analysis",
   "finished_at": 1794629696.0196013,
   "idem_key": "288157dc0b45ff2f91e8c0d7e35f7edd36638cc71b3cbf8cd4c87ca6ccc10eba",
   "kind": "EXECUTE",
   "lease_until": 1794629816.006325,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "p4c121_data",
   "operation": "summarize_csv",
   "output_digest": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
   "params": {
    "text": "sepal_length,sepal_width,petal_length,petal_width,species\r\n6.6,3.0,4.4,1.4,versicolor\r\n5.6,3.0,4.5,1.5,versicolor\r\n5.9,3.2,4.8,1.8,versicolor\r\n4.7,3.2,1.6,0.2,setosa\r\n6.4,3.2,4.5,1.5,versicolor\r\n5.2,2.7,3.9,1.4,versicolor\r\n6.3,3.3,4.7,1.6,versicolor\r\n7.2,3.6,6.1,2.5,virginica\r\n5.0,3.4,1.6,0.4,setosa\r\n5.1,3.8,1.5,0.3,setosa\r\n6.3,3.3,6.0,2.5,virginica\r\n6.6,3.0,4.4,1.4,versicolor\r\n5.1,3.4,1.5,0.2,setosa\r\n7.2,3.2,6.0,1.8,virginica\r\n5.1,3.5,1.4,0.2,setosa\r\n5.5,4.2,1.4,0.2,setosa\r\n4.6,3.4,1.4,0.3,setosa\r\n5.6,2.8,4.9,2.0,virginica\r\n6.9,3.1,4.9,1.5,versicolor\r\n4.9,3.6,1.4,0.1,setosa\r\n6.9,3.1,4.9,1.5,versicolor\r\n6.8,2.8,4.8,1.4,versicolor\r\n5.2,3.5,1.5,0.2,setosa\r\n5.0,2.0,3.5,1.0,versicolor\r\n5.9,3.0,5.1,1.8,virginica\r\n5.4,3.7,1.5,0.2,setosa\r\n6.7,3.1,5.6,2.4,virginica\r\n5.7,2.5,5.0,2.0,virginica\r\n4.8,3.4,1.9,0.2,setosa\r\n6.0,2.9,4.5,1.5,versicolor\r\n4.8,3.0,1.4,0.1,setosa\r\n5.8,2.6,4.0,1.2,versicolor\r\n6.1,2.6,5.6,1.4,virginica\r\n5.4,3.9,1.3,0.4,setosa\r\n4.9,3.0,1.4,0.2,setosa\r\n5.4,3.4,1.7,0.2,setosa\r\n6.3,2.9,5.6,1.8,virginica\r\n6.1,2.8,4.0,1.3,versicolor\r\n6.7,3.1,4.7,1.5,versicolor\r\n5.4,3.4,1.5,0.4,setosa\r\n"
   },
   "parent_task": null,
   "result": {
    "artifact_len": 344,
    "artifact_sha256": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.0161123,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.0133035,
    "task_id": "p4c121_data",
    "ticket_id": "tkt-6774a21fd2119ea4",
    "worker_id": "w-f3790e47dd"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "p4c121_data",
   "ticket_id": "tkt-6774a21fd2119ea4",
   "timeout_s": 120.0,
   "updated_at": 1794629696.019615,
   "verification": {
    "method": "recompute",
    "verification_id": "ver-17d54d5cb6",
    "verified": true
   },
   "verify_of": null,
   "worker_id": "w-f3790e47dd"
  },
  {
   "artifact_sha": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9289854,
   "depends": [],
   "dispatched_at": 1794629696.0101192,
   "error": null,
   "exclude_field": null,
   "exclude_worker": null,
   "field": "analysis",
   "finished_at": 1794629696.0231915,
   "idem_key": "ef62197571f437581ce6fb864740af35e8111a7aec5a2e2a6f9c5afde89c92e6",
   "kind": "EXECUTE",
   "lease_until": 1794629816.0101192,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "p4c121_infra",
   "operation": "scan_text",
   "output_digest": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
   "params": {
    "patterns": [
     "cpu_percent",
     "memory_percent",
     "disk_percent"
    ],
    "text": "{\"cpu_percent\": 95.7, \"cycle\": 121, \"disk_percent\": 50.5, \"load_1m\": 18.27978515625, \"memory_percent\": 84.2}"
   },
   "parent_task": null,
   "result": {
    "artifact_len": 203,
    "artifact_sha256": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.0174007,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.0134063,
    "task_id": "p4c121_infra",
    "ticket_id": "tkt-c0590b898af599eb",
    "worker_id": "w-50989dadb7"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "p4c121_infra",
   "ticket_id": "tkt-c0590b898af599eb",
   "timeout_s": 120.0,
   "updated_at": 1794629696.0232012,
   "verification": {
    "method": "recompute",
    "verification_id": "ver-9dad6fe53a",
    "verified": true
   },
   "verify_of": null,
   "worker_id": "w-50989dadb7"
  },
  {
   "artifact_sha": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9289854,
   "depends": [],
   "dispatched_at": 1794629695.9788308,
   "error": null,
   "exclude_field": null,
   "exclude_worker": null,
   "field": "analysis",
   "finished_at": 1794629695.9936466,
   "idem_key": "6e3f9c7e091ee84d194bb4386db1ea071fe5b5fd8f8d17540a9dbdf30a768664",
   "kind": "EXECUTE",
   "lease_until": 1794629815.9788308,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "p4c121_literature",
   "operation": "extract_entities",
   "output_digest": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
   "params": {
    "text": "AgentProofBench: Benchmarking Reusable Verifiers for Web Agents\nReusable Web-agent verification requires a rule to follow changing requirements and support subsequent execution. We introduce AgentProofBench, which connects paired tests of a frozen acceptance rule to execution from identical saved openings. The resource spans 97 tasks, 79 families, and four Web services. Experiments with DeepSeek Flash/Pro establish two linked measurements. Across 48 families, complete-panel and decision-replay tests retain 82/96 Flash and 79/96 Pro source programs; paired reuse-rebuild BA intervals are [-5.47, 1.57] and [-10.16, 0.00] percentage points. Across 22 execution families, deployment-state panel correctness separates program assignments whose two saved openings are both delivered correctly: 32/33 assignments with error-free panels, versus 1/11 with panel errors. All reference-defined program-gate regressions and withheld deliveries occur in the latter group. Neutral continuation attains the highest correct delivery under the tested generic feedback, providing a concrete baseline for measuring the value added by a gate. Released instructions, states, programs, reference rules, and trajectories connect each test failure to its execution consequences. AgentProofBench makes reusable verification assessable at both the requirement and policy levels."
   },
   "parent_task": null,
   "result": {
    "artifact_len": 253,
    "artifact_sha256": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629695.9918354,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629695.9854882,
    "task_id": "p4c121_literature",
    "ticket_id": "tkt-ae8aa68ce68edc97",
    "worker_id": "w-2a94b558b9"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "p4c121_literature",
   "ticket_id": "tkt-ae8aa68ce68edc97",
   "timeout_s": 120.0,
   "updated_at": 1794629695.9936562,
   "verification": {
    "method": "recompute",
    "verification_id": "ver-65d82388f6",
    "verified": true
   },
   "verify_of": null,
   "worker_id": "w-2a94b558b9"
  },
  {
   "artifact_sha": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9289854,
   "depends": [],
   "dispatched_at": 1794629695.9815118,
   "error": null,
   "exclude_field": null,
   "exclude_worker": null,
   "field": "analysis",
   "finished_at": 1794629695.996602,
   "idem_key": "99f693392e3fe9697e42d016a1b91c8f586f2903f9486b92a9230d80e47ae1a5",
   "kind": "EXECUTE",
   "lease_until": 1794629815.9815118,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "p4c121_security",
   "operation": "scan_text",
   "output_digest": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
   "params": {
    "patterns": [
     "except\\s+Exception:\\s*pass",
     "shell\\s*=\\s*True",
     "eval\\(",
     "pickle\\.loads",
     "verify\\s*=\\s*False"
    ],
    "text": "\"\"\"Durable authority: issuer registry, worker credentials, attenuated grants, per-operation tickets, revocation.\n\nThis is the only component that can create authority. Its private keys live in a 0600 keyring file that is never\nsent to a node or worker. Everything it issues is persisted, so a coordinator restart loses no authorization\nstate (grants, usage counters, replay set, revocations).\n\nGrants are byte-compatible with `cain.aos.childauth.ChildGrant` (same fields, same signature domain), so E66/E67\ncode and verifiers accept them. Additions in E68:\n\n  * issuer registry: a host is admitted only if its public key was pinned by an operator beforehand;\n  * worker identity credential: binds a worker id to the key the worker generated, the host and the role;\n  * per-operation ticket: a short-lived signature over exactly one operation for one worker;\n  * key rotation with a signed hand-over, and revocation of hosts, workers, grants and keys.\n\nOutcomes other than ALLOW are never executable. Any exception while deciding is recorded as ERROR (not ALLOW).\n\"\"\"\nfrom __future__ import annotations\n\nimport json\nimport os\nimport time\nfrom typing import Any, Dict, List, Mapping, Optional, Sequence\n\nfrom . import canon as C\nfrom .store import Store\n\nALLOW, DENY, EXPIRED, REVOKED, UNKNOWN, ERROR = \"ALLOW\", \"DENY\", \"EXPIRED\", \"REVOKED\", \"UNKNOWN\", \"ERROR\"\n\n\nclass AuthorityError(PermissionError):\n    pass\n\n\nclass Keyring:\n    \"\"\"Signing keys with rotation. File mode 0600. `active` signs; retired keys still verify; revoked never do.\"\"\"\n\n    def __init__(self, path: str):\n        self.path = path\n        if os.path.exists(path):\n            self.data = json.loads(open(path, encoding=\"utf-8\").read())\n        else:\n            self.data = {\"keys\": {}, \"active\": None}\n            self.rotate(save_only=True)\n\n    def _save(self) -> None:\n        tmp = self.path + \".tmp\"\n        fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as f:\n            json.dump(self.data, f, sort_keys=True)\n            f.flush()\n            os.fsync(f.fileno())\n        os.replace(tmp, self.path)\n\n    def rotate(self, save_only: bool = False) -> Dict[str, Any]:\n        old = self.data.get(\"active\")\n        key = C.new_key()\n        pub = C.pub_b64(key)\n        kid = C.key_id(pub)\n        self.data[\"keys\"][kid] = {\"priv\": C.priv_b64(key), \"pub\": pub, \"state\": \"ACTIVE\", \"created_at\": time.time()}\n        handover = None\n        if old and not save_only:\n            body = {\"new_kid\": kid, \"new_pub\": pub, \"old_kid\": old, \"at\": time.time()}\n            handover = {\"body\": body, \"sig\": C.sign(self.key(old), C.D_ROTATE, body), \"kid\": old}\n            self.data[\"keys\"][old][\"state\"] = \"RETIRED\"\n        self.data[\"active\"] = kid\n        self._save()\n        return {\"kid\": kid, \"pub\": pub, \"handover\": handover}\n\n    def revoke(self, kid: str) -> None:\n        if kid == self.data[\"active\"]:\n            raise AuthorityError(\"rotate before revoking the active key\")\n        self.data[\"keys\"][kid][\"state\"] = \"REVOKED\"\n        self.data[\"keys\"][kid][\"priv\"] = \"\"\n        self._save()\n\n    @property\n    def active(self) -> str:\n        return self.data[\"active\"]\n\n    def key(self, kid: Optional[str] = None):\n        k = self.data[\"keys\"][kid or self.active]\n        if not k[\"priv\"]:\n            raise AuthorityError(\"key revoked\")\n        return C.load_priv(k[\"priv\"])\n\n    def pub(self, kid: Optional[str] = None) -> str:\n        return self.data[\"keys\"][kid or self.active][\"pub\"]\n\n    def trusted_pubs(self) -> Dict[str, str]:\n        return {kid: k[\"pub\"] for kid, k in self.data[\"keys\"].items() if k[\"state\"] != \"REVOKED\"}\n\n    def public_view(self) -> Dict[str, Any]:\n        return {\"active\": self.active,\n                \"keys\": {kid: {\"pub\": k[\"pub\"], \"state\": k[\"state\"], \"created_at\": k[\"created_at\"]}\n                         for kid, k in self.data[\"keys\"].items()}}\n\n\nclass Authority:\n    def __init__(self, store: Store, keyring: Keyring, *, ticket_ttl_s: float = 60.0, grant_ttl_s: float = 900.0,\n                 max_depth: int = 3):\n        self.s = store\n        self.kr = keyring\n        self.ticket_ttl_s = float(ticket_ttl_s)\n        self.grant_ttl_s = float(grant_ttl_s)\n        self.max_depth = int(max_depth)\n        self._revoked = {r[\"subject\"] for r in store.q(\"SELECT subject FROM revocations\")}\n\n    # ------------------------------------------------------------------ issuer registry (hosts)\n    def enroll_host(self, host_id: str, pub: str, *, slots: int, operator: str, info: Optional[Mapping] = None) -> None:\n        \"\"\"Operator action: pin a host's public key. A host that is not pinned cannot join, whatever it presents.\"\"\"\n        if not operator:\n            raise AuthorityError(\"host enrollment needs a named operator\")\n        self.s.x(\"INSERT INTO hosts(host_id,pub,state,slots,enrolled_at,info) VALUES(?,?,?,?,?,?) \"\n                 \"ON CONFLICT(host_id) DO UPDATE SET pub=excluded.pub, slots=excluded.slots, state='ENROLLED', \"\n                 \"info=excluded.info\",\n                 (host_id, pub, \"ENROLLED\", int(slots), time.time(), json.dumps(dict(info or {}))))\n        self._revoked.discard(host_id)\n        self.s.x(\"DELETE FROM revocations WHERE subject=?\", (host_id,))\n        self.s.event(\"HOST_ENROLLED\", actor=operator, body={\"host_id\": host_id, \"kid\": C.key_id(pub), \"slots\": slots})\n\n    def host_pub(self, host_id: str) -> Optional[str]:\n        r = self.s.one(\"SELECT pub,state FROM hosts WHERE host_id=?\", (host_id,))\n        if r is None or r[\"state\"] == \"REVOKED\" or host_id in self._revoked:\n            return None\n        return r[\"pub\"]\n\n    # ------------------------------------------------------------------ revocation\n    def revoke(self, subject: str, *, kind: str, reason: str, actor: str = \"operator\") -> None:\n        self._revoked.add(subject)\n        self.s.x(\"INSERT OR REPLACE INTO revocations(subject,kind,at,reason) VALUES(?,?,?,?)\",\n                 (subject, kind, time.time(), reason))\n        if kind == \"host\":\n            self.s.x(\"UPDATE hosts SET state='REVOKED' WHERE host_id=?\", (subject,))\n        if kind == \"worker\":\n            self.s.x(\"UPDATE workers SET state='REVOKED', ended_at=?, end_reason=? WHERE worker_id=? \"\n                     \"AND state NOT IN ('DEAD','RETIRED')\", (time.time(), \"revoked:\" + reason, subject))\n        self.s.event(\"REVOKED\", actor=actor, body={\"subject\": subject, \"kind\": kind, \"reason\": reason})\n\n    def is_revoked(self, subject: str) -> bool:\n        return subject in self._revoked\n\n    # ------------------------------------------------------------------ worker credential\n    def issue_credential(self, *, worker_id: str, pub: str, host_id: str, role: str, mission_id: str,\n                         ttl_s: float = 86400.0) -> Dict[str, Any]:\n        now = time.time()\n        body = {\"worker_id\": worker_id, \"pub\": pub, \"host_id\": host_id, \"role\": role, \"mission_id\": mission_id,\n                \"issued_at\": now, \"expires_at\": now + ttl_s, \"cred_id\": C.rid(\"cred\")}\n        return {\"body\": body, \"sig\": C.sign(self.kr.key(), C.D_CRED, body), \"kid\": self.kr.active}\n\n    # ------------------------------------------------------------------ grants\n    def issue_grant(self, *, mission_id: str, child_id: str, parent_id: str, capabilities: Sequence[str],\n                    side_effects: Sequence[str], max_ops: int, ttl_s: Optional[float] = None, depth: int = 1,\n                    parent_grant: Optional[Mapping[str, Any]] = None, now: Optional[float] = None) -> Dict[str, Any]:\n        if not child_id or child_id == parent_id:\n            raise AuthorityError(\"child must have its own identity\")\n        if max_ops <= 0:\n            raise AuthorityError(\"max_ops must be positive\")\n        now = time.time() if now is None else float(now)\n        caps = list(dict.fromkeys(str(c).upper() for c in capabilities))\n        sides = list(dict.fromkeys(str(x) for x in side_effects))\n        expires = now + float(self.grant_ttl_s if ttl_s is None else ttl_s)\n        parent_digest = parent_id_grant = None\n        if parent_grant is not None:\n            v = self.verify_grant(parent_grant, now=now, check_ops=False)\n            if not v[\"ok\"]:\n                raise AuthorityError(\"parent grant invalid: \" + \",\".join(v[\"reasons\"]))\n            if parent_grant[\"mission_id\"] != mission_id:\n                raise AuthorityError(\"parent grant is for another mission\")\n            if \"DELEGATE\" not in parent_grant[\"capabilities\"]:\n                raise AuthorityError(\"parent may not delegate\")\n            if not set(caps) <= set(parent_grant[\"capabilities\"]):\n                raise AuthorityError(\"capability expansion refused\")\n            if not set(sides) <= set(parent_grant[\"side_effects\"]):\n                raise AuthorityError(\"side-effect expansion refused\")\n            remaining = int(parent_grant[\"max_ops\"]) - self.ops_used(parent_grant[\"grant_id\"])\n            if max_ops > remaining:\n                raise AuthorityError(\"operation budget expansion refused\")\n            depth = int(parent_grant[\"depth\"]) + 1\n            expires = min(expires, float(parent_grant[\"expires_at\"]))\n            parent_digest = C.sha(_signing_body(parent_grant))\n            parent_id_grant = parent_grant[\"grant_id\"]\n        if depth > self.max_depth:\n            raise AuthorityError(\"delegation depth limit\")\n        g = {\"grant_id\": C.rid(\"grant\", 6), \"mission_id\": mission_id, \"child_id\": str(child_id),\n             \"parent_id\": str(parent_id), \"parent_grant_digest\": parent_digest, \"capabilities\": caps,\n             \"side_effects\": sides, \"max_ops\": int(max_ops), \"ops_used\": 0, \"depth\": int(depth),\n             \"issued_at\": now, \"expires_at\": expires, \"parent_pub\": self.kr.pub(),\n             \"parent_grant_id\": parent_id_grant}\n        g[\"signature\"] = C.sign(self.kr.key(), C.D_GRANT, _signing_body(g))\n        self.s.x(\"INSERT INTO grants(grant_id,mission_id,child_id,parent_id,body,ops_used,issued_at,expires_at) \"\n                 \"VALUES(?,?,?,?,?,?,?,?)\",\n                 (g[\"grant_id\"], mission_id, child_id, parent_id, json.dumps(g, sort_keys=True), 0, now, expires))\n        self.s.event(\"GRANT_ISSUED\", mission_id=mission_id,\n                     body={\"grant_id\": g[\"grant_id\"], \"child\": child_id, \"parent\": parent_id, \"capabilities\": caps,\n                           \"side_effects\": sides, \"max_ops\": max_ops, \"depth\": depth, \"expires_at\": expires})\n        return g\n\n    def renew_grant(self, grant: Mapping[str, Any]) -> Dict[str, Any]:\n        \"\"\"Continuous authorization: a fresh short-lived grant with the remaining budget, only if still in standing.\n\n        The worker never renews itself; the coordinator calls this after re-checking mission and revocation state.\n        \"\"\"\n        v = self.verify_grant(grant, check_ops=True)\n        if not v[\"ok\"]:\n            raise AuthorityError(\"renewal refused: \" + \",\".join(v[\"reasons\"]))\n        used = self.ops_used(grant[\"grant_id\"])\n        parent = None\n        if grant.get(\"parent_grant_id\"):\n            parent = self.grant(grant[\"parent_grant_id\"])\n        g = self.issue_grant(mission_id=grant[\"mission_id\"], child_id=grant[\"child_id\"], parent_id=grant[\"parent_id\"],\n                             capabilities=grant[\"capabilities\"], side_effects=grant[\"side_effects\"],\n                             max_ops=int(grant[\"max_ops\"]) - used, depth=int(grant[\"depth\"]),\n                             parent_grant=parent) if parent else self.issue_grant(\n            mission_id=grant[\"mission_id\"], child_id=grant[\"child_id\"], parent_id=grant[\"parent_id\"],\n            capabilities=grant[\"capabilities\"], side_effects=grant[\"side_effects\"],\n            max_ops=int(grant[\"max_ops\"]) - used, depth=int(grant[\"depth\"]))\n        self.s.x(\"UPDATE grants SET superseded_by=? WHERE grant_id=?\", (g[\"grant_id\"], grant[\"grant_id\"]))\n        return g\n\n    def grant(self, grant_id: str) -> Optional[Dict[str, Any]]:\n        r = self.s.one(\"SELECT body FROM grants WHERE grant_id=?\", (grant_id,))\n        return json.loads(r[\"body\"]) if r else None\n\n    def ops_used(self, grant_id: str) -> int:\n        r = self.s.one(\"SELECT ops_used FROM grants WHERE grant_id=?\", (grant_id,))\n        return int(r[\"ops_used\"]) if r else 0\n\n    def verify_grant(self, g: Mapping[str, Any], *, now: Optional[float] = None, check_ops: bool = True) -> Dict[str, Any]:\n        now = time.time() if now is None else float(now)\n        reasons: List[str] = []\n        row = self.s.one(\"SELECT ops_used, superseded_by FROM grants WHERE grant_id=?\", (g.get(\"grant_id\"),))\n        if row is None:\n            reasons.append(\"UNKNOWN_GRANT\")                     # a grant we did not issue is never honoured\n        elif row[\"superseded_by\"]:\n            reasons.append(\"SUPERSEDED\")\n        if any(self.is_revoked(x) for x in (g.get(\"child_id\"), g.get(\"parent_id\"), g.get(\"grant_id\"),\n                                           g.get(\"mission_id\"))):\n            reasons.append(\"REVOKED\")\n        pubs = self.kr.trusted_pubs().values()\n        if g.get(\"parent_pub\") not in pubs or not C.verify(g.get(\"parent_pub\", \"\"), g.get(\"signature\", \"\"),\n                                                           C.D_GRANT, _signing_body(g)):\n            reasons.append(\"BAD_SIGNATURE\")\n        if now > float(g.get(\"expires_at\", 0)):\n            reasons.append(\"EXPIRED\")\n        if check_ops and row is not None and int(row[\"ops_used\"]) >= int(g.get(\"max_ops\", 0)):\n            reasons.append(\"OP_BUDGET_EXHAUSTED\")\n        return {\"ok\": not reasons, \"reasons\": reasons}\n\n    # ------------------------------------------------------------------ per-operation authorization\n    def authorize(self, *, grant: Mapping[str, Any], worker_id: str, task_id: str, attempt: int, operation: str,\n                  capability: str, side_effect: str, params: Mapping[str, Any], mission_state: str,\n                  host_ok: bool = True, cred_ok: bool = True, now: Optional[float] = None,\n                  mission_id: Optional[str] = None) -> Dict[str, Any]:\n        \"\"\"Decide one operation. Returns a decision dict; `ticket` is present only when the outcome is ALLOW.\"\"\"\n        now = time.time() if now is None else float(now)\n        cap = str(capability).upper()\n        params_digest = C.sha(dict(params))\n        op_digest = C.sha({\"task\": task_id, \"attempt\": attempt, \"operation\": operation, \"capability\": cap,\n                           \"side_effect\": side_effect, \"params\": params_digest, \"worker\": worker_id})\n        reasons: List[str] = []\n        outcome = ERROR\n        try:\n            v = self.verify_grant(grant, now=now)\n            reasons += v[\"reasons\"]\n            if grant.get(\"child_id\") != worker_id:\n                reasons.append(\"GRANT_NOT_FOR_WORKER\")\n            if mission_id and grant.get(\"mission_id\") != mission_id:\n                reasons.append(\"GRANT_MISSION_MISMATCH\")\n            if mission_state != \"RUNNING\":\n                reasons.append(\"MISSION_NOT_RUNNING:\" + str(mission_state))\n            if not host_ok:\n                reasons.append(\"HOST_NOT_TRUSTED\")\n            if not cred_ok:\n                reasons.append(\"CREDENTIAL_INVALID\")\n            if cap not in grant.get(\"capabilities\", []):\n                reasons.append(\"CAPABILITY_NOT_GRANTED\")\n            if side_effect not in grant.get(\"side_effects\", []):\n                reasons.append(\"SIDE_EFFECT_NOT_GRANTED\")\n            nonce = f\"{grant.get('grant_id')}:{op_digest}\"\n            if self.s.one(\"SELECT 1 FROM replay WHERE nonce=?\", (nonce,)):\n                reasons.append(\"REPLAY\")\n            if \"REVOKED\" in reasons:\n                outcome = REVOKED\n            elif \"EXPIRED\" in reasons:\n                outcome = EXPIRED\n            elif \"UNKNOWN_GRANT\" in reasons:\n                outcome = UNKNOWN\n            elif reasons:\n                outcome = DENY\n            else:\n                outcome = ALLOW\n        except Exception as e:  # noqa: BLE001  -- a fault while deciding is never an ALLOW\n            reasons.append(f\"DECISION_FAULT:{type(e).__name__}\")\n            outcome = ERROR\n        decision_id = C.rid(\"dec\", 6)\n        self.s.x(\"INSERT INTO decisions(decision_id,at,mission_id,worker_id,task_id,kind,outcome,reasons,op_digest) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?)\",\n                 (decision_id, now, grant.get(\"mission_id\"), worker_id, task_id, \"OPERATION\", outcome,\n                  json.dumps(reasons), op_digest))\n        out: Dict[str, Any] = {\"decision_id\": decision_id, \"outcome\": outcome, \"reasons\": reasons,\n                               \"op_digest\": op_digest, \"executable\": outcome == ALLOW}\n        if outcome != ALLOW:\n            return out\n        self.s.x(\"INSERT INTO replay(nonce,at) VALUES(?,?)\", (nonce, now))\n        self.s.x(\"UPDATE grants SET ops_used=ops_used+1 WHERE grant_id=?\", (grant[\"grant_id\"],))\n        body = {\"ticket_id\": C.rid(\"tkt\"), \"task_id\": task_id, \"attempt\": int(attempt),\n                \"mission_id\": grant[\"mission_id\"], \"worker_id\": worker_id, \"grant_id\": grant[\"grant_id\"],\n                \"operation\": operation, \"capability\": cap, \"side_effect\": side_effect,\n                \"params_digest\": params_digest, \"decision_id\": decision_id,\n                \"issued_at\": now, \"expires_at\": now + self.ticket_ttl_s}\n        sig = C.sign(self.kr.key(), C.D_TICKET, body)\n        self.s.x(\"INSERT INTO tickets(ticket_id,task_id,attempt,worker_id,body,sig,kid,issued_at,expires_at,state) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?,?)\",\n                 (body[\"ticket_id\"], task_id, attempt, worker_id, json.dumps(body, sort_keys=True), sig,\n                  self.kr.active, now, body[\"expires_at\"], \"ISSUED\"))\n        out[\"ticket\"] = {\"body\": body, \"sig\": sig, \"kid\": self.kr.active}\n        return out\n\n    def deny(self, *, mission_id: str, worker_id: str, task_id: str, kind: str, reasons: Sequence[str],\n             outcome: str = DENY) -> str:\n        \"\"\"Record a refusal that did not come through `authorize` (bad signature, forged result, ...).\"\"\"\n        decision_id = C.rid(\"dec\", 6)\n        self.s.x(\"INSERT INTO decisions(decision_id,at,mission_id,worker_id,task_id,kind,outcome,reasons,op_digest) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?)\",\n                 (decision_id, time.time(), mission_id, worker_id, task_id, kind, outcome,\n                  json.dumps(list(reasons)), \"\"))\n        return decision_id\n\n\ndef _signing_body(g: Mapping[str, Any]) -> Dict[str, Any]:\n    return {k: v for k, v in g.items() if k not in (\"signature\", \"ops_used\")}\n\n\ndef verify_grant_offline(g: Mapping[str, Any], trusted_pubs: Sequence[str], *, now: Optional[float] = None) -> List[str]:\n    \"\"\"Worker-side / verifier-side grant check with pinned authority keys only (no database).\"\"\"\n    reasons = []\n    if g.get(\"parent_pub\") not in trusted_pubs or not C.verify(g.get(\"parent_pub\", \"\"), g.get(\"signature\", \"\"),\n                                                               C.D_GRANT, _signing_body(g)):\n        reasons.append(\"BAD_SIGNATURE\")\n    if now is not None and now > float(g.get(\"expires_at\", 0)):\n        reasons.append(\"EXPIRED\")\n    return reasons\n"
   },
   "parent_task": null,
   "result": {
    "artifact_len": 25,
    "artifact_sha256": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629695.992103,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629695.9839697,
    "task_id": "p4c121_security",
    "ticket_id": "tkt-02977cbc3e31f094",
    "worker_id": "w-4661d686ce"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "p4c121_security",
   "ticket_id": "tkt-02977cbc3e31f094",
   "timeout_s": 120.0,
   "updated_at": 1794629695.9966106,
   "verification": {
    "method": "recompute",
    "verification_id": "ver-40dced5493",
    "verified": true
   },
   "verify_of": null,
   "worker_id": "w-4661d686ce"
  },
  {
   "artifact_sha": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9952824,
   "depends": [],
   "dispatched_at": 1794629696.0361788,
   "error": null,
   "exclude_field": "analysis",
   "exclude_worker": "w-2a94b558b9",
   "field": "analysis",
   "finished_at": 1794629696.0526779,
   "idem_key": "verify:p4c121_literature",
   "kind": "VERIFY",
   "lease_until": 1794629816.0361788,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "t-338179329f",
   "operation": "extract_entities",
   "output_digest": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
   "params": {
    "text": "AgentProofBench: Benchmarking Reusable Verifiers for Web Agents\nReusable Web-agent verification requires a rule to follow changing requirements and support subsequent execution. We introduce AgentProofBench, which connects paired tests of a frozen acceptance rule to execution from identical saved openings. The resource spans 97 tasks, 79 families, and four Web services. Experiments with DeepSeek Flash/Pro establish two linked measurements. Across 48 families, complete-panel and decision-replay tests retain 82/96 Flash and 79/96 Pro source programs; paired reuse-rebuild BA intervals are [-5.47, 1.57] and [-10.16, 0.00] percentage points. Across 22 execution families, deployment-state panel correctness separates program assignments whose two saved openings are both delivered correctly: 32/33 assignments with error-free panels, versus 1/11 with panel errors. All reference-defined program-gate regressions and withheld deliveries occur in the latter group. Neutral continuation attains the highest correct delivery under the tested generic feedback, providing a concrete baseline for measuring the value added by a gate. Released instructions, states, programs, reference rules, and trajectories connect each test failure to its execution consequences. AgentProofBench makes reusable verification assessable at both the requirement and policy levels."
   },
   "parent_task": "p4c121_literature",
   "result": {
    "artifact_len": 253,
    "artifact_sha256": "9f1b7b8b57d2547395dd15519a82c9005d11b02d746ee8950e0bb4eba529036d",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.0506573,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.0416553,
    "task_id": "t-338179329f",
    "ticket_id": "tkt-e91eea05106e1d02",
    "worker_id": "w-f3790e47dd"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "t-338179329f",
   "ticket_id": "tkt-e91eea05106e1d02",
   "timeout_s": 120.0,
   "updated_at": 1794629696.0526872,
   "verification": {
    "method": "none"
   },
   "verify_of": "p4c121_literature",
   "worker_id": "w-f3790e47dd"
  },
  {
   "artifact_sha": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629695.9977324,
   "depends": [],
   "dispatched_at": 1794629696.039157,
   "error": null,
   "exclude_field": "analysis",
   "exclude_worker": "w-4661d686ce",
   "field": "analysis",
   "finished_at": 1794629696.0729454,
   "idem_key": "verify:p4c121_security",
   "kind": "VERIFY",
   "lease_until": 1794629816.039157,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "t-8699e76d51",
   "operation": "scan_text",
   "output_digest": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
   "params": {
    "patterns": [
     "except\\s+Exception:\\s*pass",
     "shell\\s*=\\s*True",
     "eval\\(",
     "pickle\\.loads",
     "verify\\s*=\\s*False"
    ],
    "text": "\"\"\"Durable authority: issuer registry, worker credentials, attenuated grants, per-operation tickets, revocation.\n\nThis is the only component that can create authority. Its private keys live in a 0600 keyring file that is never\nsent to a node or worker. Everything it issues is persisted, so a coordinator restart loses no authorization\nstate (grants, usage counters, replay set, revocations).\n\nGrants are byte-compatible with `cain.aos.childauth.ChildGrant` (same fields, same signature domain), so E66/E67\ncode and verifiers accept them. Additions in E68:\n\n  * issuer registry: a host is admitted only if its public key was pinned by an operator beforehand;\n  * worker identity credential: binds a worker id to the key the worker generated, the host and the role;\n  * per-operation ticket: a short-lived signature over exactly one operation for one worker;\n  * key rotation with a signed hand-over, and revocation of hosts, workers, grants and keys.\n\nOutcomes other than ALLOW are never executable. Any exception while deciding is recorded as ERROR (not ALLOW).\n\"\"\"\nfrom __future__ import annotations\n\nimport json\nimport os\nimport time\nfrom typing import Any, Dict, List, Mapping, Optional, Sequence\n\nfrom . import canon as C\nfrom .store import Store\n\nALLOW, DENY, EXPIRED, REVOKED, UNKNOWN, ERROR = \"ALLOW\", \"DENY\", \"EXPIRED\", \"REVOKED\", \"UNKNOWN\", \"ERROR\"\n\n\nclass AuthorityError(PermissionError):\n    pass\n\n\nclass Keyring:\n    \"\"\"Signing keys with rotation. File mode 0600. `active` signs; retired keys still verify; revoked never do.\"\"\"\n\n    def __init__(self, path: str):\n        self.path = path\n        if os.path.exists(path):\n            self.data = json.loads(open(path, encoding=\"utf-8\").read())\n        else:\n            self.data = {\"keys\": {}, \"active\": None}\n            self.rotate(save_only=True)\n\n    def _save(self) -> None:\n        tmp = self.path + \".tmp\"\n        fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as f:\n            json.dump(self.data, f, sort_keys=True)\n            f.flush()\n            os.fsync(f.fileno())\n        os.replace(tmp, self.path)\n\n    def rotate(self, save_only: bool = False) -> Dict[str, Any]:\n        old = self.data.get(\"active\")\n        key = C.new_key()\n        pub = C.pub_b64(key)\n        kid = C.key_id(pub)\n        self.data[\"keys\"][kid] = {\"priv\": C.priv_b64(key), \"pub\": pub, \"state\": \"ACTIVE\", \"created_at\": time.time()}\n        handover = None\n        if old and not save_only:\n            body = {\"new_kid\": kid, \"new_pub\": pub, \"old_kid\": old, \"at\": time.time()}\n            handover = {\"body\": body, \"sig\": C.sign(self.key(old), C.D_ROTATE, body), \"kid\": old}\n            self.data[\"keys\"][old][\"state\"] = \"RETIRED\"\n        self.data[\"active\"] = kid\n        self._save()\n        return {\"kid\": kid, \"pub\": pub, \"handover\": handover}\n\n    def revoke(self, kid: str) -> None:\n        if kid == self.data[\"active\"]:\n            raise AuthorityError(\"rotate before revoking the active key\")\n        self.data[\"keys\"][kid][\"state\"] = \"REVOKED\"\n        self.data[\"keys\"][kid][\"priv\"] = \"\"\n        self._save()\n\n    @property\n    def active(self) -> str:\n        return self.data[\"active\"]\n\n    def key(self, kid: Optional[str] = None):\n        k = self.data[\"keys\"][kid or self.active]\n        if not k[\"priv\"]:\n            raise AuthorityError(\"key revoked\")\n        return C.load_priv(k[\"priv\"])\n\n    def pub(self, kid: Optional[str] = None) -> str:\n        return self.data[\"keys\"][kid or self.active][\"pub\"]\n\n    def trusted_pubs(self) -> Dict[str, str]:\n        return {kid: k[\"pub\"] for kid, k in self.data[\"keys\"].items() if k[\"state\"] != \"REVOKED\"}\n\n    def public_view(self) -> Dict[str, Any]:\n        return {\"active\": self.active,\n                \"keys\": {kid: {\"pub\": k[\"pub\"], \"state\": k[\"state\"], \"created_at\": k[\"created_at\"]}\n                         for kid, k in self.data[\"keys\"].items()}}\n\n\nclass Authority:\n    def __init__(self, store: Store, keyring: Keyring, *, ticket_ttl_s: float = 60.0, grant_ttl_s: float = 900.0,\n                 max_depth: int = 3):\n        self.s = store\n        self.kr = keyring\n        self.ticket_ttl_s = float(ticket_ttl_s)\n        self.grant_ttl_s = float(grant_ttl_s)\n        self.max_depth = int(max_depth)\n        self._revoked = {r[\"subject\"] for r in store.q(\"SELECT subject FROM revocations\")}\n\n    # ------------------------------------------------------------------ issuer registry (hosts)\n    def enroll_host(self, host_id: str, pub: str, *, slots: int, operator: str, info: Optional[Mapping] = None) -> None:\n        \"\"\"Operator action: pin a host's public key. A host that is not pinned cannot join, whatever it presents.\"\"\"\n        if not operator:\n            raise AuthorityError(\"host enrollment needs a named operator\")\n        self.s.x(\"INSERT INTO hosts(host_id,pub,state,slots,enrolled_at,info) VALUES(?,?,?,?,?,?) \"\n                 \"ON CONFLICT(host_id) DO UPDATE SET pub=excluded.pub, slots=excluded.slots, state='ENROLLED', \"\n                 \"info=excluded.info\",\n                 (host_id, pub, \"ENROLLED\", int(slots), time.time(), json.dumps(dict(info or {}))))\n        self._revoked.discard(host_id)\n        self.s.x(\"DELETE FROM revocations WHERE subject=?\", (host_id,))\n        self.s.event(\"HOST_ENROLLED\", actor=operator, body={\"host_id\": host_id, \"kid\": C.key_id(pub), \"slots\": slots})\n\n    def host_pub(self, host_id: str) -> Optional[str]:\n        r = self.s.one(\"SELECT pub,state FROM hosts WHERE host_id=?\", (host_id,))\n        if r is None or r[\"state\"] == \"REVOKED\" or host_id in self._revoked:\n            return None\n        return r[\"pub\"]\n\n    # ------------------------------------------------------------------ revocation\n    def revoke(self, subject: str, *, kind: str, reason: str, actor: str = \"operator\") -> None:\n        self._revoked.add(subject)\n        self.s.x(\"INSERT OR REPLACE INTO revocations(subject,kind,at,reason) VALUES(?,?,?,?)\",\n                 (subject, kind, time.time(), reason))\n        if kind == \"host\":\n            self.s.x(\"UPDATE hosts SET state='REVOKED' WHERE host_id=?\", (subject,))\n        if kind == \"worker\":\n            self.s.x(\"UPDATE workers SET state='REVOKED', ended_at=?, end_reason=? WHERE worker_id=? \"\n                     \"AND state NOT IN ('DEAD','RETIRED')\", (time.time(), \"revoked:\" + reason, subject))\n        self.s.event(\"REVOKED\", actor=actor, body={\"subject\": subject, \"kind\": kind, \"reason\": reason})\n\n    def is_revoked(self, subject: str) -> bool:\n        return subject in self._revoked\n\n    # ------------------------------------------------------------------ worker credential\n    def issue_credential(self, *, worker_id: str, pub: str, host_id: str, role: str, mission_id: str,\n                         ttl_s: float = 86400.0) -> Dict[str, Any]:\n        now = time.time()\n        body = {\"worker_id\": worker_id, \"pub\": pub, \"host_id\": host_id, \"role\": role, \"mission_id\": mission_id,\n                \"issued_at\": now, \"expires_at\": now + ttl_s, \"cred_id\": C.rid(\"cred\")}\n        return {\"body\": body, \"sig\": C.sign(self.kr.key(), C.D_CRED, body), \"kid\": self.kr.active}\n\n    # ------------------------------------------------------------------ grants\n    def issue_grant(self, *, mission_id: str, child_id: str, parent_id: str, capabilities: Sequence[str],\n                    side_effects: Sequence[str], max_ops: int, ttl_s: Optional[float] = None, depth: int = 1,\n                    parent_grant: Optional[Mapping[str, Any]] = None, now: Optional[float] = None) -> Dict[str, Any]:\n        if not child_id or child_id == parent_id:\n            raise AuthorityError(\"child must have its own identity\")\n        if max_ops <= 0:\n            raise AuthorityError(\"max_ops must be positive\")\n        now = time.time() if now is None else float(now)\n        caps = list(dict.fromkeys(str(c).upper() for c in capabilities))\n        sides = list(dict.fromkeys(str(x) for x in side_effects))\n        expires = now + float(self.grant_ttl_s if ttl_s is None else ttl_s)\n        parent_digest = parent_id_grant = None\n        if parent_grant is not None:\n            v = self.verify_grant(parent_grant, now=now, check_ops=False)\n            if not v[\"ok\"]:\n                raise AuthorityError(\"parent grant invalid: \" + \",\".join(v[\"reasons\"]))\n            if parent_grant[\"mission_id\"] != mission_id:\n                raise AuthorityError(\"parent grant is for another mission\")\n            if \"DELEGATE\" not in parent_grant[\"capabilities\"]:\n                raise AuthorityError(\"parent may not delegate\")\n            if not set(caps) <= set(parent_grant[\"capabilities\"]):\n                raise AuthorityError(\"capability expansion refused\")\n            if not set(sides) <= set(parent_grant[\"side_effects\"]):\n                raise AuthorityError(\"side-effect expansion refused\")\n            remaining = int(parent_grant[\"max_ops\"]) - self.ops_used(parent_grant[\"grant_id\"])\n            if max_ops > remaining:\n                raise AuthorityError(\"operation budget expansion refused\")\n            depth = int(parent_grant[\"depth\"]) + 1\n            expires = min(expires, float(parent_grant[\"expires_at\"]))\n            parent_digest = C.sha(_signing_body(parent_grant))\n            parent_id_grant = parent_grant[\"grant_id\"]\n        if depth > self.max_depth:\n            raise AuthorityError(\"delegation depth limit\")\n        g = {\"grant_id\": C.rid(\"grant\", 6), \"mission_id\": mission_id, \"child_id\": str(child_id),\n             \"parent_id\": str(parent_id), \"parent_grant_digest\": parent_digest, \"capabilities\": caps,\n             \"side_effects\": sides, \"max_ops\": int(max_ops), \"ops_used\": 0, \"depth\": int(depth),\n             \"issued_at\": now, \"expires_at\": expires, \"parent_pub\": self.kr.pub(),\n             \"parent_grant_id\": parent_id_grant}\n        g[\"signature\"] = C.sign(self.kr.key(), C.D_GRANT, _signing_body(g))\n        self.s.x(\"INSERT INTO grants(grant_id,mission_id,child_id,parent_id,body,ops_used,issued_at,expires_at) \"\n                 \"VALUES(?,?,?,?,?,?,?,?)\",\n                 (g[\"grant_id\"], mission_id, child_id, parent_id, json.dumps(g, sort_keys=True), 0, now, expires))\n        self.s.event(\"GRANT_ISSUED\", mission_id=mission_id,\n                     body={\"grant_id\": g[\"grant_id\"], \"child\": child_id, \"parent\": parent_id, \"capabilities\": caps,\n                           \"side_effects\": sides, \"max_ops\": max_ops, \"depth\": depth, \"expires_at\": expires})\n        return g\n\n    def renew_grant(self, grant: Mapping[str, Any]) -> Dict[str, Any]:\n        \"\"\"Continuous authorization: a fresh short-lived grant with the remaining budget, only if still in standing.\n\n        The worker never renews itself; the coordinator calls this after re-checking mission and revocation state.\n        \"\"\"\n        v = self.verify_grant(grant, check_ops=True)\n        if not v[\"ok\"]:\n            raise AuthorityError(\"renewal refused: \" + \",\".join(v[\"reasons\"]))\n        used = self.ops_used(grant[\"grant_id\"])\n        parent = None\n        if grant.get(\"parent_grant_id\"):\n            parent = self.grant(grant[\"parent_grant_id\"])\n        g = self.issue_grant(mission_id=grant[\"mission_id\"], child_id=grant[\"child_id\"], parent_id=grant[\"parent_id\"],\n                             capabilities=grant[\"capabilities\"], side_effects=grant[\"side_effects\"],\n                             max_ops=int(grant[\"max_ops\"]) - used, depth=int(grant[\"depth\"]),\n                             parent_grant=parent) if parent else self.issue_grant(\n            mission_id=grant[\"mission_id\"], child_id=grant[\"child_id\"], parent_id=grant[\"parent_id\"],\n            capabilities=grant[\"capabilities\"], side_effects=grant[\"side_effects\"],\n            max_ops=int(grant[\"max_ops\"]) - used, depth=int(grant[\"depth\"]))\n        self.s.x(\"UPDATE grants SET superseded_by=? WHERE grant_id=?\", (g[\"grant_id\"], grant[\"grant_id\"]))\n        return g\n\n    def grant(self, grant_id: str) -> Optional[Dict[str, Any]]:\n        r = self.s.one(\"SELECT body FROM grants WHERE grant_id=?\", (grant_id,))\n        return json.loads(r[\"body\"]) if r else None\n\n    def ops_used(self, grant_id: str) -> int:\n        r = self.s.one(\"SELECT ops_used FROM grants WHERE grant_id=?\", (grant_id,))\n        return int(r[\"ops_used\"]) if r else 0\n\n    def verify_grant(self, g: Mapping[str, Any], *, now: Optional[float] = None, check_ops: bool = True) -> Dict[str, Any]:\n        now = time.time() if now is None else float(now)\n        reasons: List[str] = []\n        row = self.s.one(\"SELECT ops_used, superseded_by FROM grants WHERE grant_id=?\", (g.get(\"grant_id\"),))\n        if row is None:\n            reasons.append(\"UNKNOWN_GRANT\")                     # a grant we did not issue is never honoured\n        elif row[\"superseded_by\"]:\n            reasons.append(\"SUPERSEDED\")\n        if any(self.is_revoked(x) for x in (g.get(\"child_id\"), g.get(\"parent_id\"), g.get(\"grant_id\"),\n                                           g.get(\"mission_id\"))):\n            reasons.append(\"REVOKED\")\n        pubs = self.kr.trusted_pubs().values()\n        if g.get(\"parent_pub\") not in pubs or not C.verify(g.get(\"parent_pub\", \"\"), g.get(\"signature\", \"\"),\n                                                           C.D_GRANT, _signing_body(g)):\n            reasons.append(\"BAD_SIGNATURE\")\n        if now > float(g.get(\"expires_at\", 0)):\n            reasons.append(\"EXPIRED\")\n        if check_ops and row is not None and int(row[\"ops_used\"]) >= int(g.get(\"max_ops\", 0)):\n            reasons.append(\"OP_BUDGET_EXHAUSTED\")\n        return {\"ok\": not reasons, \"reasons\": reasons}\n\n    # ------------------------------------------------------------------ per-operation authorization\n    def authorize(self, *, grant: Mapping[str, Any], worker_id: str, task_id: str, attempt: int, operation: str,\n                  capability: str, side_effect: str, params: Mapping[str, Any], mission_state: str,\n                  host_ok: bool = True, cred_ok: bool = True, now: Optional[float] = None,\n                  mission_id: Optional[str] = None) -> Dict[str, Any]:\n        \"\"\"Decide one operation. Returns a decision dict; `ticket` is present only when the outcome is ALLOW.\"\"\"\n        now = time.time() if now is None else float(now)\n        cap = str(capability).upper()\n        params_digest = C.sha(dict(params))\n        op_digest = C.sha({\"task\": task_id, \"attempt\": attempt, \"operation\": operation, \"capability\": cap,\n                           \"side_effect\": side_effect, \"params\": params_digest, \"worker\": worker_id})\n        reasons: List[str] = []\n        outcome = ERROR\n        try:\n            v = self.verify_grant(grant, now=now)\n            reasons += v[\"reasons\"]\n            if grant.get(\"child_id\") != worker_id:\n                reasons.append(\"GRANT_NOT_FOR_WORKER\")\n            if mission_id and grant.get(\"mission_id\") != mission_id:\n                reasons.append(\"GRANT_MISSION_MISMATCH\")\n            if mission_state != \"RUNNING\":\n                reasons.append(\"MISSION_NOT_RUNNING:\" + str(mission_state))\n            if not host_ok:\n                reasons.append(\"HOST_NOT_TRUSTED\")\n            if not cred_ok:\n                reasons.append(\"CREDENTIAL_INVALID\")\n            if cap not in grant.get(\"capabilities\", []):\n                reasons.append(\"CAPABILITY_NOT_GRANTED\")\n            if side_effect not in grant.get(\"side_effects\", []):\n                reasons.append(\"SIDE_EFFECT_NOT_GRANTED\")\n            nonce = f\"{grant.get('grant_id')}:{op_digest}\"\n            if self.s.one(\"SELECT 1 FROM replay WHERE nonce=?\", (nonce,)):\n                reasons.append(\"REPLAY\")\n            if \"REVOKED\" in reasons:\n                outcome = REVOKED\n            elif \"EXPIRED\" in reasons:\n                outcome = EXPIRED\n            elif \"UNKNOWN_GRANT\" in reasons:\n                outcome = UNKNOWN\n            elif reasons:\n                outcome = DENY\n            else:\n                outcome = ALLOW\n        except Exception as e:  # noqa: BLE001  -- a fault while deciding is never an ALLOW\n            reasons.append(f\"DECISION_FAULT:{type(e).__name__}\")\n            outcome = ERROR\n        decision_id = C.rid(\"dec\", 6)\n        self.s.x(\"INSERT INTO decisions(decision_id,at,mission_id,worker_id,task_id,kind,outcome,reasons,op_digest) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?)\",\n                 (decision_id, now, grant.get(\"mission_id\"), worker_id, task_id, \"OPERATION\", outcome,\n                  json.dumps(reasons), op_digest))\n        out: Dict[str, Any] = {\"decision_id\": decision_id, \"outcome\": outcome, \"reasons\": reasons,\n                               \"op_digest\": op_digest, \"executable\": outcome == ALLOW}\n        if outcome != ALLOW:\n            return out\n        self.s.x(\"INSERT INTO replay(nonce,at) VALUES(?,?)\", (nonce, now))\n        self.s.x(\"UPDATE grants SET ops_used=ops_used+1 WHERE grant_id=?\", (grant[\"grant_id\"],))\n        body = {\"ticket_id\": C.rid(\"tkt\"), \"task_id\": task_id, \"attempt\": int(attempt),\n                \"mission_id\": grant[\"mission_id\"], \"worker_id\": worker_id, \"grant_id\": grant[\"grant_id\"],\n                \"operation\": operation, \"capability\": cap, \"side_effect\": side_effect,\n                \"params_digest\": params_digest, \"decision_id\": decision_id,\n                \"issued_at\": now, \"expires_at\": now + self.ticket_ttl_s}\n        sig = C.sign(self.kr.key(), C.D_TICKET, body)\n        self.s.x(\"INSERT INTO tickets(ticket_id,task_id,attempt,worker_id,body,sig,kid,issued_at,expires_at,state) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?,?)\",\n                 (body[\"ticket_id\"], task_id, attempt, worker_id, json.dumps(body, sort_keys=True), sig,\n                  self.kr.active, now, body[\"expires_at\"], \"ISSUED\"))\n        out[\"ticket\"] = {\"body\": body, \"sig\": sig, \"kid\": self.kr.active}\n        return out\n\n    def deny(self, *, mission_id: str, worker_id: str, task_id: str, kind: str, reasons: Sequence[str],\n             outcome: str = DENY) -> str:\n        \"\"\"Record a refusal that did not come through `authorize` (bad signature, forged result, ...).\"\"\"\n        decision_id = C.rid(\"dec\", 6)\n        self.s.x(\"INSERT INTO decisions(decision_id,at,mission_id,worker_id,task_id,kind,outcome,reasons,op_digest) \"\n                 \"VALUES(?,?,?,?,?,?,?,?,?)\",\n                 (decision_id, time.time(), mission_id, worker_id, task_id, kind, outcome,\n                  json.dumps(list(reasons)), \"\"))\n        return decision_id\n\n\ndef _signing_body(g: Mapping[str, Any]) -> Dict[str, Any]:\n    return {k: v for k, v in g.items() if k not in (\"signature\", \"ops_used\")}\n\n\ndef verify_grant_offline(g: Mapping[str, Any], trusted_pubs: Sequence[str], *, now: Optional[float] = None) -> List[str]:\n    \"\"\"Worker-side / verifier-side grant check with pinned authority keys only (no database).\"\"\"\n    reasons = []\n    if g.get(\"parent_pub\") not in trusted_pubs or not C.verify(g.get(\"parent_pub\", \"\"), g.get(\"signature\", \"\"),\n                                                               C.D_GRANT, _signing_body(g)):\n        reasons.append(\"BAD_SIGNATURE\")\n    if now is not None and now > float(g.get(\"expires_at\", 0)):\n        reasons.append(\"EXPIRED\")\n    return reasons\n"
   },
   "parent_task": "p4c121_security",
   "result": {
    "artifact_len": 25,
    "artifact_sha256": "73d7a257d5d4ec2a3a4609d026996ec180911dc33bbf549f3179b4511a1a266b",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.0685115,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.0422947,
    "task_id": "t-8699e76d51",
    "ticket_id": "tkt-af5ab38c8ce88809",
    "worker_id": "w-50989dadb7"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "t-8699e76d51",
   "ticket_id": "tkt-af5ab38c8ce88809",
   "timeout_s": 120.0,
   "updated_at": 1794629696.0729554,
   "verification": {
    "method": "none"
   },
   "verify_of": "p4c121_security",
   "worker_id": "w-50989dadb7"
  },
  {
   "artifact_sha": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629696.021303,
   "depends": [],
   "dispatched_at": 1794629696.068145,
   "error": null,
   "exclude_field": "verification",
   "exclude_worker": "w-f3790e47dd",
   "field": "analysis",
   "finished_at": 1794629696.084679,
   "idem_key": "verify:p4c121_data",
   "kind": "VERIFY",
   "lease_until": 1794629816.068145,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "t-2a6179b4b2",
   "operation": "summarize_csv",
   "output_digest": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
   "params": {
    "text": "sepal_length,sepal_width,petal_length,petal_width,species\r\n6.6,3.0,4.4,1.4,versicolor\r\n5.6,3.0,4.5,1.5,versicolor\r\n5.9,3.2,4.8,1.8,versicolor\r\n4.7,3.2,1.6,0.2,setosa\r\n6.4,3.2,4.5,1.5,versicolor\r\n5.2,2.7,3.9,1.4,versicolor\r\n6.3,3.3,4.7,1.6,versicolor\r\n7.2,3.6,6.1,2.5,virginica\r\n5.0,3.4,1.6,0.4,setosa\r\n5.1,3.8,1.5,0.3,setosa\r\n6.3,3.3,6.0,2.5,virginica\r\n6.6,3.0,4.4,1.4,versicolor\r\n5.1,3.4,1.5,0.2,setosa\r\n7.2,3.2,6.0,1.8,virginica\r\n5.1,3.5,1.4,0.2,setosa\r\n5.5,4.2,1.4,0.2,setosa\r\n4.6,3.4,1.4,0.3,setosa\r\n5.6,2.8,4.9,2.0,virginica\r\n6.9,3.1,4.9,1.5,versicolor\r\n4.9,3.6,1.4,0.1,setosa\r\n6.9,3.1,4.9,1.5,versicolor\r\n6.8,2.8,4.8,1.4,versicolor\r\n5.2,3.5,1.5,0.2,setosa\r\n5.0,2.0,3.5,1.0,versicolor\r\n5.9,3.0,5.1,1.8,virginica\r\n5.4,3.7,1.5,0.2,setosa\r\n6.7,3.1,5.6,2.4,virginica\r\n5.7,2.5,5.0,2.0,virginica\r\n4.8,3.4,1.9,0.2,setosa\r\n6.0,2.9,4.5,1.5,versicolor\r\n4.8,3.0,1.4,0.1,setosa\r\n5.8,2.6,4.0,1.2,versicolor\r\n6.1,2.6,5.6,1.4,virginica\r\n5.4,3.9,1.3,0.4,setosa\r\n4.9,3.0,1.4,0.2,setosa\r\n5.4,3.4,1.7,0.2,setosa\r\n6.3,2.9,5.6,1.8,virginica\r\n6.1,2.8,4.0,1.3,versicolor\r\n6.7,3.1,4.7,1.5,versicolor\r\n5.4,3.4,1.5,0.4,setosa\r\n"
   },
   "parent_task": "p4c121_data",
   "result": {
    "artifact_len": 344,
    "artifact_sha256": "4a00561cef2433aa0cdb20534438bc4b87dff19b716ca2daaa3d8a2a5206efda",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.073358,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.0709977,
    "task_id": "t-2a6179b4b2",
    "ticket_id": "tkt-49755623d266899e",
    "worker_id": "w-2a94b558b9"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "t-2a6179b4b2",
   "ticket_id": "tkt-49755623d266899e",
   "timeout_s": 120.0,
   "updated_at": 1794629696.0846884,
   "verification": {
    "method": "none"
   },
   "verify_of": "p4c121_data",
   "worker_id": "w-2a94b558b9"
  },
  {
   "artifact_sha": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
   "attempt": 1,
   "capability": "WORK",
   "created_at": 1794629696.024752,
   "depends": [],
   "dispatched_at": 1794629696.10673,
   "error": null,
   "exclude_field": "verification",
   "exclude_worker": "w-50989dadb7",
   "field": "analysis",
   "finished_at": 1794629696.112069,
   "idem_key": "verify:p4c121_infra",
   "kind": "VERIFY",
   "lease_until": 1794629816.10673,
   "max_attempts": 3,
   "mission_id": "msn-829e601236",
   "node_id": "t-8917a9d0a9",
   "operation": "scan_text",
   "output_digest": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
   "params": {
    "patterns": [
     "cpu_percent",
     "memory_percent",
     "disk_percent"
    ],
    "text": "{\"cpu_percent\": 95.7, \"cycle\": 121, \"disk_percent\": 50.5, \"load_1m\": 18.27978515625, \"memory_percent\": 84.2}"
   },
   "parent_task": "p4c121_infra",
   "result": {
    "artifact_len": 203,
    "artifact_sha256": "f4dd02fdb49055d2cdacd7fbf3748bdc0380477ba9d6d35d78284edec84d709e",
    "attempt": 1,
    "error": null,
    "finished_at": 1794629696.11024,
    "mission_id": "msn-829e601236",
    "ok": true,
    "started_at": 1794629696.1089525,
    "task_id": "t-8917a9d0a9",
    "ticket_id": "tkt-499933e8a47fb6f9",
    "worker_id": "w-4661d686ce"
   },
   "role": "worker",
   "side_effect": "local_artifact",
   "state": "VERIFIED",
   "task_id": "t-8917a9d0a9",
   "ticket_id": "tkt-499933e8a47fb6f9",
   "timeout_s": 120.0,
   "updated_at": 1794629696.1120787,
   "verification": {
    "method": "none"
   },
   "verify_of": "p4c121_infra",
   "worker_id": "w-4661d686ce"
  }
 ]
}