feat(onboarding): PLC/blob file upload (multipart) + single-file ingest fix #163

Merged
sharang merged 2 commits from feat/artifact-file-upload into main 2026-07-16 09:41:13 +00:00
Owner

Delivers PLC projects (and other blob artifacts) to the agent by file upload,
completing the SPS/PLC onboarding demo path: onboard a PlcSps target → upload the
PLC project → scan → findings.

What's here

  • Agent: POST /api/v1/targets/{id}/artifacts/upload (axum multipart). Stores
    the uploaded bytes and $pushes a PlcProject/firmware/source/mobile artifact
    (with stored_path + size_bytes + plc_format) onto the target.
  • Dashboard: upload_target_artifact server fn (reqwest multipart) + a wizard
    file input for blob artifact kinds, with a PLC-format selector; files are staged
    in the wizard and uploaded after the target is created.
  • Ingest fix: a single uploaded .st/.xml (not a zip) was content-addressed
    to an extensionless blob, so the PLC scanner's extension-based discovery
    skipped it (zero findings). Ingest now materializes a non-archive blob into the
    work dir under its original file name, so analyze_tree finds it and reports a
    readable path. New unit test covers upload → ingest → scan.

Verification

  • cargo test -p compliance-agent --lib (ingest + plc suites green, incl. the new
    single_uploaded_plc_file_is_materialized_and_scannable).
  • cargo fmt --all --check, cargo clippy -p compliance-agent -- -D warnings clean.
  • Dashboard compiles under both server and web features.

🤖 Generated with Claude Code

Delivers PLC projects (and other blob artifacts) to the agent by **file upload**, completing the SPS/PLC onboarding demo path: onboard a PlcSps target → upload the PLC project → scan → findings. ## What's here - **Agent**: `POST /api/v1/targets/{id}/artifacts/upload` (axum multipart). Stores the uploaded bytes and `$push`es a `PlcProject`/firmware/source/mobile artifact (with `stored_path` + `size_bytes` + `plc_format`) onto the target. - **Dashboard**: `upload_target_artifact` server fn (reqwest multipart) + a wizard file input for blob artifact kinds, with a PLC-format selector; files are staged in the wizard and uploaded after the target is created. - **Ingest fix**: a single uploaded `.st`/`.xml` (not a zip) was content-addressed to an **extensionless** blob, so the PLC scanner's extension-based discovery skipped it (zero findings). Ingest now materializes a non-archive blob into the work dir under its original file name, so `analyze_tree` finds it and reports a readable path. New unit test covers upload → ingest → scan. ## Verification - `cargo test -p compliance-agent --lib` (ingest + plc suites green, incl. the new `single_uploaded_plc_file_is_materialized_and_scannable`). - `cargo fmt --all --check`, `cargo clippy -p compliance-agent -- -D warnings` clean. - Dashboard compiles under both `server` and `web` features. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sharang added 2 commits 2026-07-16 09:34:21 +00:00
Add a real file-upload path so PLC projects (and other blob artifacts:
firmware images, source archives, mobile packages) can be delivered to
the agent instead of referencing a local path.

- agent: POST /api/v1/targets/{id}/artifacts/upload (axum multipart);
  stores bytes under {artifact_store_base_path}/uploads/{id}/... and
  $push-es the artifact (with stored_path + size_bytes) onto the target.
- dashboard: upload_target_artifact server fn (reqwest multipart) + wizard
  file input for blob artifact kinds, with a PLC format selector.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(ingest): materialize single-file PLC uploads so the scanner finds them
CI / Check (pull_request) Successful in 6m42s
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
c8ab5177bb
A PlcProject uploaded as a single .st/.xml file (not a zip) was stored as a
content-addressed blob with no extension, so the PLC scanner's extension-based
file discovery skipped it — an uploaded project produced zero findings.

When an "extractable" blob turns out not to be an archive, materialize it into
the artifact work dir under its original file name (from source_ref, which the
upload handler sets to the uploaded filename). analyze_tree then discovers it by
extension and reports a readable path. Falls back to the raw blob if the copy
fails. Covers the demo's upload -> scan path end to end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sharang merged commit afa5c985ee into main 2026-07-16 09:41:13 +00:00
sharang deleted branch feat/artifact-file-upload 2026-07-16 09:41:13 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sharang/compliance-scanner-agent#163