Files
shopdb-flask/docs/PROJECT-REVIEW.md
cproudlock ee083ea80e docs: stop publishing internal references to a public wiki
docs/ is excluded from the code bundle and its scrub gate, because it goes to
the GitHub wiki instead - via a generator that has no gate at all. So the one
part of the repository written in prose, by people, about internal
infrastructure, was the one part nothing checked.

What was reaching a public wiki: the internal git server's URL and hostname,
.gitea workflow paths, developer home directories in the GE-Enforce cutover
reference, and a dev database root password inside a copy-pasteable command in
the import guide.

All replaced with neutral equivalents. tests/test_docs_publishable.py is now the
gate, at the source, in CI - a wiki page cannot be un-published, so catching this
after the fact is not good enough.

PROJECT-REVIEW.md also referred to internal tooling by name throughout; those
references are generalised. It remains an internal candid assessment of this
project that is nonetheless published, which is worth a separate decision.
2026-08-03 15:12:25 -04:00

8.4 KiB

ShopDB Flask - Project Health Review

As of HEAD ecf4ef6 (2026-07-30), product __version__ 0.7.0, contract __contract_version__ 0.15.0 (verified in shopdb/__init__.py).

1. Executive Summary

Overall: healthy engineering, drifting focus. The stated product vision ("plugin system is the product," the project brief) is delivered: all 7 refactor phases are done, 13 bundled plugins are contract-compliant, the per-plugin migration regime (ADR-008) is live and exercised (geenforce is at geenforce0002blobs, proving the post-cutover chain works in anger), and CI enforces naming, contract, and real-MySQL migration idempotency. Test count grew 1077 -> 1159 since the last the project brief snapshot.

The concern is not quality but trajectory. the project brief and ROADMAP.md both name the last big milestone before 1.0 as "legacy-ASP data import + production pilot." The loader is built and VM-validated (16 stages, scripts/site_imports/wjf/), but the prod run has not happened, and ~35 of the last 60 commits went to the GE-Enforce HTTPS cutover instead. That work is legitimate and high-value, but it is feature/fleet work on one plugin, and it has accumulated two process debts that violate the project's own discipline: the cutover playbook (docs/geenforce-api-cutover.md) is the only dirty file in the repo and is untracked, and the prod-patch-geenforce robocopy fast-path can leave prod ahead of git.

Verdict: on track against standards, behind against goals. The 1.0 gate has four items; only one is arguably done, and the roadmap doc does not know it.

2. Standards Compliance

Rule Status Evidence
Naming (tables/columns/vars, CONTRIBUTING.md) MET scripts/check-naming-and-style.sh present and executable; dedicated naming job in the internal CI workflow. One borderline: asset.py:175 documents a derived API key location_name with an underscore - not a DB-mirrored column so likely legal, but worth a glance since "response keys match column names exactly" is the spirit of the rule.
Plugin contract (manifest.json, BasePlugin, shopdb.api only) MET 13 plugins/*/manifest.json verified; contract test suites in tests/; contract bumped correctly to 0.15.0 for the geenforce resource-scope fetch tokens (75386d2), per ADR-002 discipline.
Migration ownership (ADR-008) MET PLUGIN_TABLE_OWNERS registry tested by tests/test_plugin_migrations.py (EXPECTED_HEAD_REVISION lines 47-51); migrations-mysql CI job does fresh utf8mb4 MySQL 8 upgrade + all plugin chains + second-upgrade-no-op assertion. The geenforce 0002blobs revision shows the per-plugin chain is being used as designed, not just anchored.
Versioning/release discipline (ADR-007) AT RISK Tags through v0.7.0 exist and contract bumps are disciplined, but the documentation half of the procedure has drifted - see Gaps 3.
ADRs canonical, new priorities get an ADR AT RISK 14 ADRs present. But lean per-site builds are half-shipped (ADR-014 ACCEPTED and implemented; default_enabled: false on 5 plugins) while ADR-013, which defines the catalog/tiers/signed-artifact model those builds imply, is still PROPOSED. The GE-Enforce HTTPS cutover itself - a major architectural shift off the SMB share - lives in an untracked doc, not an ADR or ADR-012 amendment.
Style (plain ASCII, no emojis, comment discipline) MET Enforced by the same pre-commit hook + CI naming job.
Everything in git / repo as source of truth VIOLATED docs/geenforce-api-cutover.md untracked (only dirty file, verified git status); prod-patch-geenforce robocopy path acknowledged in-doc as leaving prod ahead of git.

3. Roadmap Status

Done: Phases 0-6 (contract lock through multi-site distribution, tags v0.5.0-v0.7.0). Legacy import machinery complete: docs/IMPORT-API.md contract, 16-stage wjf loader VM-validated. Air-gapped deploy kit (6534590).

1.0 must-haves (ROADMAP.md), honestly scored:

  1. Asset model fully wired - appears DONE but unrecorded. Asset.mapx (shopdb/core/models/asset.py:121), inheritsposition (relationship.py:132), and propagation logic (relationship.py, core/api/assets.py, cli/__init__.py) are all in code. ROADMAP still lists this as outstanding. Verify the ADR-001 contract tests cover it, then strike it.
  2. Equipment data migration one-shot - NOT DONE. scripts/migration/ contains only fix_legacy_schema.sql, one-offs/, and a README. No equipment script.
  3. Printers legacy-table cleanup - NOT DONE. Recent printers commits (0d40780..c075658) are installer/feature work, not retirement.
  4. External plugin UI packaging - NOT DONE, and gate criterion 3 (one external plugin built end-to-end) has no evidence.

In-flight: GE-Enforce HTTPS cutover dominates (~35/60 recent commits). Per the cutover doc's own section 12: only displays/kiosks are on the API; cmm/collections/keyence/genspect/heattreat/partmarker/common fleet still enforce from the SFLD SMB share; loggedinuser resolution unwired; registry cleanup pending; 3DPrintRoom route is a placeholder. Secondary streams: printers install-batch, applications notes, server reclassification, TV dashboard.

Pace/scope health: Velocity is high and test coverage tracks the work (17 of ~29 plugin test files are geenforce). But the project has been at 0.7.0 with "prod pilot is the last big milestone" as the stated goal since mid-July, while shipping ~185 commits of plugin-feature work. That is a real product being used - good - but the 1.0 gate is not moving, and a half-migrated fleet (API for displays, SMB for everything else) is the worst place to pause the cutover.

4. Gaps and Risks

  1. Untracked cutover playbook (docs/geenforce-api-cutover.md). The single most valuable in-flight document is one rm away from gone, and invisible to any other machine or contributor.
  2. Prod-ahead-of-git debt. The prod-patch-geenforce fast-path means production behavior may not be reproducible from any commit. This directly undermines ADR-012's "engine is source of truth" and the release discipline of ADR-007.
  3. Documentation drift, three concrete instances (all verified): ROADMAP.md header says contract 0.13.0 (actual 0.15.0); the project brief says 1077 tests (actual 1159 collected) and claims a "lean-build" CI job that does not exist in the internal CI workflow (jobs: backend, naming, frontend, migrations-mysql - lean coverage is folded into pytest via tests/test_lean_build_guards.py). Also .github/workflows/ci.yml differs from the internal CI workflow - one of them is stale.
  4. Split-brain fleet enforcement. Displays/kiosks on the API, the rest of the fleet on the SMB share, with staged-but-unpushed manifest fixes elsewhere (MTConnect v1 stranding). Two delivery mechanisms means two failure modes and doubles the audit surface until the cutover finishes.
  5. 1.0 gate criterion 4 unproven: docs/DEPLOY.md has not been validated by an actual fresh-host prod deploy. The air-gapped kit exists; the pilot does not.
  6. ADR-013 limbo: lean builds shipped under ADR-014 while the catalog/signing model that makes external distribution safe remains PROPOSED. Fine short-term, but gate criterion 3 (external plugin) will force the question.

5. Prioritized Recommendations

  1. Commit docs/geenforce-api-cutover.md today. Zero-cost, eliminates the worst single-point-of-loss risk.
  2. Reconcile prod-patched geenforce files back into git and gate or retire the robocopy fast-path. Until prod == some tag, ADR-007 is fiction for this plugin.
  3. One doc-sync pass (30 min): ROADMAP header to 0.15.0, the project brief test count and CI job list, strike must-have (a) if contract tests confirm the Asset wiring, delete or sync the stale .github workflow.
  4. Finish the cutover or park it cleanly. Either drive the remaining fleet groups onto the API per section 12, or write down the frozen state as an ADR-012 amendment so the split-brain period is a documented decision, not drift.
  5. Schedule the prodscratch import run and prod pilot. This is the actual 1.0 milestone and everything is built for it; it validates DEPLOY.md (gate 4) for free.
  6. Pair the equipment one-shot migration with printers retirement (must-haves b and c) - they are coordinated by design; doing them together avoids touching the legacy tables twice.
  7. Decide ADR-013 before building the external-plugin end-to-end proof (gate 3); the geenforce client work is the natural seed for that external plugin.