Skip to content

Commit 0b71e8a

Browse files
author
Wood Cell Dev
committed
Add capture parity tooling and enforcement regressions
1 parent 8edd96b commit 0b71e8a

40 files changed

Lines changed: 10348 additions & 395 deletions

ENGINEERING_LOG.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,62 @@
412412
- Wired dendro import toolkit into the results page with format catalog + preview (`frontend/src/components/Analysis/DendroToolkitPanel.tsx`, `frontend/src/services/api.ts`, `frontend/src/services/analysisService.ts`).
413413
- Updated milestone alignment docs for new parity progress (`docs/multi_milestone_execution_plan.md`, `docs/milestone_4_5_readiness_audit.md`).
414414
- `.venv/bin/python -m pytest tests/test_api_v2.py::test_project_ring_summary_endpoint`
415+
416+
## 2025-09-23 00:19 UTC
417+
- Authored remote capture architecture reference (`docs/capture/remote_twain_agent.md`) outlining agent pairing, presets, and health reporting.
418+
- Added remote capture agent package with Typer CLI and synthetic fallback (`agents/capture_agent`); implemented remote agent auth bypass for middleware and new capture stores.
419+
- Extended API with agent/preset/job endpoints plus JSON stores (`scripts/data_store.py`, `scripts/api_v2.py`), including remote upload path handling and preset CRUD.
420+
- Enhanced `cellctl` with `capture agents|presets|create-preset` commands and refreshed product blueprint + milestone 7 audit for remote capture progress.
421+
- Added regression tests covering agent lifecycle and preset CRUD (`tests/test_api_v2.py`), ran `.venv/bin/python -m pytest tests/test_api_v2.py` successfully.
422+
423+
## 2025-09-23 01:12 UTC
424+
- Implemented TWAIN/SANE-enabled provider registry in the capture agent with retry, preview, and stitched path-scan support (`agents/capture_agent/providers/*`, `agents/capture_agent/main.py`).
425+
- Wired backend to persist path-scan metadata, active agent jobs, and capture summaries (`scripts/api_v2.py`, `scripts/data_store.py`), adding `/api/v2/capture/summary` and CLI summary view.
426+
- Updated docs to reflect remote-agent capabilities and outstanding validation work (`docs/product_blueprint.md`, `docs/milestone_7_gap_audit.md`).
427+
- Expanded pytest coverage with path-scan and capture summary flows (`tests/test_api_v2.py`), all passing via `.venv/bin/python -m pytest tests/test_api_v2.py`.
428+
429+
## 2025-09-23 02:20 UTC
430+
- Surfaced WinCELL morphometrics in the React results console: hydraulic/ratio histograms, debris rollups, and per-cell-type summaries (`frontend/src/pages/Results.tsx`, `frontend/src/services/api.ts`).
431+
- Extended ring summary exports with per-ring series and hooked export actions in the UI (`scripts/api_v2.py`, `frontend/src/components/Analysis/RingSummaryPanel.tsx`).
432+
- Hardened regression coverage for ring exports and membership flows (`tests/test_api_v2.py`).
433+
- `.venv/bin/python -m pytest tests/test_api_v2.py`
434+
435+
## 2025-09-23 02:45 UTC
436+
- Added project-level ring chronology aggregation + chronology exports for WinCELL parity (`scripts/api_v2.py`, `frontend/src/components/Analysis/RingSummaryPanel.tsx`).
437+
- Introduced inference anomaly heuristics (coverage, debris ratio, hydraulic bounds) to feed parity alerts (`scripts/api_v2.py`).
438+
- Wired chronology types through analysis services and UI, including new charts/tables (`frontend/src/services/api.ts`, `frontend/src/services/analysisService.ts`).
439+
- Updated milestone audit to reflect the analytics progress (`docs/milestone_7_gap_audit.md`).
440+
- `.venv/bin/python -m pytest tests/test_api_v2.py`
441+
442+
## 2025-09-23 03:05 UTC
443+
- Carried calendar-year signals into ring summaries/exports and attached grouped morphometric stats + density summaries to WinDENDRO/XLCell bundles (`scripts/api_v2.py`).
444+
- Surfaced coverage/debris/hydraulic KPIs and density dashboards in the React results console (`frontend/src/pages/Results.tsx`).
445+
- Enriched chronology tooling with year-aware charts/tables (`frontend/src/components/Analysis/RingSummaryPanel.tsx`).
446+
- Tightened regression coverage for chronology/density exports (`tests/test_api_v2.py`).
447+
- `.venv/bin/python -m pytest tests/test_api_v2.py`
448+
449+
## 2025-09-23 11:05 UTC
450+
- Added parity export helper + pytest marker to validate WinDENDRO/XLCell bundles (`tests/test_api_v2.py::test_inference_export_parity`), seeded via `_run_parity_export_job`.
451+
- Surfaced QA harness through `cellctl qa parity` (runs `pytest -m parity`) and registered marker metadata (`pytest.ini`).
452+
- Updated Milestone 7 QA plan and gap audit to reflect the new automation coverage.
453+
454+
## 2025-09-23 11:40 UTC
455+
- Logged hardware validation matrix and path-scan QA protocol (`docs/capture/hardware_validation_matrix.md`, `docs/capture/path_scan_qa.md`).
456+
- Added parity harness tests + utility checklist (`tests/test_morphometrics_parity.py`, `docs/exports/reference_dataset_checklist.md`).
457+
- Authored specs for acquisition dashboard, debris tooling, region enforcement, vessel grouping, and results parity UI (`docs/capture/acquisition_dashboard_spec.md`, `docs/frontend_debris_tooling.md`, `docs/analysis_region_enforcement.md`, `docs/vessel_grouping_workflow.md`, `docs/frontend_results_parity.md`).
458+
## 2025-09-23 12:35 UTC
459+
- Added parity analytics pipeline: per-cell-type metrics, parity alert detection, export health caching, and bundle metadata storage (`scripts/api_v2.py`).
460+
- Extended parity pytest harness to validate analytics payloads and export health (`tests/test_morphometrics_parity.py`).
461+
- Upgraded Results dashboard with parity overview, export health panel, and density trend chart (`frontend/src/pages/Results.tsx`); refreshed API typings (`frontend/src/services/api.ts`).
462+
- Documented parity UI completion (`docs/frontend_results_parity.md`).
463+
## 2025-09-23 14:35 UTC
464+
- Implemented analysis-region enforcement pipeline: detections now carry structured rejection filters and analytics track accepted/rejected breakdowns (`scripts/api_v2.py`).
465+
- Added regression covering region enforcement scenarios and export metadata (`tests/test_api_v2.py::test_analysis_region_enforcement_flags_detections`).
466+
- Exposed detection filters and enforcement summary in API typings, and surfaced enforcement dashboards + per-image rejection chips in React results view (`frontend/src/services/api.ts`, `frontend/src/pages/Results.tsx`).
467+
- Updated enforcement plan doc with implementation status notes (`docs/analysis_region_enforcement.md`).
468+
469+
## 2025-09-23 18:45 UTC
470+
- Added parity regression to ensure analysis-region edits propagate to analytics and WinDENDRO exports (`tests/test_morphometrics_parity.py::test_analysis_region_edits_refresh_exports`).
471+
- Injected deterministic image dimensions into dry-run fixtures so enforcement math aligns with edge thresholds (`tests/test_morphometrics_parity.py`).
472+
- Refreshed milestone 7 audit to capture delivered debris tooling/enforcement work and highlight remaining acquisition + automation gaps (`docs/milestone_7_gap_audit.md`).
473+
- `.venv/bin/python -m pytest tests/test_morphometrics_parity.py::test_analysis_region_edits_refresh_exports`

agents/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Agent utilities for bridging educator hardware with the Cell platform."""

agents/capture_agent/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""Remote capture agent package."""
2+
3+
__all__ = ['config', 'devices', 'main']

agents/capture_agent/config.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""Configuration helpers for the remote capture agent."""
2+
3+
from __future__ import annotations
4+
5+
import json
6+
import os
7+
from dataclasses import dataclass, asdict
8+
from pathlib import Path
9+
from typing import Optional
10+
11+
CONFIG_DIR = Path(os.getenv('CELL_AGENT_HOME', Path.home() / '.cell'))
12+
CONFIG_PATH = CONFIG_DIR / 'capture_agent.json'
13+
14+
15+
@dataclass
16+
class AgentConfig:
17+
api_base: str
18+
agent_id: str
19+
token: str
20+
label: Optional[str] = None
21+
22+
23+
def load_config(path: Path = CONFIG_PATH) -> AgentConfig:
24+
if not path.exists():
25+
raise FileNotFoundError(f"Capture agent is not paired; run 'capture-agent register' first ({path})")
26+
payload = json.loads(path.read_text())
27+
return AgentConfig(
28+
api_base=payload['api_base'],
29+
agent_id=payload['agent_id'],
30+
token=payload['token'],
31+
label=payload.get('label')
32+
)
33+
34+
35+
def save_config(config: AgentConfig, path: Path = CONFIG_PATH) -> None:
36+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
37+
payload = asdict(config)
38+
path.write_text(json.dumps(payload, indent=2))
39+
40+
41+
def delete_config(path: Path = CONFIG_PATH) -> None:
42+
if path.exists():
43+
path.unlink()

agents/capture_agent/devices.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Device enumeration helpers built on top of provider registry."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Dict, List
6+
7+
from .providers import enumerate_all_devices, get_provider, ProviderCaptureError
8+
9+
10+
def enumerate_devices() -> List[Dict[str, str]]:
11+
devices = enumerate_all_devices()
12+
if not devices:
13+
devices.append(
14+
{
15+
"device_id": "simulator-local",
16+
"label": "Simulator (install TWAIN/SANE for hardware)",
17+
"provider": "simulator",
18+
"kind": "virtual",
19+
}
20+
)
21+
return devices
22+
23+
24+
def capture_image(
25+
provider_id: str,
26+
device_id: str,
27+
*,
28+
settings: Dict[str, str] | None = None,
29+
path_scan: Dict[str, str] | None = None,
30+
retry: int = 1,
31+
):
32+
provider = get_provider(provider_id)
33+
if not provider.available():
34+
raise ProviderCaptureError(f"Provider {provider_id} is not available on this host")
35+
return provider.capture(device_id=device_id, settings=settings, path_scan=path_scan, retry=retry)

0 commit comments

Comments
 (0)