Skip to main content

Verification ledger: admin guide, files 00 to 03

Scope: every > Not confirmed by code: block in docs-obsidian/user-guide/admin/00-README.md, 01-first-login-and-navigation.md, 02-users-roles-permissions.md, 03-warehouse-structure.md. Method: static reading only (no build, no database, no server). Paths are relative to crates/ unless stated. Update 2026-10-11: the fix F-01 (29c0cd6d7) replaced libs/wms-lib-auth/src/authorization/bootstrap.rs by libs/wms-lib-core/src/model/initial_admin.rs. bootstrap-admin now creates the user through UserBmc::create, so rows 2, 14, 22 and the findings F1 and F4 below describe the code before the fix: the first administrator can sign in (the test the_created_administrator_can_sign_in in initial_admin.rs checks the password the way the login does), and must_rotate_password is no longer written by that command.

Result: 21 blocks. 12 CONFIRMED, 7 CORRECTED, 2 UNRESOLVABLE-BY-READING. One new unresolved block was added in 01 (bootstrap sign-in), so 3 blocks remain in the four files.

#fileoriginal claimoutcomeevidenceaction taken
100-READMEUnknown whether anything reads the replenishment policy code.CONFIRMED (nothing reads it)libs/wms-lib-core/src/model/sku.rs:206, owners/owner_config.rs:102 only store it. libs/wms-lib-sql/sql/wms-app/migrations/024_*.sql:20-24 ("Reserved identity placeholder"). 001_baseline.sql:2145 (SKU column NOT NULL default 1), :18165 (FK RESTRICT). No other reader found by grep in libs/ and services/.Block replaced by a plain statement.
201 (sign-in)Unknown where the UI forces the password change after must_rotate_password.CORRECTEDmust_rotate_password is written only in libs/wms-lib-auth/src/authorization/bootstrap.rs:122. No Rust, SQL or TS code reads it (grep over crates/ and ui/src).Text now says nothing enforces it. Block deleted. A new block was added (see row 22).
301 (password)Screen says "at least 8 characters" but code checks 6.CONFIRMEDservices/web-ui-server/src/routes/http_params.rs:26 (length(min = 6, message = "...8 characters.")). Called by auth/login.rs:34-41.Block replaced by a plain statement and advice to use 8 or more.
401 (switcher)Position and label of the warehouse switcher unknown.CONFIRMEDservices/web-ui-server/src/components/partials/masthead.rs:60-70 (button #wms-tabs-launcher, shows warehouse code, title Switch warehouse, in .utils group of the top bar). components/partials/application_menu.rs:24-100 (pop-up, search field, Enterprise row only for ADMIN holders, No warehouses assigned). Opens via ui/wms-lib/events.js:190-215.Steps 1 and 2 rewritten. Block replaced by a plain statement.
501 (dashboard)Unknown how the dashboard form opens.CONFIRMEDwms-meta-ui/migrations/001_baseline.sql:23057 (container main_workspace, default_tab_id = 1), :23066 (tab 1 = dashboard, form 1). services/viewport_service.rs:14-28, auth/session_init.rs:34. Breadcrumb reset: routes/breadcrumb_handler.rs:666-679.Block replaced: it is the default tab (home page).
601 (menu to form)Form codes for several menu items were inferred.CORRECTEDTraced menu_item -> ui_event -> tab_items -> form_base for all 55 baseline menu items (script over 001_baseline.sql) and for items added in migrations 073, 080, 081, 086, 088, 093, 095, 098, 101, 111, 117, 123. All codes in the table match except Policy > Handling Unit Registry: 080_handling_unit_screens.sql:314,528-570 opens handling_unit_registry_type_list_form, not handling_unit_registry_shell_form. Direct target_form_id count (7 items) confirmed.Table cell fixed. Block replaced by a description of the real chain. Note on Dashboard item added (see row 23).
701 (required message)Exact wording of the "required field" message unknown.CORRECTEDLive text is <Humanized field> is required: services/web-ui-server/src/extensions/generic/validate_action.rs:228-236 (resolve_required_message), :239-253. Key validation.required_field exists only in wms-meta-ui/migrations/archive_pre_baseline*.Block replaced by the real wording.
802 (buttons)Unknown whether the UI hides a button or only denies the click.CORRECTEDSidebar filtered by menu and form rights: components/partials/body.rs:66-90, sidenav::menu_item_usable. Component screens hide buttons: services/component/gate.rs:1-40, components/partials/toolbar.rs:84. Ordinary toolbars: no permission check in components/partials/toolbar.rs. Click denied: extensions/tx_helper.rs (check_action_chain_permissions).Block replaced by a three-point description.
902 (role rights)No complete per-method API list per role.UNRESOLVABLE-BY-READINGRights come from code lists, seeder.rs, and many migrations; the merged result exists only in enterprise.role_permission at run time.Block rewritten with the exact unknown and the steps and SQL to verify.
1002 (password length API)Minimum password length at the API unknown.CONFIRMED (no rule)libs/wms-lib-core/src/model/user.rs:479-515 (create), :675-700 (update_pwd), :596-604 (empty password skipped on update). services/app-server/src/web/rpcs/user_rpc.rs:60-105 has no check.Block replaced by a plain statement. See finding F2.
1102 (duplicate key text)Message text for duplicate keys unknown.CORRECTEDlibs/wms-lib-web/src/error.rs:393-398 maps 23505 to Record already exists; :399-407 maps FK refusal to Cannot delete: record is in use. user_warehouse and role creates do not resolve the violation (no resolve_unique_violation in model/user_warehouse.rs, model/role.rs).Block replaced by the real texts. Table cells still name the constraint (kept as the cause).
1202 (system roles)Unknown whether is_system roles are protected from deletion.CONFIRMED (no guard)is_system appears only in wms-enterprise/migrations/001_baseline.sql:194,811 and web-ui-server/src/components/layout/cortive_role_list.rs:152,194. No trigger on enterprise.role except the RBAC epoch bump (:2046). role_rpc.rs:21,22 delete without a guard.Block replaced by a plain statement and a warning.
1302 (API key header)Header name on every endpoint unknown.CONFIRMEDlibs/wms-lib-web/src/middleware/mw_auth.rs:43 (Bearer wms_live_sk_), :215-245.Block replaced; scope stated as "every route behind this middleware".
1402 (complexity, lock-out, rotate)No complexity rule, lock-out or enforcement of must_rotate_password found.CORRECTEDNo complexity rule (see row 10). No lock-out, but a throttle exists: libs/wms-lib-auth/src/authentication/login_throttle.rs:10-16,45,51 (10 failures per 60 s, by user name and by client, in memory). Counter column is audit only: libs/wms-lib-core/src/model/user.rs:778-800. must_rotate_password: see row 2. Guide bullet "must change the password" was wrong.Section 9 rewritten as five plain bullets. Block deleted.
1503 (add warehouse)No tool found that adds a second warehouse.UNRESOLVABLE-BY-READINGservices/tenant-manager/src/web/rpcs/tenant_rpc.rs:60-122 creates db, runs migrations, no warehouse row. libs/wms-lib-sql/sql/tenant-manager/templates/setup_users_for_tenant_db.sql:11 creates only wh1. Warehouse rows exist only in sql/dev_only/install-db/900-dev-seed.sql:500. libs/wms-lib-auth/src/authorization/bootstrap.rs:88-97 needs the row. Whether a production runbook exists is a product matter.Block rewritten: facts listed, exact unknown and verification steps.
1603 (seeded locations)Unknown whether the product needs UNKNOWN, DOCK, QC, RETURN, RTV, STAGE, PICKTO.CONFIRMED (with corrections)wms-app/migrations/001_baseline.sql:4178-4181 (zone defaults), :17521-17563 (FK RESTRICT), :2973 (location default zone DOCK), :17255,17297 (owner defaults), :8350-8461 (seed rows). 064_*.sql:19-23 seeds INTRANSIT (the guide said the baseline did). 3D page: services/web-ui-server/src/components/pages/warehouse_3d.rs:141. RTV: libs/wms-inbound/src/service/receipt/damage/move_damage_to_rtv.rs:9. No code reads UNKNOWN, QC, RETURN or RTV by name.Block replaced by a dependency list. INTRANSIT source corrected.
1703 (location generator)Unknown if the check digit is computed for generated locations, and what a duplicate does.CONFIRMEDservices/app-server/src/web/rpcs/location_rpc.rs:31-47 (digit only in create_loc), :113-122 (gen_locs does not compute). libs/wms-lib-core/src/model/base/crud_fns.rs:99-140 (one multi-row INSERT). libs/wms-lib-web/src/error.rs:393. Wizard calls gen_locs: extensions/customization/location/wizard_submit_action.rs:62.Block replaced by two plain statements.
1803 (zone fields)Replenishment fields do nothing; ADR says zone mixing rules have no reader.CORRECTED (second half was wrong)Replenishment fields have no reader (grep: only putawayzone_rpc.rs:45-46 and the form gate). Zone lot mixing IS read: libs/wms-inventory/src/inventory_service.rs:1406-1420,1477-1560, test libs/wms-inventory/tests/move_command_integration.rs:1513.Block replaced. docs-obsidian/putaway_policy/README.md:53,88 is stale (see F6).
1903 (operator rule)Exact rule for the operator list unknown.CONFIRMEDlibs/wms-lib-core/src/model/tasks/operator.rs:236-273: rf_login = true, status = 'Active', a user_warehouse row for the warehouse; any role. Loop: services/app-server/src/services/cleanup_tasks.rs:150,991-1020.Block replaced. Two other lines in 03 and one in 02 (section 8) fixed to add "status Active".
2003 (3D controls)Controls of the 3D page unknown.CONFIRMEDservices/web-ui-server/src/components/pages/warehouse_3d.rs:12-135. English texts: wms-meta-ui/migrations/118_bespoke_warehouse_topology_words.sql:5-43.Block replaced by a control list.
2103 (cycle count)Full count workflow not confirmed.CONFIRMED (scope note)It is a scope statement, not a code question.Block replaced by a plain scope sentence.
2201 (new block)NEW: can the bootstrap administrator sign in?UNRESOLVABLE-BY-READINGlibs/wms-lib-auth/src/authorization/bootstrap.rs:109-122 stores a bare Argon2 PHC hash with empty pwd_salt. libs/wms-lib-auth/src/pwd/mod.rs:94-104 accepts only #scheme#hash. Reading says sign-in fails; only a run proves it.Block written with exact unknown and verification steps.
2301 (extra fix)Enterprise note listed only Warehouses and Owners as dead items.CORRECTEDMenu item ent_dashboard (id 29) has no target_form_id and no ui_event (001_baseline.sql:21044; script trace).Note extended to Dashboard.

Product findings​

F1. Bootstrap administrator probably cannot sign in. libs/wms-lib-auth/src/authorization/bootstrap.rs:109-122 writes a raw Argon2 PHC string (no #02# style prefix) and an empty salt. libs/wms-lib-auth/src/pwd/mod.rs:94-104 (PwdParts::from_str) needs ^#(\w+)#(.*). wms-lib-web/src/handlers/handlers_login.rs:112-126 then fails with LoginFailPwdNotMatching. Needs a run to confirm. No test covers hash-then-login for this command (bootstrap.rs tests at :170+ test only config).

F2. No server-side password rule. libs/wms-lib-core/src/model/user.rs:479-515 and :675-700; RPCs create_user / update_user. An empty password is stored on create. The only check is on sign-in (6 characters), so an account made with a short password can never sign in.

F3. Wrong message on sign-in. services/web-ui-server/src/routes/http_params.rs:26: rule is min = 6, text says 8.

F4. must_rotate_password is dead. It is written (bootstrap.rs:122) and in the schema (wms-enterprise/migrations/001_baseline.sql:216), but no reader exists. The CLI message services/app-server/src/cli.rs:82 and the log line bootstrap.rs:148 tell the operator to rotate "on first login", which nothing prompts. failed_login_attempts is audit only (user.rs:778-800).

F5. Duplicate-key and generator errors hide the cause. libs/wms-lib-web/src/error.rs:393-398 returns Record already exists for every unique violation that has no model-level resolver, with no constraint name. Generated locations (gen_locs) fail as a whole when one code exists, and the user is not told which code.

F6. Stale design note: docs-obsidian/putaway_policy/README.md:53,88 says putawayzone_lot_commingle has no reader. It has one since libs/wms-inventory/src/inventory_service.rs:1537-1553.

F7. Inconsistent check digit: create_loc computes it (location_rpc.rs:42-44), gen_locs does not (:113-122), although both are described by the setting CHECK_DIGIT_ENABLED ("new locations", wms-app/migrations/001_baseline.sql:9947).

F8. Dead enterprise menu item Dashboard (ent_dashboard, wms-meta-ui/migrations/001_baseline.sql:21044): no form, no event. Same class as Warehouses and Owners.

F9. Stale comment: services/web-ui-server/src/services/snapshot/impersonation.rs:123-125 (and :1468) says the server logout does not touch the session. routes/login_handler.rs:95-101 does session.flush().

F10. Throttle is per process only (login_throttle.rs header). With several app-server copies the allowed rate multiplies. A stated limit, not a bug.

F11. Other guide files may repeat the wrong registry form code. Not checked here: 04-owners-sku-uom-pack-hierarchy.md (handling_unit_registry_shell_form). Owner of that file should check against 080_handling_unit_screens.sql:314,528-570.