Build GE-Enforce manifest-store plugin (P0/P1): model, importer, parity gate
All checks were successful
CI / backend (push) Successful in 1m36s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s

First execution phases of docs/proposals/ge-enforce-plugin.md. The GE-Enforce
manifest becomes shopdb data.

P0 scaffold: new geenforce plugin (api_prefix /api/geenforce, default_enabled
false, core_version >=0.7.0). Registered in PLUGIN_TABLE_OWNERS (ADR-008); its
0001 baseline really creates the tables.

P1a model: one wide manifestentries table + entrytype discriminator (not STI,
not JSON blob), manifestscopes (UNIQUE scopename+phase), the three multi-value
filter child tables, inusechecks + processes, immutable manifestpublishedversions
(frozen rendered JSON), manifestpayloads (inline, capped), pctypealiases
(mirror of the engine lib's alias graph). regvalue stored as its raw JSON
literal so DWord typing survives.

P1c importer + exporter: parse common + gea-shopfloor-* + preinstall.json into
draft rows and rebuild the JSON verbatim from rows in sortorder.

P1d parity harness (GATE A): filters.py mirrors the engine's four filter
functions + alias graph; parity.py proves import+export is behaviorally lossless
(field-identical + same-entries-fire across 18 machine-profile fixtures) WITHOUT
byte-diffing. Verified PASS against all 11 real reference manifests (64 entries)
and a synthetic site-neutral fixture covering every type/filter (the CI gate).

First slice (gea-shopfloor-cmm shape): service layer (import/publish/rollback/
export-to-share), CLI (parity, import-share, publish, export-share), and the
client endpoint GET /api/geenforce/manifest serving the current published
snapshot (never the draft) with ETag/304. Split permissions
geenforce.manage/publish/fetch. Tests prove import->publish->serve, draft edits
never change served bytes, publish+rollback, and auth (401 unauth/wrong-scope).

Contract 0.11.0: added service_token_authorized(scope) to shopdb.api so plugin
service endpoints authorize a scoped managed token without importing core token
internals. Documented in PLUGIN-HOOKS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-12 16:53:18 -04:00
parent cf2f9c308e
commit d85b33bd68
24 changed files with 1830 additions and 3 deletions

View File

@@ -0,0 +1,20 @@
[
{"label": "collections-okuma-bay", "pctype": "gea-shopfloor-collections", "subtype": "Machine", "hostname": "WJPC0615", "machinenumber": "3201", "cmmversion": ""},
{"label": "collections-mtconnect-bay", "pctype": "gea-shopfloor-collections", "subtype": "Machine", "hostname": "WJPC7501", "machinenumber": "7501", "cmmversion": ""},
{"label": "collections-other-bay", "pctype": "gea-shopfloor-collections", "subtype": "Machine", "hostname": "WJPC0001", "machinenumber": "0001", "cmmversion": ""},
{"label": "nocollections", "pctype": "gea-shopfloor-nocollections", "subtype": "", "hostname": "WJPC2000", "machinenumber": "", "cmmversion": ""},
{"label": "common-timeclock", "pctype": "gea-shopfloor-common", "subtype": "", "hostname": "WJPC3000", "machinenumber": "", "cmmversion": ""},
{"label": "cmm-2016", "pctype": "gea-shopfloor-cmm", "subtype": "", "hostname": "WJCMM01", "machinenumber": "9101", "cmmversion": "2016"},
{"label": "cmm-2019", "pctype": "gea-shopfloor-cmm", "subtype": "", "hostname": "WJCMM02", "machinenumber": "9102", "cmmversion": "2019"},
{"label": "cmm-2026", "pctype": "gea-shopfloor-cmm", "subtype": "", "hostname": "WJCMM11", "machinenumber": "9111", "cmmversion": "2026"},
{"label": "cmm-noversion-legacy", "pctype": "gea-shopfloor-cmm", "subtype": "", "hostname": "WJCMM99", "machinenumber": "9199", "cmmversion": ""},
{"label": "keyence-vr6000", "pctype": "Keyence", "subtype": "vr6000", "hostname": "WJKEY01", "machinenumber": "8001", "cmmversion": ""},
{"label": "keyence-vr3000", "pctype": "Keyence", "subtype": "vr3000", "hostname": "WJKEY02", "machinenumber": "8002", "cmmversion": ""},
{"label": "genspect", "pctype": "gea-shopfloor-genspect", "subtype": "", "hostname": "WJGEN01", "machinenumber": "8100", "cmmversion": ""},
{"label": "heattreat", "pctype": "gea-shopfloor-heattreat", "subtype": "", "hostname": "WJHT01", "machinenumber": "8200", "cmmversion": ""},
{"label": "waxtrace", "pctype": "gea-shopfloor-waxtrace", "subtype": "", "hostname": "WJWAX01", "machinenumber": "8300", "cmmversion": ""},
{"label": "partmarker", "pctype": "gea-shopfloor-partmarker", "subtype": "", "hostname": "WJPM01", "machinenumber": "8400", "cmmversion": ""},
{"label": "display", "pctype": "gea-shopfloor-display", "subtype": "", "hostname": "WJDISP01", "machinenumber": "", "cmmversion": ""},
{"label": "legacy-standard-machine", "pctype": "Standard", "subtype": "Machine", "hostname": "WJLEG01", "machinenumber": "3202", "cmmversion": ""},
{"label": "legacy-cmm-name", "pctype": "CMM", "subtype": "", "hostname": "WJLEG02", "machinenumber": "9102", "cmmversion": "2019"}
]