{
  "schemaVersion": 5,
  "format": "trace-manifest",
  "emitter": {
    "name": "specassay-check",
    "version": "0.9.0-beta"
  },
  "targetName": "FieldKit",
  "repoPath": "/work/fieldkit",
  "generatedAt": "2026-08-11T12:00:00Z",
  "gate": {
    "ok": true,
    "failures": []
  },
  "totals": {
    "registryIdCount": 31,
    "acCount": 16,
    "coveredCount": 10
  },
  "statusCounts": {
    "proven": 18,
    "tracked-debt": 4,
    "GAP": 0,
    "backlog": 9
  },
  "rows": [
    {
      "id": "US-CAPT-01",
      "type": "US",
      "tier": "intent",
      "statement": "US-CAPT-01 — As a field tech, I record observations on site, connected or not.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 12
      },
      "registry": {
        "path": "PRD.md",
        "line": 12
      },
      "status": "backlog",
      "parents": [],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "FR-CAPT-01",
          "FR-CAPT-02"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "FR-CAPT-01",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-CAPT-01 — Observation forms render from a versioned template and validate locally.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 13
      },
      "registry": {
        "path": "PRD.md",
        "line": 13
      },
      "status": "proven",
      "parents": [
        "US-CAPT-01"
      ],
      "implementations": [
        {
          "path": "src/capture/forms.py",
          "line": 41,
          "excerpt": "# @covers FR-CAPT-01"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-CAPT-01",
          "AC-CAPT-02"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "FR-CAPT-02",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-CAPT-02 — Photos and GPS fixes attach to an observation as first-class fields.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 14
      },
      "registry": {
        "path": "PRD.md",
        "line": 14
      },
      "status": "proven",
      "parents": [
        "US-CAPT-01"
      ],
      "implementations": [
        {
          "path": "src/capture/attachments.py",
          "line": 22,
          "excerpt": "# @covers FR-CAPT-02"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-CAPT-03",
          "AC-CAPT-04"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "AC-CAPT-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-CAPT-01 — A completed form saves locally in under 1s with no network.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 15
      },
      "registry": {
        "path": "PRD.md",
        "line": 15
      },
      "status": "proven",
      "parents": [
        "FR-CAPT-01"
      ],
      "implementations": [
        {
          "path": "src/capture/store.py",
          "line": 18,
          "excerpt": "# @covers AC-CAPT-01"
        }
      ],
      "proofs": [
        {
          "name": "test_AC_CAPT_01_local_save_under_1s_offline",
          "path": "tests/test_capture.py",
          "line": 12
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-CAPT-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-CAPT-02 — Validation failures name the field and block save until fixed.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 16
      },
      "registry": {
        "path": "PRD.md",
        "line": 16
      },
      "status": "proven",
      "parents": [
        "FR-CAPT-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_CAPT_02_validation_names_field_blocks_save",
          "path": "tests/test_capture.py",
          "line": 33
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-CAPT-03",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-CAPT-03 — A photo attached offline is stored full-resolution and thumbnailed.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 17
      },
      "registry": {
        "path": "PRD.md",
        "line": 17
      },
      "status": "proven",
      "parents": [
        "FR-CAPT-02"
      ],
      "implementations": [
        {
          "path": "src/capture/attachments.py",
          "line": 57,
          "excerpt": "# @covers AC-CAPT-03"
        }
      ],
      "proofs": [
        {
          "name": "test_AC_CAPT_03_offline_photo_full_res_and_thumb",
          "path": "tests/test_attachments.py",
          "line": 9
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-CAPT-04",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-CAPT-04 — A GPS fix older than 30s is flagged stale on the form.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 18
      },
      "registry": {
        "path": "PRD.md",
        "line": 18
      },
      "status": "tracked-debt",
      "parents": [
        "FR-CAPT-02"
      ],
      "implementations": [
        {
          "path": "src/capture/gps.py",
          "line": 31,
          "excerpt": "# @covers AC-CAPT-04"
        }
      ],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/capture/tasks.md",
          "line": 21,
          "excerpt": "- [ ] T204 — Carries: AC-CAPT-04"
        }
      ],
      "attestedBy": null
    },
    {
      "id": "US-SYNC-01",
      "type": "US",
      "tier": "intent",
      "statement": "US-SYNC-01 — As a field tech, my observations reach the team without me thinking about it.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 22
      },
      "registry": {
        "path": "PRD.md",
        "line": 22
      },
      "status": "backlog",
      "parents": [],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "FR-SYNC-01"
        ],
        "coveredChildren": 1
      }
    },
    {
      "id": "FR-SYNC-01",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-SYNC-01 — Queued observations sync in the background when a connection appears.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 23
      },
      "registry": {
        "path": "PRD.md",
        "line": 23
      },
      "status": "proven",
      "parents": [
        "US-SYNC-01"
      ],
      "implementations": [
        {
          "path": "src/sync/queue.py",
          "line": 15,
          "excerpt": "# @covers FR-SYNC-01"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-SYNC-01",
          "AC-SYNC-02",
          "AC-SYNC-03"
        ],
        "coveredChildren": 3
      }
    },
    {
      "id": "AC-SYNC-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-SYNC-01 — A queued observation appears on the team dashboard within 10s of reconnect.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 24
      },
      "registry": {
        "path": "PRD.md",
        "line": 24
      },
      "status": "proven",
      "parents": [
        "FR-SYNC-01"
      ],
      "implementations": [
        {
          "path": "src/sync/queue.py",
          "line": 62,
          "excerpt": "# @covers AC-SYNC-01"
        }
      ],
      "proofs": [
        {
          "name": "test_AC_SYNC_01_dashboard_within_10s_of_reconnect",
          "path": "tests/test_sync.py",
          "line": 14
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-SYNC-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-SYNC-02 — Sync retries with backoff and never drops an observation.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 25
      },
      "registry": {
        "path": "PRD.md",
        "line": 25
      },
      "status": "proven",
      "parents": [
        "FR-SYNC-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_SYNC_02_retry_backoff_never_drops",
          "path": "tests/test_sync.py",
          "line": 41
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-SYNC-03",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-SYNC-03 — Two techs editing the same observation merge without losing either edit.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 26
      },
      "registry": {
        "path": "PRD.md",
        "line": 26
      },
      "status": "tracked-debt",
      "parents": [
        "FR-SYNC-01"
      ],
      "implementations": [
        {
          "path": "src/sync/merge.py",
          "line": 28,
          "excerpt": "# @covers AC-SYNC-03"
        }
      ],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/sync/tasks.md",
          "line": 17,
          "excerpt": "- [ ] T311 — Carries: AC-SYNC-03"
        }
      ],
      "attestedBy": null
    },
    {
      "id": "US-EXP-01",
      "type": "US",
      "tier": "intent",
      "statement": "US-EXP-01 — As a project lead, I hand a client a report they can open anywhere.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 30
      },
      "registry": {
        "path": "PRD.md",
        "line": 30
      },
      "status": "backlog",
      "parents": [],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "FR-EXP-01",
          "FR-EXP-02"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "FR-EXP-01",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-EXP-01 — Any filtered set of observations exports as PDF and CSV.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 31
      },
      "registry": {
        "path": "PRD.md",
        "line": 31
      },
      "status": "proven",
      "parents": [
        "US-EXP-01"
      ],
      "implementations": [
        {
          "path": "src/export/report.py",
          "line": 19,
          "excerpt": "# @covers FR-EXP-01"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-EXP-01",
          "AC-EXP-02"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "FR-EXP-02",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-EXP-02 — Exports embed the capture timestamps and GPS fixes verbatim.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 32
      },
      "registry": {
        "path": "PRD.md",
        "line": 32
      },
      "status": "proven",
      "parents": [
        "US-EXP-01"
      ],
      "implementations": [
        {
          "path": "src/export/fields.py",
          "line": 12,
          "excerpt": "# @covers FR-EXP-02"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-EXP-03"
        ],
        "coveredChildren": 1
      }
    },
    {
      "id": "AC-EXP-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-EXP-01 — A 500-observation export completes in under 20s.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 33
      },
      "registry": {
        "path": "PRD.md",
        "line": 33
      },
      "status": "proven",
      "parents": [
        "FR-EXP-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_EXP_01_500_obs_under_20s",
          "path": "tests/test_export.py",
          "line": 22
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-EXP-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-EXP-02 — The PDF renders every attached photo at print resolution.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 34
      },
      "registry": {
        "path": "PRD.md",
        "line": 34
      },
      "status": "proven",
      "parents": [
        "FR-EXP-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_EXP_02_pdf_photos_print_resolution",
          "path": "tests/test_export.py",
          "line": 48
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-EXP-03",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-EXP-03 — CSV column order is stable across app versions.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 35
      },
      "registry": {
        "path": "PRD.md",
        "line": 35
      },
      "status": "tracked-debt",
      "parents": [
        "FR-EXP-02"
      ],
      "implementations": [
        {
          "path": "src/export/fields.py",
          "line": 44,
          "excerpt": "# @covers AC-EXP-03"
        }
      ],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/export/tasks.md",
          "line": 9,
          "excerpt": "- [ ] T407 — Carries: AC-EXP-03"
        }
      ],
      "attestedBy": null
    },
    {
      "id": "US-AUTH-01",
      "type": "US",
      "tier": "intent",
      "statement": "US-AUTH-01 — As an org admin, only my team sees my project's data.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 39
      },
      "registry": {
        "path": "PRD.md",
        "line": 39
      },
      "status": "backlog",
      "parents": [],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "FR-AUTH-01"
        ],
        "coveredChildren": 1
      }
    },
    {
      "id": "FR-AUTH-01",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-AUTH-01 — Project access is role-scoped: admin, editor, viewer.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 40
      },
      "registry": {
        "path": "PRD.md",
        "line": 40
      },
      "status": "proven",
      "parents": [
        "US-AUTH-01"
      ],
      "implementations": [
        {
          "path": "src/auth/roles.py",
          "line": 16,
          "excerpt": "# @covers FR-AUTH-01"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": true,
        "children": [
          "AC-AUTH-01",
          "AC-AUTH-02"
        ],
        "coveredChildren": 2
      }
    },
    {
      "id": "AC-AUTH-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-AUTH-01 — A viewer role cannot modify or export observations.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 41
      },
      "registry": {
        "path": "PRD.md",
        "line": 41
      },
      "status": "proven",
      "parents": [
        "FR-AUTH-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_AUTH_01_viewer_cannot_modify_or_export",
          "path": "tests/test_auth.py",
          "line": 11
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-AUTH-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-AUTH-02 — Revoking access takes effect on the revoked device within one sync.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 42
      },
      "registry": {
        "path": "PRD.md",
        "line": 42
      },
      "status": "proven",
      "parents": [
        "FR-AUTH-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_AUTH_02_revoke_effective_within_one_sync",
          "path": "tests/test_auth.py",
          "line": 37
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "NFR-PERF-01",
      "type": "NFR",
      "tier": "requirement",
      "statement": "NFR-PERF-01 — The observation list stays at 60fps with 2,000 records on device.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 46
      },
      "registry": {
        "path": "PRD.md",
        "line": 46
      },
      "status": "proven",
      "parents": [],
      "implementations": [
        {
          "path": "src/ui/list_virtualizer.py",
          "line": 8,
          "excerpt": "# @covers NFR-PERF-01"
        }
      ],
      "proofs": [
        {
          "name": "test_AC_PERF_01_list_60fps_2000_records",
          "path": "tests/test_perf.py",
          "line": 15
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "NFR-PERF-02",
      "type": "NFR",
      "tier": "requirement",
      "statement": "NFR-PERF-02 — Cold start to usable form in under 2s on a mid-range device.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 47
      },
      "registry": {
        "path": "PRD.md",
        "line": 47
      },
      "status": "tracked-debt",
      "parents": [],
      "implementations": [
        {
          "path": "src/app/boot.py",
          "line": 5,
          "excerpt": "# @covers NFR-PERF-02"
        }
      ],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/perf/tasks.md",
          "line": 12,
          "excerpt": "- [ ] T512 — Carries: NFR-PERF-02"
        }
      ],
      "attestedBy": null
    },
    {
      "id": "NFR-A11Y-01",
      "type": "NFR",
      "tier": "requirement",
      "statement": "NFR-A11Y-01 — Every capture flow is operable by screen reader alone.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 48
      },
      "registry": {
        "path": "PRD.md",
        "line": 48
      },
      "status": "proven",
      "parents": [],
      "implementations": [
        {
          "path": "src/ui/a11y.py",
          "line": 21,
          "excerpt": "# @covers NFR-A11Y-01"
        }
      ],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": false,
        "children": [
          "AC-A11Y-01",
          "AC-A11Y-02"
        ],
        "coveredChildren": 1
      }
    },
    {
      "id": "AC-A11Y-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-A11Y-01 — Form fields announce label, value, and validation state.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 49
      },
      "registry": {
        "path": "PRD.md",
        "line": 49
      },
      "status": "proven",
      "parents": [
        "NFR-A11Y-01"
      ],
      "implementations": [],
      "proofs": [
        {
          "name": "test_AC_A11Y_01_fields_announce_label_value_state",
          "path": "tests/test_a11y.py",
          "line": 10
        }
      ],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-A11Y-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-A11Y-02 — Photo capture is reachable and operable without touch gestures.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 50
      },
      "registry": {
        "path": "PRD.md",
        "line": 50
      },
      "status": "backlog",
      "parents": [
        "NFR-A11Y-01"
      ],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/backlog/tasks.md",
          "line": 14,
          "excerpt": "- [ ] T601 — Carries: AC-A11Y-02"
        }
      ],
      "attestedBy": null
    },
    {
      "id": "US-MAP-01",
      "type": "US",
      "tier": "intent",
      "statement": "US-MAP-01 — As a project lead, I see every observation pinned on one map.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 54
      },
      "registry": {
        "path": "PRD.md",
        "line": 54
      },
      "status": "backlog",
      "parents": [],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": false,
        "children": [
          "FR-MAP-01"
        ],
        "coveredChildren": 0
      }
    },
    {
      "id": "FR-MAP-01",
      "type": "FR",
      "tier": "requirement",
      "statement": "FR-MAP-01 — The map clusters pins and filters by the same query as the list.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 55
      },
      "registry": {
        "path": "PRD.md",
        "line": 55
      },
      "status": "backlog",
      "parents": [
        "US-MAP-01"
      ],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null,
      "rollup": {
        "covered": false,
        "children": [
          "AC-MAP-01",
          "AC-MAP-02"
        ],
        "coveredChildren": 0
      }
    },
    {
      "id": "AC-MAP-01",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-MAP-01 — Tapping a cluster zooms to its observations.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 56
      },
      "registry": {
        "path": "PRD.md",
        "line": 56
      },
      "status": "backlog",
      "parents": [
        "FR-MAP-01"
      ],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [],
      "attestedBy": null
    },
    {
      "id": "AC-MAP-02",
      "type": "AC",
      "tier": "criterion",
      "statement": "AC-MAP-02 — Map view works from the offline tile cache.",
      "origin": {
        "kind": "registry-line",
        "path": "PRD.md",
        "line": 57
      },
      "registry": {
        "path": "PRD.md",
        "line": 57
      },
      "status": "backlog",
      "parents": [
        "FR-MAP-01"
      ],
      "implementations": [],
      "proofs": [],
      "carryingTasks": [
        {
          "path": "specs/backlog/tasks.md",
          "line": 19,
          "excerpt": "- [ ] T702 — Carries: AC-MAP-02"
        }
      ],
      "attestedBy": null
    }
  ]
}
