The device console is a default-grey tkinter window with no hierarchy: no grouping, no state colour, no type scale, the privilege warning buried in a monospace paragraph, "Çık" duplicated at two sizes, and an output area that looks editable. Every measurement is in the delivered work; the point here is that the fix is a system, not a repaint. Adds PRODUCT.md (product truth: who uses this, from where, under what constraints), docs/DESIGN.md (the direction contract and the shared status vocabulary) and web/static/tokens.css (the values both surfaces read). The vocabulary is the load-bearing part. Four severities -- ok / warn / danger / info -- plus one action accent, and one Turkish word per device stage (KURULDU / KAYITLI / HAZIR / HATA / YOK) used identically on the device and in the central panel. A fifth hue is a bug, and colour is never the only carrier: every badge ships its word, so the fleet list stays readable in greyscale. The ground is light on purpose. The console runs in workshops and dealer service areas in daylight; a near-black ops console loses its own body text there and its state colours collapse into equal-brightness smudges. No webfont: the fleet installs offline from a committed pool, so a font CDN is a broken page on every device.
69 lines
5.8 KiB
Markdown
69 lines
5.8 KiB
Markdown
# Product
|
|
|
|
<!-- impeccable:product-schema 1 -->
|
|
|
|
## Platform
|
|
|
|
web
|
|
|
|
Two surfaces share this record. The **central panel** is a web surface (browser, server-rendered). The **device console** is a native desktop surface: a Python/tkinter application that ships on each field PC and runs with no network. Visual work on the device console follows the native-platform guidance for its own platform; this value names the surface under design here.
|
|
|
|
## Stack
|
|
|
|
Python standard library only (`http.server` + server-rendered templates). No framework and no third-party dependency: the fleet installs offline from a committed package pool, and `fastapi`/`uvicorn`/`flask` are not in that pool. Adding one would mean the panel cannot be installed on the devices it manages. Confirmed with the user over FastAPI for this reason.
|
|
|
|
## Users
|
|
|
|
**Field technician** — a dealer/authorised service person who receives a Windows 10 PC and must turn it into a Blueforce Field OS device. Works at the device, often in a workshop or a customer site, with limited time and no developer background. Job: run the install, know whether it succeeded, and recover when it did not.
|
|
|
|
**Central operator** — the person responsible for the whole fleet (~700 devices) from an office browser. Job: see which devices are installed or not, which rollout wave each is in, and push an approved update. Handles many devices per session and needs status, not detail.
|
|
|
|
Both operate the same fleet from opposite ends: the technician from the device, the operator from the browser.
|
|
|
|
## Product Purpose
|
|
|
|
Convert a fleet of Windows 10 field PCs into machines running Blueforce Field OS, and keep them correct afterwards. Success means a technician finishes an install without internet access, without guessing, and without a silent partial state — and an operator can say at any moment which devices are ready and which are not.
|
|
|
|
## Positioning
|
|
|
|
The install is provably offline and fail-closed. The device carries its own signed package pool, the installer refuses to continue when the contract does not hold rather than half-installing, and every destructive step demands explicit approval with a root gate. Neither property can be copied by a neighbouring tool that assumes internet access or treats a failed check as a warning.
|
|
|
|
## Operating Context
|
|
|
|
- Fleet: ~700 Windows 10 field PCs, converted in waves LAB(2) → P1(5) → P2(20) → W1(50) → W2(100) → PROD, production behind a separate typed override.
|
|
- Install target: Ubuntu 26.04.1 LTS ("Resolute Raccoon"), GNOME desktop installed but not the boot default — the device boots to a terminal and the desktop is switched on when required.
|
|
- Network: the field estate is reached over WireGuard; four remote channels are supported (SSH-over-WG, xRDP, RustDesk OSS, MeshCentral). No commercial remote-desktop licence (AnyDesk was rejected).
|
|
- Fleet tooling: Ansible CLI + Semaphore Community for orchestration, Prometheus + Node Exporter + Grafana OSS + Uptime Kuma for monitoring, Docusaurus for documentation.
|
|
- Device state machine: `PROVISIONED_OFFLINE → ENROLLED → READY`, with no skipping and no going back; `READY` is refused unless every channel reports `verified`.
|
|
- Documentation set: 33 numbered Turkish documents plus README/SUMMARY, served through Docusaurus.
|
|
|
|
## Capabilities and Constraints
|
|
|
|
**Confirmed functionality** — the device console exposes 48 operations: 13 write (all requiring root) and 35 read-only. The installer is `scripts/install/blueforce-install.sh`, driven by an offline bundle at `provisioning/offline-repo/built/` (index + `pool/` of 1321 `.deb` files, ~887 MB). Evidence of fleet state is an inventory and a enrolment token per device.
|
|
|
|
**Hard constraints** — no internet during install or normal operation; every user-visible string is Turkish (code, comments and commit messages stay English); destructive operations need an explicit typed confirmation and a root gate; a check that fails stops the operation, it never degrades to a warning.
|
|
|
|
**Deliberately undecided** — where the central panel is hosted and how it authenticates to the fleet. Not invented here: the panel is being designed before its deployment model is fixed.
|
|
|
|
## Brand Commitments
|
|
|
|
Name: **Blueforce Field OS**. Existing operator documentation and console copy are Turkish and already carry the product voice — plain, factual, no marketing register. No logo or palette is binding; no visual identity exists yet.
|
|
|
|
## Evidence on Hand
|
|
|
|
- `docs/` — 33 numbered Turkish documents, including `01-ARCHITECTURE`, `24-DECISION-LOG` (K-01…K-14), `27-OFFLINE-PROVISIONING`, `33-OPERATOR-CONSOLE`.
|
|
- `bfos/` — the device console (`operations.py` catalogue of 48 operations, `runner.py`, `tui.py`, `ui_gui.py`).
|
|
- `provisioning/offline-repo/` — the committed package pool and its manifests.
|
|
- No analytics, no customer logos, no testimonials, no benchmark numbers, and no screenshots of a working web panel exist. Nothing of the sort may be fabricated.
|
|
|
|
## Product Principles
|
|
|
|
1. **Fail closed, never half-install.** A device that cannot be verified stays unfinished and says so; a degraded success is worse than a clear refusal.
|
|
2. **Offline is a design property, not a deployment accident.** Anything the fleet needs travels with the fleet.
|
|
3. **Destructive work is explicit.** Approval and root are gates, not warnings.
|
|
4. **State is legible at a glance.** Which wave, which stage, which channel — readable in seconds, from a device screen or across 700 devices.
|
|
5. **Turkish for operators, English for the codebase.** No mixed-language surface.
|
|
|
|
## Accessibility & Inclusion
|
|
|
|
Field devices are operated in workshops and customer sites, sometimes on small or poorly lit screens; the console is used with a keyboard more often than a mouse. Readable contrast and non-colour-only status signalling are requirements, not enhancements. No formal standard (WCAG level) was agreed; none is claimed.
|