From 16c1b5f19206b13d8a43d09becaa319450d0f3d6 Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 17 Oct 2026 16:37:22 +0200 Subject: [PATCH] docs: publish sanitized installer analysis --- README.md | 1 + docs/research/config-comparison.md | 41 +++++++++++++++++++++ docs/research/installer-inventory.md | 9 +++-- docs/research/machine-profile.yaml | 21 +++++++---- evidence/public-installer-configs.jsonl | 9 +++++ tests/test_public_evidence.py | 49 +++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 docs/research/config-comparison.md create mode 100644 evidence/public-installer-configs.jsonl create mode 100644 tests/test_public_evidence.py diff --git a/README.md b/README.md index 64bfe7b..55e5063 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Start with: - [Data handling policy](docs/data-handling.md) - [LightBurn collection checklist](docs/collection/lightburn.md) - [Sanitized machine profile](docs/research/machine-profile.yaml) +- [110/300 configuration comparison](docs/research/config-comparison.md) - [Repository boundary decision](docs/adr/0001-public-private-repository-boundary.md) ## Validation diff --git a/docs/research/config-comparison.md b/docs/research/config-comparison.md new file mode 100644 index 0000000..7c8b397 --- /dev/null +++ b/docs/research/config-comparison.md @@ -0,0 +1,41 @@ +# EZCAD2 110 mm / 300 mm configuration comparison + +- Date: 2026-10-17 +- Method: offline byte comparison and parsing of text configuration only +- Private evidence snapshot: commit `50e589c` + +No executable, DLL, plugin, driver, or machine command was run. + +## Result + +Each lens tree contains 101 files. Ninety-five files are byte-identical and six +differ: `AUTOSAVE.ezd`, `cfglog.txt`, `Custom.ini`, `EZCAD.CFG`, `Usb.log`, and +`plug/markcfg7`. There are no files missing from either tree. + +| Artifact | 110 mm | 300 mm | Observation | +| --- | ---: | ---: | --- | +| `markcfg7` | 10,423 bytes; `sha256-4bc09e50d3d0de8652df` | 10,425 bytes; `sha256-f5a88d31a882a56bcfd9` | Opaque binary profiles; only 49 leading bytes and 4,522 trailing bytes are shared. Treat each as an indivisible lens-specific profile. | +| `CoeFile.cfg` | 68,608 bytes; `sha256-05d2e8982a2dc64d6778` | Same content and hash | This correction file is shared by both supplied profiles. | +| `EZCAD.CFG` | `sha256-93bdf1d8da34312e57f4` | `sha256-eaf64932c2bee2cbc470` | Workspace is centered at ±55 mm versus ±150 mm. The remaining semantic differences are lens-tree plugin paths, which are redacted here. | +| `Usb.log` | 7,728 bytes; `sha256-e01aff572dcd39b51e6d` | 7,774 bytes; `sha256-b57cf786d2bbe29841b0` | The 110 mm file is an exact prefix of the 300 mm file; the extra 46 bytes look like appended log state, not a lens parameter. | + +The differences in autosave, configuration log, and custom-state files are +likely session history rather than authoritative hardware configuration. This +is an inference from their role and filenames, not yet a decoded format claim. + +## Controller metadata + +The supplied Windows driver metadata identifies the controller family as a JCZ +USB laser-marking controller using the `Lmcv2u` driver family. It declares USB +VID `9588` and PID `9899`. This is installer evidence only and remains pending +verification against the connected machine in Windows Device Manager. + +Evidence: `sha256-ebfe631958b9522533ff` and +`sha256-17ac4330cec7bc49b672`. + +## Safety consequence + +Do not synthesize a new profile by editing offsets inside `markcfg7`, and do not +assume the shared correction file makes the two profiles interchangeable. The +first implementation must parse and report before it can write or transmit any +configuration. diff --git a/docs/research/installer-inventory.md b/docs/research/installer-inventory.md index 43d1486..68bdaa9 100644 --- a/docs/research/installer-inventory.md +++ b/docs/research/installer-inventory.md @@ -1,7 +1,7 @@ # Original installer-stick inventory -Status: preliminary metadata inventory; content hashes are pending private -acquisition. +Status: acquired, hashed, and preserved in private evidence snapshot commit +`50e589c`. The read-only source contains an EZCAD2 2.14.16 installation configured for a JPT 100 W E2/M7 source. Separate 110 mm and 300 mm configurations are present. @@ -19,5 +19,6 @@ All originals and exact source locators belong in PrivateStash. This public inventory intentionally omits serial numbers, Drive identifiers, executable copies, and manual copies. -The detailed comparison report will be added only after the private snapshot is -hashed and verified. +See the [sanitized 110/300 comparison](config-comparison.md) and +[`evidence/public-installer-configs.jsonl`](../../evidence/public-installer-configs.jsonl) +for traceable public hashes. diff --git a/docs/research/machine-profile.yaml b/docs/research/machine-profile.yaml index 849d021..e68a481 100644 --- a/docs/research/machine-profile.yaml +++ b/docs/research/machine-profile.yaml @@ -23,18 +23,23 @@ lightburn: build: null status: pending-collection usb: - vid: null - pid: null - driver: null - status: pending-collection + vid: "9588" + pid: "9899" + driver: Lmcv2u + status: installer-metadata-observed-pending-live-verification safety: phase_0_hardware_commands_allowed: false phase_0_laser_output_allowed: false evidence: - - artifact_id: pending-installer-110-markcfg7 - sha256: null - - artifact_id: pending-installer-300-markcfg7 - sha256: null + - artifact_id: sha256-4bc09e50d3d0de8652df + sha256: 4bc09e50d3d0de8652dfd0d4617bc69c85e5be22b1598eab097e042339f8fcbd + role: ezcad2-110-markcfg7 + - artifact_id: sha256-f5a88d31a882a56bcfd9 + sha256: f5a88d31a882a56bcfd9f69af9112438cbb8b21e50fa8c8d546ff1060f9a7ffd + role: ezcad2-300-markcfg7 + - artifact_id: sha256-ebfe631958b9522533ff + sha256: ebfe631958b9522533ffb1e78c8961073e3549039053ea0d56e4c82cfe8bff83 + role: jcz-windows-driver-metadata notes: - No complete serial numbers or private source locators are stored here. - Incorrect galvo or source configuration can damage hardware; values are not inferred by trial and error. diff --git a/evidence/public-installer-configs.jsonl b/evidence/public-installer-configs.jsonl new file mode 100644 index 0000000..fc08a72 --- /dev/null +++ b/evidence/public-installer-configs.jsonl @@ -0,0 +1,9 @@ +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-4bc09e50d3d0de8652df","classification":"private-third-party","media_type":"application/octet-stream","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"4bc09e50d3d0de8652dfd0d4617bc69c85e5be22b1598eab097e042339f8fcbd","size_bytes":10423} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-f5a88d31a882a56bcfd9","classification":"private-third-party","media_type":"application/octet-stream","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"f5a88d31a882a56bcfd9f69af9112438cbb8b21e50fa8c8d546ff1060f9a7ffd","size_bytes":10425} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-05d2e8982a2dc64d6778","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"05d2e8982a2dc64d6778e5db5a8370e28ff49d07f304b9189e6724249cf37d86","size_bytes":68608} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-93bdf1d8da34312e57f4","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"93bdf1d8da34312e57f453758c165efd92916b82c9f239730f0793eeedd9b7f0","size_bytes":12683} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-eaf64932c2bee2cbc470","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"eaf64932c2bee2cbc470f93c1b8281fbf7819ea9c339a10fae219e2fa0bbc9b6","size_bytes":12683} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-e01aff572dcd39b51e6d","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"e01aff572dcd39b51e6d84c95fe1042f2a8d2c66517aac4769a86b700d2ca247","size_bytes":7728} +{"analysis_refs":["docs/research/config-comparison.md"],"artifact_id":"sha256-b57cf786d2bbe29841b0","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"b57cf786d2bbe29841b002f47561b49c0422c054506a22e89dcfc2083e9d74a0","size_bytes":7774} +{"analysis_refs":["docs/research/config-comparison.md","docs/research/machine-profile.yaml"],"artifact_id":"sha256-ebfe631958b9522533ff","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"ebfe631958b9522533ffb1e78c8961073e3549039053ea0d56e4c82cfe8bff83","size_bytes":2574} +{"analysis_refs":["docs/research/config-comparison.md","docs/research/machine-profile.yaml"],"artifact_id":"sha256-17ac4330cec7bc49b672","classification":"private-third-party","media_type":"text/plain","observed_at_utc":"2026-10-17T14:32:32Z","origin":"private-evidence-snapshot-2026-10-17","sha256":"17ac4330cec7bc49b6727e1cfed97844f8f3d28a0583f6243259a6323e63d82b","size_bytes":116} diff --git a/tests/test_public_evidence.py b/tests/test_public_evidence.py new file mode 100644 index 0000000..2dd2f0d --- /dev/null +++ b/tests/test_public_evidence.py @@ -0,0 +1,49 @@ +import json +import re +import unittest +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +class PublicEvidenceTests(unittest.TestCase): + def test_public_evidence_matches_manifest_contract(self) -> None: + schema = json.loads( + (ROOT / "schemas" / "artifact-manifest.schema.json").read_text(encoding="utf-8") + ) + required = set(schema["required"]) + allowed = set(schema["properties"]) + artifact_pattern = re.compile(schema["properties"]["artifact_id"]["pattern"]) + digest_pattern = re.compile(schema["properties"]["sha256"]["pattern"]) + classifications = set(schema["properties"]["classification"]["enum"]) + + lines = (ROOT / "evidence" / "public-installer-configs.jsonl").read_text( + encoding="utf-8" + ).splitlines() + self.assertEqual(len(lines), 9) + + for line in lines: + entry = json.loads(line) + self.assertFalse(required - set(entry)) + self.assertFalse(set(entry) - allowed) + self.assertRegex(entry["artifact_id"], artifact_pattern) + self.assertRegex(entry["sha256"], digest_pattern) + self.assertEqual(entry["artifact_id"], f"sha256-{entry['sha256'][:20]}") + self.assertIn(entry["classification"], classifications) + self.assertNotIn("relative_path", entry) + self.assertNotIn("source_locator", entry) + + def test_public_evidence_has_unique_content_ids(self) -> None: + entries = [ + json.loads(line) + for line in (ROOT / "evidence" / "public-installer-configs.jsonl") + .read_text(encoding="utf-8") + .splitlines() + ] + ids = [entry["artifact_id"] for entry in entries] + self.assertEqual(len(ids), len(set(ids))) + + +if __name__ == "__main__": + unittest.main()