# Real Image Manifest Validator v0.1.0

Offline manual n8n template for checking one or two supplied JPEG/PNG files against a reviewed manifest. It performs byte integrity checks and requires alt text, credit and a permission note. It never fetches images, calls a model or approves publication.

Licence: **MIT** — see [LICENSE](n8n-real-image-manifest-validator-LICENSE.txt) and [licence scope](n8n-real-image-manifest-validator-NOTICE.md). The MIT grant covers this module’s workflow code and documentation; it does not grant rights to image fixtures or third-party marks. The premium product licence remains separate. Include the licence notice when redistributing the JSON.

Download: `/downloads/n8n-real-image-manifest-validator.json`; licence: `/downloads/n8n-real-image-manifest-validator-LICENSE.txt`; scope notice: `/downloads/n8n-real-image-manifest-validator-NOTICE.md`.

## Import and configure

1. Import `workflow.json` (website download: `/downloads/n8n-real-image-manifest-validator.json`) into a new n8n workflow and keep it inactive.
2. Read **Supply reviewed image bytes**. Its bytes field is intentionally empty: an unconfigured run must stop with `Missing image data`. The downloadable template embeds no image bytes.
3. Supply your own image as canonical base64 in `asset_files['assets/imagem-1.jpg'].data`, together with its lowercase SHA-256 in both the file and manifest entries. Set `bytes` to the decoded byte length. Update MIME, path, alt, caption and permission note for that exact file. The file must be genuinely reviewed; populated strings do not prove permission.
4. For a reproducible local demonstration, use the already-published [first AI brief screenshot](https://theaicontentmachine.company/images/articles/2026-09-29/b01-first-brief-canvas.jpg). The example metadata identifies this file: 77,002 bytes; SHA-256 `2f24b4b340a6fda421fc59bccf112737118f9b0f8f93427858322d1d4cbc36df`. The validator does not download it. Its provenance is recorded in `fixture-provenance.json`; public visibility alone is not permission for other uses.
5. Execute manually. Expected: `assets_valid`, `image_count: 1`, `byte_integrity_verified: true`, `rights_verified_by_code: false`, `image_decoding_verified: false`, `publication_approved: false`.

Node.js preparation example, run only on an image you are allowed to process (no network):

```js
const fs = require('node:fs');
const crypto = require('node:crypto');
const bytes = fs.readFileSync('your-reviewed-image.jpg');
const sha256 = crypto.createHash('sha256').update(bytes).digest('hex');
// Keep this output local; paste only into your authorised private n8n workspace.
const file = { data: bytes.toString('base64'), sha256 };
console.log(JSON.stringify({ bytes: bytes.length, file }));
```

## Contract and strict limits

- Exactly 1–2 asset objects and matching `asset_files` entries; extra files and duplicate paths are rejected
- Paths: only `assets/imagem-1.jpg`, `assets/imagem-2.jpg`, `assets/imagem-1.png`, `assets/imagem-2.png`. No traversal, absolute paths or URLs
- JPEG (`image/jpeg`, `.jpg`) or PNG (`image/png`, `.png`), from 1 byte up to 2 MiB **inclusive**, subject to signature checks
- Base64 must be canonical, padded where required, with no whitespace or data-URL prefix. Its encoded size is checked before decoding
- Declared decoded length, MIME, extension, initial byte signature and both SHA-256 values must agree with the actual bytes
- Nonempty `content_id`, `alt`, `caption` and `permission_note`, each at most 2,000 characters

**Important:** a matching signature is not a full image decode. Truncated, corrupt or specially crafted bytes may share a JPEG/PNG signature. Open each image in a trusted viewer and separately check relevance, legibility, personal information, attribution and permission. The code does not authenticate reviewers or verify legal rights. Hashes prove consistency with the supplied manifest, not authenticity, safety, ownership or prior approval.

## Negative test and recovery

After a valid run, blank `permission_note` and confirm the validator stops. Restore the note and confirm success. Then change one byte without updating the hashes and confirm integrity rejection; restore the exact approved bytes and rerun. If an image genuinely changes, review it again before preparing a new manifest. Do not just recalculate hashes to bypass a failure.

## Runtime and data handling

Requires n8n's JavaScript Code node with `Buffer` and the built-in `crypto` module. [n8n documents crypto availability on Cloud](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code); self-hosted module policy must allow it. This template does not change server security settings.

There are no credentials, pinned data, schedules, filesystem reads, remote fetches or LLM calls in the export. Successful output omits base64 and unrelated input fields. Input bytes are still visible inside your n8n run; disabling saved execution data does not hide editor data or erase existing history. Inspect retention and logging before providing any private image. The sample export requests no success/error/manual execution saving. Never publish a configured export containing private bytes.

## Tests and provenance

Run `node --test automation/editorial/image-manifest.test.cjs`. Tests use the exact previously approved screenshot for the real positive case. Size/signature boundary fixtures are synthetic byte buffers and **not** evidence that a real image decodes. Code-node tests exercise the exported JavaScript with a restricted local harness; that evidence is separate from the live n8n runs. The fresh n8n 2.39.6 import passed the real-image case, rejected an empty permission note, rejected a manifest SHA-256 of 64 zeros while the original bytes stayed unchanged, and accepted the restored exact sample. The live integrity-negative case changed the manifest hash; byte mutation is covered in local tests. The isolated test workflow was then saved with the canonical empty-byte sample; it correctly stopped with Missing image data and remained manual-only/unpublished. These observations apply to the recorded validator hash, not all n8n versions or images. The current result and release gates are recorded in `docs/free-workflow-candidates-2026-09-30.json`.

Live-test limitation: the n8n export-download step could not be completed in the test browser. The canonical template and deployed download are byte-checked separately; no post-save runtime-export audit is claimed.

Live-tested validator JavaScript SHA-256: `4504b5380928a112c00f7c95f65536afe2fdb394b5e6eb60d63874adc4cd1a49`. The release export changes the top-level version name only; executable nodes and sample input are unchanged.
