{
  "schema_version": "evidence-package@2.2",
  "spec_version": "devtask.execution@1.0",
  "bundle_id": "devtask-execution-dt-1788706481169-vh26-1-1788707405762",
  "capability": "devtask.execution@1.0",
  "run_id": "dt-1788706481169-vh26:1",
  "claim_ladder": "L1",
  "executed_at": "2026-09-06T15:10:06.335Z",
  "trace_events": [
    "devtask_contract_bound:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"contract_hash\":\"f152056dc57e13ebdd80b6bb8034ab562956b7ac0602ac1c802641580e155056\",\"contract_schema_version\":\"work-contract@1.0\",\"risk_class\":\"R2\",\"protect_existing_tests\":false,\"test_protection_disclosure\":\"disclosed\"}",
    "devtask_attempt_started:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"started_at\":\"2026-09-06T14:54:52.819Z\"}",
    "devtask_execution_context:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"execution_reference\":\"dev_task_attempts:80\",\"sandbox_reference\":\"sandbox-attestation:sha256:d0082a36ea064af8b93eb2c9fa97c1667db1a49d4928cb42ad3065c563db3489\",\"executor\":\"deepseek\",\"harness_id\":\"agent-loop-server\",\"adapter_version\":\"repo-contribution-pipeline/deepseek@1.0.0\",\"adapter_version_sha256\":\"c36e789ec4f969715737cecd0c76ea879d3c955623e0a61e1fad3439d992e63b\"}",
    "devtask_negative_claim:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"claim\":\"no_network_outside_scope\",\"verified_by\":\"sandbox_policy:bubblewrap_unshare_net_fail_closed\",\"strength\":\"policy_derived\",\"result\":true,\"evidence_ref\":{\"artifact\":\"attestation\",\"id\":\"controller_evidence.sandbox_attestation\",\"digest\":\"sha256:76e4e381c472522fdc12692dac393b6846d81aaf8b488f96c456e750cea63402\"}}",
    "devtask_negative_claim:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"claim\":\"no_secret_access\",\"verified_by\":\"sandbox_policy:bubblewrap_clearenv\",\"strength\":\"policy_derived\",\"result\":true,\"evidence_ref\":{\"artifact\":\"runtime_trace\",\"id\":\"trace_events:without_negative_claims\",\"digest\":\"sha256:d1e119552f071f6aec320d1bcfc7f249bf30aa3506494a010a88bd60c131e69d\"}}",
    "devtask_negative_claim:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"claim\":\"no_write_outside_allowlist\",\"verified_by\":\"sandbox_policy:snapshot_without_git_or_symlinks\",\"strength\":\"policy_derived\",\"result\":true,\"evidence_ref\":{\"artifact\":\"runtime_trace\",\"id\":\"trace_events:without_negative_claims\",\"digest\":\"sha256:d1e119552f071f6aec320d1bcfc7f249bf30aa3506494a010a88bd60c131e69d\"}}",
    "devtask_validation:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"validation_status\":\"passed\",\"validation_reference\":\"dev_tasks.validation_result\"}",
    "devtask_diff_evidence:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"diff_stat_sha256\":\"31d5b9e06ede9a363166f1b9bbea76b2b3bf690e12ea93654084df864d3d0198\",\"diff_full_sha256\":\"4de1221356e65fe0645b72be4b9f1108aa258bbdbe3d8c0c32c0350ef3bad84b\",\"scope\":\"diff_stat_and_full\"}",
    "devtask_ci_result:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"result_commit\":\"9bbc765acef52a7da132558a537f1e9aeeeb28d2\",\"conclusion\":\"success\",\"checked_at\":\"2026-09-06T15:10:05.758Z\",\"source\":\"github_checks_and_statuses\",\"checks\":[{\"name\":\"test\",\"conclusion\":\"success\"}]}",
    "devtask_human_approval:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"actor_id\":\"tenant:tn_07bd75b1cac738f6966e061c53367178:owner\",\"approved_at\":\"2026-09-06 14:59:38\",\"approval_reference\":\"dev_tasks.approved_by\"}",
    "devtask_outcome:{\"task_id\":\"dt-1788706481169-vh26\",\"attempt_number\":1,\"outcome\":\"COMPLETED\",\"completed_at\":\"2026-09-06 14:59:41\",\"reference\":\"dev_tasks.state\"}"
  ],
  "trace_hash_chain": [
    "7ae13be9307603dc5bc2a1dfd51c781fef12d6fa186133b7af6f367b3a9f8b78",
    "db4abe26981459e755f7b4db6f3d2cbb2147beb7f7a36dee429ff289bd4cb2c9",
    "eaa0c53156e797488436fa621b723ce64da875683189a6f97b77964cd14ef249",
    "b132275218f6b9e0baa52b132a4ef4abca19bb626aad24775213a1a0b0e2caff",
    "26a83451e64b312d624722dbfed7972f57f4754fbfa97945ba7f7a1a107fa59c",
    "07c13dfef8ede38a3bc7f30f7d84d882e62328b67c431abb60e1e5eac639b9a1",
    "c246a515ad0eb13ba9dd6012dfb85096d91916f6ddda29f11f230e80a46d4fde",
    "54e20d535128b4f44358a8a020de60826688c8226d0c9ba4afcea59d6ef57bbe",
    "f73de00b7185e29e3cc0d1f6e66213ee49ff53bb91dc1365df6ade13a319df13",
    "14990189d961eec2cd0d51bed70febcaa5a02b15440ebd16dea643918a551a8f",
    "04cab512e59ac075d55085e70db1ade5657c88bde7d644a705876dd137b7660a"
  ],
  "outcome": "verified",
  "signer_key_id": "ed25519:8ebca0b6c3f238df04a39dd17ad030c958577f4dc56b9038dc03f6eb87327a94",
  "controller_evidence": {
    "contract_snapshot": {
      "schemaVersion": "work-contract@1.0",
      "title": "Fuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Str",
      "rawText": "Fuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Strings grossschreibt und den Rest unveraendert laesst. Bei leerem String soll ein leerer String zurueckgegeben werden, bei nicht-String-Eingabe ein TypeError wie bei den bestehenden Funktionen in der Datei. Ergaenze passende Tests in stringUtils.test.js im bestehenden Stil der Datei.",
      "acceptanceCriteria": [],
      "acceptanceAssertions": [],
      "protectExistingTests": false,
      "testProtectionDisclosure": "disclosed",
      "riskClass": "R2",
      "capabilityIds": [],
      "engineSelection": {
        "mode": "manual",
        "engine": "deepseek",
        "reason": "Im Pro-Modus manuell gewaehlt.",
        "capabilityIds": [],
        "evidence": null
      }
    },
    "producer": "privileged_controller",
    "task_id": "dt-1788706481169-vh26",
    "attempt_number": 1,
    "base_commit": "6144503d1eca83a8cb1ad3e0c5d0b8929af4e256",
    "result_reference": "github_pr:https://github.com/Alex-Proof/alex-controlled-agent-demo/pull/37",
    "diff_stat_sha256": "31d5b9e06ede9a363166f1b9bbea76b2b3bf690e12ea93654084df864d3d0198",
    "diff_full": "diff --git a/stringUtils.js b/stringUtils.js\nindex 29b4c26..0b1824a 100644\n--- a/stringUtils.js\n+++ b/stringUtils.js\n@@ -88,3 +88,52 @@ export function truncateWithEllipsis(text, maxLength) {\n   // b/c) Kuerzen und Ellipsis exakt ins Budget legen.\n   return text.slice(0, maxLength - ELLIPSIS_LENGTH) + ELLIPSIS;\n }\n+\n+/**\n+ * capitalizeFirst -- schreibt den ersten Buchstaben eines Strings gross und\n+ * laesst den Rest unveraendert.\n+ *\n+ * Design-Entscheidungen im Detail:\n+ *\n+ * 1) \"Rest unveraendert\": Anders als ein naiver Title-Case-Helper werden die\n+ *    restlichen Zeichen NICHT kleingeschrieben. Die Funktion uebernimmt nur\n+ *    den ersten Buchstaben in die Grossschreibung und laesst den Text dahinter\n+ *    exakt so stehen, wie er uebergeben wurde -- \"hALLO\" wird also zu \"HALLO\",\n+ *    nicht zu \"Hallo\". Damit ist die Funktion verlustfrei fuer die Gross-/\n+ *    Kleinschreibung des Rests und eignet sich als unueberraschender Baustein.\n+ *\n+ * 2) Umsetzung: Das erste Zeichen wird ueber text.charAt(0) geholt (statt\n+ *    text[0]), weil charAt(0) auch bei leerem String sauber '' liefert und\n+ *    keine undefined-Luecken erzeugt. Angehaengt wird text.slice(1) -- der\n+ *    gesamte Rest ab Index 1.\n+ *\n+ * 3) Unicode-Bewusstheit (analog zu truncateWithEllipsis): Die Funktion\n+ *    arbeitet auf UTF-16-Code-Units. Die haeufigsten Faelle (inkl. Umlaute\n+ *    wie \"ä\" -> \"Ä\") werden korrekt abgedeckt. Surrogatpaare (z.B. Emoji am\n+ *    Stringanfang) oder der \"ß\"-Sonderfall (toUpperCase liefert dort \"SS\",\n+ *    was das Ergebnis verlaengert) sind eine bewusste, dokumentierte\n+ *    Abwaegung zugunsten von Einfachheit.\n+ *\n+ * Randfaelle:\n+ *   - leerer String ('') -> '' (es gibt keinen Buchstaben zum Grossschreiben)\n+ *   - erstes Zeichen ist kein Buchstabe (Zahl, Leerzeichen, Sonderzeichen):\n+ *     toUpperCase aendert daran nichts, der Text bleibt unveraendert\n+ *\n+ * Validierung (fail-fast, bewusst strikt): Ist text kein String, wird ein\n+ * TypeError geworfen -- Programmierfehler am Aufrufer werden sofort sichtbar\n+ * statt stillschweigend falsche Ergebnisse zu liefern. Dieses Verhalten ist\n+ * identisch zu truncateWithEllipsis, damit beide Funktionen dieser Datei ein\n+ * einheitliches, vorhersehbares Fehlerverhalten aufweisen.\n+ */\n+export function capitalizeFirst(text) {\n+  if (typeof text !== 'string') {\n+    throw new TypeError(`text muss ein String sein, erhalten: ${typeof text}`);\n+  }\n+\n+  // Leerer String: kein Buchstabe vorhanden, unveraendert '' zurueckgeben.\n+  if (text.length === 0) {\n+    return '';\n+  }\n+\n+  return text.charAt(0).toUpperCase() + text.slice(1);\n+}\ndiff --git a/stringUtils.test.js b/stringUtils.test.js\nindex 96182c8..d0eb0ac 100644\n--- a/stringUtils.test.js\n+++ b/stringUtils.test.js\n@@ -1,6 +1,6 @@\n import { test } from 'node:test';\n import assert from 'node:assert/strict';\n-import { truncateWithEllipsis } from './stringUtils.js';\n+import { truncateWithEllipsis, capitalizeFirst } from './stringUtils.js';\n \n test('kuerzt einen kurzen String nicht, wenn er in maxLength passt', () => {\n   const input = 'Hallo Welt';\n@@ -56,3 +56,35 @@ test('Invariante: Ergebnislaenge ist niemals groesser als maxLength', () => {\n     );\n   }\n });\n+\n+test('schreibt den ersten Buchstaben gross und laesst den Rest unveraendert', () => {\n+  assert.equal(capitalizeFirst('hallo welt'), 'Hallo welt');\n+  assert.equal(capitalizeFirst('alex'), 'Alex');\n+});\n+\n+test('laesst den Rest auch dann unveraendert, wenn er gross ist', () => {\n+  assert.equal(capitalizeFirst('hALLO'), 'HALLO');\n+  assert.equal(capitalizeFirst('aBcDeF'), 'ABcDeF');\n+});\n+\n+test('laesst einen bereits gross beginnenden String unveraendert', () => {\n+  assert.equal(capitalizeFirst('Hallo'), 'Hallo');\n+  assert.equal(capitalizeFirst('ALEX'), 'ALEX');\n+});\n+\n+test('leerer String bleibt leer', () => {\n+  assert.equal(capitalizeFirst(''), '');\n+});\n+\n+test('wirft einen TypeError, wenn text kein String ist', () => {\n+  assert.throws(() => capitalizeFirst(42), TypeError);\n+  assert.throws(() => capitalizeFirst(null), TypeError);\n+  assert.throws(() => capitalizeFirst(undefined), TypeError);\n+  assert.throws(() => capitalizeFirst({}), TypeError);\n+  assert.throws(() => capitalizeFirst(['a']), TypeError);\n+});\n+\n+test('laesst Strings mit Nicht-Buchstaben am Anfang unveraendert', () => {\n+  assert.equal(capitalizeFirst('123 abc'), '123 abc');\n+  assert.equal(capitalizeFirst('  führendes Leerzeichen'), '  führendes Leerzeichen');\n+});",
    "diff_full_sha256": "4de1221356e65fe0645b72be4b9f1108aa258bbdbe3d8c0c32c0350ef3bad84b",
    "execution_reference": "dev_task_attempts:80",
    "validation_reference": "dev_tasks.validation_result",
    "approval_reference": "dev_tasks.approved_by",
    "sandbox_reference": "sandbox-attestation:sha256:d0082a36ea064af8b93eb2c9fa97c1667db1a49d4928cb42ad3065c563db3489",
    "sandbox_attestation": {
      "schema_version": "sandbox-attestation@2.0",
      "sandbox_id": "sandbox:devtask-dt-1788706481169-vh26-1788706492535:c1cf5a0e661e8475",
      "agent_id": "devtask-dt-1788706481169-vh26-1788706492535",
      "started_at": "2026-09-06T14:54:53.810Z",
      "completed_at": "2026-09-06T14:57:52.543Z",
      "snapshot_sha256": "c1cf5a0e661e8475f8403a92f95d69e41ff506a057174ca53d5ede6ae47db6fa",
      "policy_sha256": "dc0a29632e53f37f3d02426ae9c3da65b557a53185265da9cd5d0f7c8cb26189",
      "os_isolation_available": true,
      "git_metadata_absent": true,
      "controller_checkout_separated": true,
      "network_policy": "bubblewrap_unshare_net_fail_closed",
      "environment_policy": "bubblewrap_clearenv",
      "process_policy": "systemd_scope_limits_and_kill",
      "handoff_manifest_sha256": "26f391fe737c65d6ce4c9f3d2a36074bf13ee2d6cabad34b432c52bb98636eaa",
      "rejected_manifest_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
      "network_capture": null
    },
    "agent_run_id": "devtask-dt-1788706481169-vh26-1788706492535",
    "repository_state": {
      "schema_version": "repository-state@1.0",
      "base_commit": "6144503d1eca83a8cb1ad3e0c5d0b8929af4e256",
      "result_commit": "9bbc765acef52a7da132558a537f1e9aeeeb28d2",
      "tree_before_sha256": "6c68ca9ef574468533d7e61209acc19434844d8129ff8ec05d61c3a5485b7052",
      "tree_after_sha256": "fcaeca98c0ec5769e6ab5cac71f503c961c74fbd58083243f0484a613f369c6e",
      "changed_files": [
        {
          "path": "stringUtils.js",
          "status": "M",
          "before_sha256": "e3c35b4c0cef3f3be49339da176807aab94233b0aa0f496c2464123c66fc2c0b",
          "after_sha256": "214b05686031bc1c500e074de5bc00e0c7b64cf29533fac4a4db7e3b61700529"
        },
        {
          "path": "stringUtils.test.js",
          "status": "M",
          "before_sha256": "de487c841df54fd881ee58211c8f9c56dccb9ed82662513fd27f1a1a4d77f1bb",
          "after_sha256": "e6109db54dd97a17764d682272d1561aa610b70f5de1671bdf9540d56daf6433"
        }
      ]
    },
    "test_integrity_policy": {
      "schema_version": "test-integrity-policy@1.0",
      "policy": "protect_existing_tests",
      "protected": false,
      "status": "not_requested",
      "violating_files": []
    }
  },
  "required_evidence": [
    "contract",
    "attempt",
    "execution_context",
    "validation",
    "outcome",
    "base_commit",
    "diff_full",
    "human_approval",
    "result_reference",
    "ci_result",
    "repository_state"
  ],
  "approval_attestation_required": true,
  "customer_evidence": {
    "schema_version": "customer-evidence@1.0",
    "brief": {
      "title": "Fuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Str",
      "raw_text": "Fuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Strings grossschreibt und den Rest unveraendert laesst. Bei leerem String soll ein leerer String zurueckgegeben werden, bei nicht-String-Eingabe ein TypeError wie bei den bestehenden Funktionen in der Datei. Ergaenze passende Tests in stringUtils.test.js im bestehenden Stil der Datei."
    },
    "cost_partial": {
      "cost_usd": 0.00961,
      "cost_usd_tracked": true,
      "turns_used": 11,
      "duration_seconds": 180,
      "assigned_model": "deepseek-v4-flash",
      "assigned_engine": "deepseek",
      "token_tracking": "not_available"
    },
    "denied": [],
    "approval": {
      "proven": true,
      "actor_id": "tenant:tn_07bd75b1cac738f6966e061c53367178:owner",
      "channel": "pilot",
      "confirmed_by": "tn_07bd75b1cac738f6966e061c53367178",
      "confirmed_at": "2026-09-06 14:54:49",
      "approved_at": "2026-09-06 14:59:38",
      "approval_reference": "dev_tasks.approved_by"
    },
    "open_risks": [
      {
        "code": "coverage_not_measured",
        "description": "Ob der geaenderte Code durch Tests abgedeckt ist, wird nicht automatisch gemessen -- strukturelle Grenze, keine Aussage ueber diesen einzelnen Lauf.",
        "recommended_action": "Optional: Testabdeckung des geaenderten Codes separat pruefen (z.B. Coverage-Tool), falls fuer diesen Auftrag wichtig."
      },
      {
        "code": "domain_correctness_not_verified",
        "description": "Ob die Aenderung fachlich das Richtige tut, wurde nicht automatisiert geprueft -- das bleibt Teil der menschlichen Freigabe.",
        "recommended_action": "Fachliche Korrektheit durch menschliches Review oder eine Domaenen-Pruefung bestaetigen lassen."
      },
      {
        "code": "no_acceptance_criteria",
        "description": "Keine Abnahmekriterien vorgegeben -- die Erfuellung ist nur anhand der Freitext-Beschreibung beurteilbar.",
        "recommended_action": "Fuer kuenftige Auftraege Abnahmekriterien vorgeben, damit die Erfuellung objektiv pruefbar wird."
      },
      {
        "code": "tests_not_protected",
        "description": "Bestehende Tests waren fuer diesen Lauf nicht ausdruecklich vor Aenderung/Loeschung geschuetzt.",
        "recommended_action": "Fuer kuenftige Laeufe protect_existing_tests aktivieren, falls ungewollte Aenderungen daran vermieden werden sollen."
      },
      {
        "code": "dependency_tree_not_fully_audited",
        "description": "Nur neu eingefuehrte Abhaengigkeiten wurden gegen bekannte Schwachstellen (OSV.dev) geprueft, nicht der gesamte bestehende Abhaengigkeitsbaum des Ziel-Repos.",
        "recommended_action": "Fuer eine vollstaendige Pruefung ein dediziertes SBOM-/Dependency-Audit-Tool auf dem gesamten Repo einsetzen."
      }
    ],
    "acceptance_assertions": [],
    "customer_summary": "Fuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Str\n\nAuftrag:\nFuege stringUtils.js eine neue exportierte Funktion capitalizeFirst(text) hinzu, die nur den ersten Buchstaben eines Strings grossschreibt und den Rest unveraendert laesst. Bei leerem String soll ein leerer String zurueckgegeben werden, bei nicht-String-Eingabe ein TypeError wie bei den bestehenden Funktionen in der Datei. Ergaenze passende Tests in stringUtils.test.js im bestehenden Stil der Datei.\n\nKosten:\n$0.01, 11 Turns, 3m 0s\nEs werden ausschließlich Aggregatkosten erfasst, keine Tokenzahlen.\n\nFreigabe:\nBewiesen freigegeben über Kanal `pilot`.\nBestätigt von: tn_07bd75b1cac738f6966e061c53367178\nBestätigt am: 2026-09-06 14:54:49\n\nAbgelehnte Aktionen:\nKeine abgelehnten Aktionen in diesem Lauf.\n\nOffene Risiken:\n- Ob der geaenderte Code durch Tests abgedeckt ist, wird nicht automatisch gemessen -- strukturelle Grenze, keine Aussage ueber diesen einzelnen Lauf.\n- Nur neu eingefuehrte Abhaengigkeiten wurden gegen bekannte Schwachstellen (OSV.dev) geprueft, nicht der gesamte bestehende Abhaengigkeitsbaum des Ziel-Repos.\n- Ob die Aenderung fachlich das Richtige tut, wurde nicht automatisiert geprueft -- das bleibt Teil der menschlichen Freigabe.\n- Keine Abnahmekriterien vorgegeben -- die Erfuellung ist nur anhand der Freitext-Beschreibung beurteilbar.\n- Bestehende Tests waren fuer diesen Lauf nicht ausdruecklich vor Aenderung/Loeschung geschuetzt.\n\nErfolgskriterien:\nKeine typisierten Erfolgskriterien fuer diesen Auftrag definiert."
  },
  "signature": "mwhoxQTjEVsPifQTG1XY6GtCvCUEaw5obAj/yodQj7RNH3lcgYY5TX4/1+e9d3hHF9AFMsgFgcXCZqWEj5D4DQ==",
  "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAtFx/N93jfigyZXuWDEalUDrB34ZHw/v3duhjlVIH2yY=\n-----END PUBLIC KEY-----\n",
  "rfc3161_timestamp": {
    "schema_version": "rfc3161-timestamp@1.0",
    "tsa_url": "https://freetsa.org/tsr",
    "timestamped_sha256": "60321aaece563a895edd9422ea06a8d713440e49b7ecda060a075a18724589ff",
    "gen_time": "2026-09-06T15:10:07.000Z",
    "token_der_base64": "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"
  },
  "approval_attestation": {
    "schema_version": "approval-attestation@1.0",
    "actor_id": "tenant:tn_07bd75b1cac738f6966e061c53367178:owner",
    "approved_at": "2026-09-06 14:59:38",
    "bundle_sha256": "51399325cfd6e3320954cca387d7ba7029ac0d595bda6a9d7499db8baa8698d1",
    "signer_key_id": "ed25519:208fb4cf182bd011293fcfdc05f5fc2504aacff3f91fb6ec25fc5947bfa3a2f2",
    "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEArk0TPMKRyFeRtxB+u4+KHVmFF52F8c5152TnDXAdZ7Y=\n-----END PUBLIC KEY-----\n",
    "signature": "DcB9P6/yY95K/LdHrW7ZpHLVJi5h+qSY5Qso7kULAgbAvuW/rCn+qImKzhRbyVpKh73AotlBZmeOHoTQ2XkuBQ=="
  },
  "observer_receipt": {
    "schema_version": "observer-receipt@1.0",
    "observer_url": "http://167.233.61.52:8420",
    "leaf_index": 3,
    "received_at": "2026-09-06T15:10:08.573Z"
  }
}
