Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a44e9cd
Replace Asset Profiles with Asset Rubrics placeholder
Apr 19, 2026
d46ffb7
Port C2PA asset rubrics to the browser and wire them into ReportViewer
Apr 20, 2026
6f27f55
Add sidecar file support
andyparsons Apr 20, 2026
fa3b2a3
Wire sidecar+asset UI: pending state prompt, multi-file drops, re-pro…
andyparsons Apr 20, 2026
9c8052e
Switch app font from DM Sans to Inter
andyparsons Apr 21, 2026
3f82472
Port rubric evaluator from JMESPath to json-formula
andyparsons Apr 21, 2026
eab9b65
Sync rubrics with upstream and normalize bare bool/null keywords
andyparsons Apr 25, 2026
77fcc33
Source ManifestSummary from signals rubric; loosen Rubrics tab gate
andyparsons Apr 26, 2026
8104ad9
restores some colors for message statuses
andyparsons Apr 27, 2026
d27c70b
Remove low-value fields from report view
andyparsons May 4, 2026
ceafd61
UI with tree view WIP
andyparsons May 5, 2026
b5e4eff
Add pan/zoom canvas to tree view; fix ingredient thumbnails
andyparsons May 5, 2026
a740358
Disable node click-to-focus in tree view
andyparsons May 5, 2026
e3cbd89
Tree view: curved SVG connectors, adaptive canvas height, sharp zoom
andyparsons May 5, 2026
b48b327
Fix initial tree zoom: root card always 200px wide
andyparsons May 5, 2026
d13fc6d
feat: group validation status by manifest and improve failure reporting
sherifhanna-google May 6, 2026
c4dede6
Fix viewport layout: tree fills height, all tabs consistent width
andyparsons May 6, 2026
4f4efd7
Fix hero/drop-target width: add w-full to max-w-5xl container
andyparsons May 6, 2026
1727c90
Merge remote-tracking branch 'origin/main' into simplifying-ui
andyparsons May 6, 2026
70d9626
Merge remote-tracking branch 'sherifhanna/failure-ui-fixes' into simp…
andyparsons May 6, 2026
365cbca
Remove Provenance section from Report tab (redundant with Summary tree)
andyparsons May 6, 2026
c270028
Load Inter from Google Fonts so it actually renders
andyparsons May 6, 2026
64b5974
Fix failing tests: add ResizeObserver mock and click Report tab
andyparsons May 6, 2026
13167bc
Fix no-manifest files showing as errors instead of informational state
andyparsons May 7, 2026
fae96fa
Improve tree node labels: wider cards, date, relationship, all actions
andyparsons May 7, 2026
b6ac2d0
Show uncredentialed ingredients as stub nodes in the provenance tree
andyparsons May 7, 2026
dbbbc30
Fix validation error box width in summary view
andyparsons May 7, 2026
d02f559
Sync rubrics from canonical conformance repo; update golden fixtures
andyparsons May 7, 2026
a637b5f
Always show Rubrics tab, removing the trusted-only gate
andyparsons May 7, 2026
551278d
Prevent drag on tree nodes from triggering the file drop overlay
andyparsons May 7, 2026
c809609
Simplify sidecar flow: use packaged SDK only, no local WASM requirement
andyparsons May 8, 2026
371e5cf
Fix sidecar hash mismatch: always use packaged SDK for .c2pa files
andyparsons May 8, 2026
79f7ec6
Re-wire sidecar+asset hash verification via local WASM
andyparsons May 8, 2026
372419b
Sidecar-only inspection: validate manifest integrity without the asset
deblanco May 11, 2026
d3ba273
Remove synthetic soft-vs-hard binding consistency check
deblanco May 12, 2026
72e62bd
Support arbitrary asset types in sidecar+asset validation
deblanco May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@ npm run copy:profile-evaluator # Copy profile evaluator from ../profile-evaluat

**`src/lib/types.ts`** — `ConformanceReport` extends `CrJson` with conformance-specific fields: `usedITL`, `usedTestCerts`, and `_conformanceToolVersion` (git metadata injected at build time).

**`src/lib/profileEvaluator.ts`** — Dynamically imports the profile evaluator WASM from `public/profile-evaluator/`. Used by `AssetProfilePage.svelte`.
**`src/lib/rubrics/`** — Client-side evaluator for YAML-authored C2PA asset rubrics. Ported from the Python reference at `../../c2pa/conformance/asset-rubrics`. See the Rubrics section below for details.

**`src/lib/version.ts`** — Auto-generated before each build/dev start via `scripts/generate-version.js`. Do not edit manually.

### Routing
`App.svelte` handles navigation between three pages:
`App.svelte` handles navigation between two pages:
- Main validation page (default)
- Test Certificates (`CertificateManager.svelte`)
- Asset Profiles (`AssetProfilePage.svelte`)

### WASM Modules
Two WASM binaries are committed to `public/`:
One WASM binary is committed to `public/`:
- `public/c2pa.wasm` — Official C2PA reader (copied from `@contentauth/c2pa-web` during `postinstall`)
- `public/profile-evaluator/` — Profile evaluator (from sibling `profile-evaluator-rs` repo, updated via `copy:profile-evaluator` script)

(`public/profile-evaluator/` is a legacy directory — the profile-evaluator page was removed when Rubrics replaced it. Safe to delete when convenient.)

### Trust Lists
- **C2PA Trust List**: Fetched at runtime from GitHub
Expand Down
3 changes: 3 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="C2PA Verify - Content Credentials Validator and Conformance Testing Tool. Verify C2PA manifests against official trust lists." />
<title>C2PA Verify</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
Expand Down
21 changes: 16 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@tsconfig/svelte": "^5.0.2",
"@vitest/ui": "^4.0.18",
"autoprefixer": "^10.4.23",
"gh-pages": "^6.2.0",
"happy-dom": "^20.4.0",
"jsdom": "^27.4.0",
"postcss": "^8.5.6",
Expand All @@ -36,8 +37,10 @@
"vitest": "^4.0.18"
},
"dependencies": {
"@adobe/json-formula": "^2.0.0",
"@contentauth/c2pa-web": "^0.6.1",
"@peculiar/x509": "^1.14.3",
"highlight.js": "^11.11.1"
"highlight.js": "^11.11.1",
"yaml": "^2.8.3"
}
}
46 changes: 41 additions & 5 deletions public/local-c2pa/c2pa_local.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,59 @@ export function init(): void;

export function read_manifest_store(file_bytes: Uint8Array, format: string, settings_json?: string | null): Promise<string>;

/**
* Inspect a detached (`.c2pa`) manifest store without an asset.
*
* Used when the user drops a sidecar without the matching asset. We feed
* the manifest bytes to `with_manifest_data_and_stream_async` paired with
* an empty stream. The signature, certificate chain, and JUMBF structure
* are validated normally; the asset-hash bindings will report
* `assertion.dataHash.mismatch` because there is no asset to bind to —
* that is expected, and callers should label this as an integrity-only
* inspection in the UI.
*
* * `manifest_bytes` - raw bytes of the `.c2pa` sidecar (JUMBF manifest store).
* * `settings_json` - trust settings (same shape as `read_manifest_store`).
*/
export function read_sidecar_integrity_only(manifest_bytes: Uint8Array, settings_json?: string | null): Promise<string>;

/**
* Validate a detached (`.c2pa`) manifest store against its referenced asset.
*
* This is the sidecar-with-asset case: the C2PA manifest lives in its own file
* (`manifest_bytes`) and the asset whose hash-bindings the manifest claims
* lives separately (`asset_bytes`). We feed both into c2pa-rs's
* `with_manifest_data_and_stream_async`, which evaluates the asset-hash
* assertions *against the actual asset bytes* — something we cannot do with
* the single-blob `read_manifest_store` path.
*
* * `manifest_bytes` - raw bytes of the `.c2pa` sidecar (JUMBF manifest store).
* * `asset_bytes` - raw bytes of the referenced asset.
* * `asset_format` - MIME type of the asset (e.g. "image/jpeg"). The
* sidecar's own format is always `application/c2pa` and the SDK infers that.
* * `settings_json` - trust settings (same shape as `read_manifest_store`).
*/
export function read_sidecar_manifest_store(manifest_bytes: Uint8Array, asset_bytes: Uint8Array, asset_format: string, settings_json?: string | null): Promise<string>;

export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;

export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly get_version: () => [number, number];
readonly init: () => void;
readonly read_manifest_store: (a: number, b: number, c: number, d: number, e: number, f: number) => any;
readonly wasm_bindgen__closure__destroy__h0667ea7aa0a255a7: (a: number, b: number) => void;
readonly wasm_bindgen__convert__closures_____invoke__hca39902318df4249: (a: number, b: number, c: any) => [number, number];
readonly wasm_bindgen__convert__closures_____invoke__h2986024ebf27e018: (a: number, b: number, c: any, d: any) => void;
readonly wasm_bindgen__convert__closures_____invoke__hdd2e4c5eb311bd94: (a: number, b: number) => void;
readonly read_sidecar_manifest_store: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => any;
readonly read_sidecar_integrity_only: (a: number, b: number, c: number, d: number) => any;
readonly get_version: () => [number, number];
readonly wasm_bindgen__convert__closures_____invoke__h1aa715c00eec31bd: (a: number, b: number, c: any) => [number, number];
readonly wasm_bindgen__convert__closures_____invoke__h0ef758fe9ac3980a: (a: number, b: number, c: any, d: any) => void;
readonly wasm_bindgen__convert__closures_____invoke__h2b3ed67cbe4afe0c: (a: number, b: number) => void;
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_exn_store: (a: number) => void;
readonly __externref_table_alloc: () => number;
readonly __wbindgen_externrefs: WebAssembly.Table;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
readonly __externref_table_dealloc: (a: number) => void;
readonly __wbindgen_start: () => void;
}
Expand Down
Loading