A fresh install could not build its schema. Core revision
7d51_endpoint_logcollections creates endpointlogcollections with a foreign
key onto endpointcommands, but PLUGIN_TABLE_OWNERS lists both tables as
owned by the endpoints plugin, and only the plugin's 0002 revision creates
endpointcommands.
Core migrations run before any plugin chain, and a plugin chain only runs
once that plugin is enabled, which cannot happen before the schema exists.
So there is no ordering in which the core revision can succeed on an empty
database. MySQL rejects it with 1824, 'Failed to open the referenced table
endpointcommands'. That is the first command the README gives an adopting
site, on the branch that exists for sites to adopt.
Nothing caught it because the suite runs on sqlite:///:memory: and SQLite
accepts a foreign key onto a table that does not exist. The failure is
MySQL-only and therefore invisible to every test.
Fix:
- endpoints revision 0025 creates the table in the plugin chain, after
0002 has created its foreign key target. Guarded, so it is a no-op on
sites that already applied the core revision.
- 7d51 skips when endpointcommands is absent, which is exactly the fresh
install case 0025 then covers. Its downgrade is guarded to match.
- EXPECTED_HEAD_REVISION records the new endpoints head.
Verified against real MySQL 8.4, not SQLite: on an empty database the
README sequence now completes, 7d51 stamps without creating anything, and
enabling the endpoints plugin builds endpointlogcollections with
endpointlogcollections_ibfk_2 pointing at endpointcommands.
main was 16 days and 259 commits behind the line the product is actually built
on, at contract 0.30.0 against 0.35.0, with no per-PC credential code at all. It
was neither current nor curated - just stale. This brings it forward and, at the
same time, makes it mean something: main is what a receiving site installs, and
nothing else.
WHAT IT CARRIES. Twelve plugins - backups, computers, endpoints, guides,
knowledgebase, machines, network, notifications, printers, slides, tools,
warranty - plus applications, which is manifest-less core and always ships. The
only manifest dependency inside that set is endpoints on computers, and both are
in it, so the closure is self-contained.
WHAT IT DOES NOT. employees, geenforce, measuringtools, printedparts and usb
stay on the site line. So do the Windows installer tree, the VM rehearsal
helpers, the agent tooling config, one site's data loader, the internal audit
and findings records, and the planner spreadsheet. 1,135 tracked files against
1,438.
A REMOVAL THAT BREAKS THE APP IS NOT A REMOVAL, and two nearly shipped:
deploy/site-profile-universal.json still named all seventeen plugins. It is the
file docs/DEPLOY.md tells a site to provision from, so a fresh install would
have failed at `flask plugin apply-profile` with PluginError - the first thing a
receiving site does, broken by the branch meant to serve them. It now names the
twelve that exist, and its comment says the two must agree.
agent/ was never refreshed. Whoever populated this branch copied shopdb/,
plugins/, frontend/ and tests/ from the site line and left the agent tree at its
September state: 22 C# and PowerShell sources missing, including AgentCredentials,
EnrollmentService, AgentHttpFactory and the fleet-alert client, plus one file the
site line had deleted still present. The old tree is internally consistent, so it
compiles, and nothing in CI builds it - every gate was green over a server that
speaks enrollment and per-PC credentials to a bundled agent source that cannot.
Resynced whole.
DECISIONS THIS ENCODES, rather than defers:
- The plugin-authoring lab builds printedparts, whose manifest depends on
employees, so it could not stay. The lab remains on the site line and main
ships no build-along tutorial. That is a real loss for an adopting developer
and is recorded here rather than discovered later.
- Recognition, Training and Recertification notifications are no longer seeded.
Each splits one notification into a card per employee and renders a photo,
which needs a plugin this branch does not bundle. Seeding them would offer an
author a type that cannot resolve anybody. A site that installs employees gets
them from that plugin's own seed.
- Windows/IIS is documented as the legacy path throughout, and the README leads
with Docker, because that is what a receiving site gets.
The API description is regenerated for THIS branch - 347 paths and 483
operations, down from 415 and 573 - so the published contract describes what is
here rather than what the site line serves. docs/CONFIG.md lost the two
measuring-tool label keys the code no longer declares, which two lanes had
decided opposite ways.
Suite: 3124 passed, 6 skipped. Naming and style gates pass. The docs gates run
rather than skip, and every index line count is derived from the file it names.
Ben Baker's installed-software collection, software delivery (run_script and
update_app), agentless adoption tool and command-queue hardening, with his
authorship preserved.
Reviewed before promotion. Fixed: the endpoints plugin tests were never collected
by pytest, the SBOM snapshot table's key would exhaust on MySQL, ingest did not
truncate two columns strict MySQL would reject, and update_app's version branch
pinned a digest for a file that route never serves. Agent packaging moved off
require_role('admin') onto a new endpoints.agentpackage permission.
Contract 0.27.0. Full suite 2231, frontend 314.
Default fuzzy reconcile threshold to 0 and refuse merges when digit runs differ so numbered labels like Bay 311 never bind to Bay 310. Keep edit forms from clearing saved model fields when category filtering hides untyped rows. Includes in-progress computers policy and endpoints command feature work.
Migration tests knew no endpoints head revision, so the parametrized guards raised KeyError. Register it in EXPECTED_HEAD_REVISION.
EndpointState declared lastreportedat both index=True and an explicit db.Index over the same column, and the baseline migration named single-column indexes differently from what create_all builds. On a pre-existing table the name-keyed guard could not see the create_all index and added a duplicate, tripping the idempotency guard. Drop the redundant declaration and rename migration indexes to ix_<table>_<column> to match.
endpoints was absent from the universal site profile, so the installer would not offer it and prune-schema would drop its tables at provisioning. Add it.
The agent design record lived under docs/, which is stripped to the public wiki and normally absent from the tree; a lone file there un-skipped the wiki-publish guards. Move it into the plugin.
The merge of the Entra device-identity work added computers 0002/0003 migrations, advancing the computers head past its anchor. Update the expected-head guard to match so upgrade-all stays green.
Assign printers to a MACHINE and let whichever PC controls it install them, with
the observed half kept strictly apart from the assigned half: a collector report
can never write an assignment row. Adoption is explicit. Adds a singular
relationship type so defaultprinter can mean exactly one, client scripts that
converge a bay's queues and correct a drifted one in place, and a wave gate so a
fleet-wide driver rollout cannot stampede its own share.
On the container side: the compose stack never persisted the instance directory,
so a rebuild discarded plugins.json and every upload. It is a volume now, the
image ships instance/ owned by the app user so the mountpoint is writable, and
the database moves to MySQL 8.4 LTS, which the Windows runbook has recommended
since 8.0 went end of life. The image also could not build at all: the frontend
stage never copied the plugin staging script it runs.
Adds a topology migration guide covering IIS to Docker and back.
The gage lab assigns real WJRP asset numbers: internal itemcode stays
auto-minted, a new optional unique gagelabtag carries the lab's number,
searchable and kiosk-resolved (scans and bare digits against either
identifier). Print files render as stacked revision cards instead of a
scrolling table.
Catalog with photos and append-only print-file revisions, a stock
ledger attributing every take/restock/adjust to a badge-resolved
employee, a touch kiosk (scan bin, scan badge, keypad quantity) with a
deliberately open decrement-only take endpoint, 1x0.5in CODE128 bin
labels, low-stock email alerts to selected users, roles, or addresses,
and stock/consumption/by-person reports with a cache-vs-ledger
reconcile. Ships disabled; enable per site. Contract 0.13.0 adds the
mailer and the User/Role models to the plugin surface.
Flask + Vue rewrite of the classic-ASP shopdb, built as a plugin
framework so sister GE Aerospace sites can adopt it. Product version
0.7.0-pre-0.8.0, plugin contract 0.11.0, 966 backend tests.
Key entry points:
- docs/INSTALL-WINDOWS-IIS.md - tested Windows + IIS install runbook
(own-site and subpath deployment methods)
- docs/PILOT-DEPLOY.md - production pilot: stand up + import + verify
- docs/IMPORT-API.md - schema-agnostic legacy data import contract
- scripts/site_imports/wjf/ - West Jefferson reference import loader
- docs/adr/ - twelve accepted architecture decision records