aim-web2.1.0rc9

This commit is contained in:
admin_rb
2026-09-22 19:23:17 +02:00
parent d095887d2e
commit 3dfc80b782
438 changed files with 31613 additions and 1510 deletions
+97
View File
@@ -0,0 +1,97 @@
# AIM WebGUI global agent standards - 2.1.0rc9
Read this file before changing application, tests, deployment or documentation. Update it in the same release whenever a global convention or security boundary changes.
## Product boundary and compatibility
AIM Core is independently installed and managed. This candidate targets supplied Core **3.3.0rc8**, service/wire/event API **1.0**, `play_task_host_v1`, `inventory_hierarchy_v1`, `target_outcome_summary_v1`, and `native_defaults_preflight_v2`. WebGUI HTTP remains **v2** and SQLite remains **schema 5**. Do not call this production-qualified merely because source tests pass.
Core rc8 additionally advertises `collection_baselines.ansible.windows` as `>=3.8.0,<4.0.0`. Require that public capability declaration, but do not install, upgrade or privately discover collections from WebGUI; Core readiness and operator acceptance own the actual collection environment.
Read Core's ADDON_AGENTS.md, ADDON_API.md, ADDON_SUPPORT.md and RELEASE_HANDOFF.md. Use only documented fixed `aimctl` JSONL operations via the existing adapter/client. Never import private AIM/Ansible modules, parse Core inventories locally, rewrite Ansible argv, vendor Core, or modify its source/configuration/runtime/roles/Vaults/keys. Additive unknown response fields may be ignored; unsupported capabilities/errors must not become invented successes. Removing or breaking the add-on must not prevent terminal AIM from working.
The executor is an add-on-owned, pre-started non-root same-UID Core caller. Web and queue use aim-web; the executor uses the independently provisioned AIM execution identity. No sudo/setuid/key-export bridge, HTTP-started Ansible command or arbitrary command/path/actor/environment endpoint. Private Unix IPC uses peer checks. Shared local service identities are trusted controller actors, not hostile-tenant isolation.
## Execution, credentials and preserved workflows
A run needs fresh review, not a saved plan. Keep bounded private expiring reviews, explicit targets, frozen scope/options/mode/key handling/revision and current grant/approval checks at dispatch. One-run submissions are idempotent; saved names are optional with transactional NFKC/casefold/strip collision prevention, never upsert by title. Existing plans/jobs/accounts/audit survive normal releases.
Use Core's reported credential requirements and native inventory precedence. No forced Custom/password-only overrides, become-password UI, private-key uploads, prompt automation, credential guessing or secret cache. Secret collection stays authenticated, CSRF/origin-protected HTTPS POST with bounded bodies; credentials travel in a separate private FD, not request JSON, argv, environment, database, logs or files. Preserve literal UTF-8 and existing one-run deadlines. Python cleanup is not physical memory erasure.
Final Core status/exit/counters and target facts remain authoritative. Partially succeeded is a presentation label, not a rewritten Core result or database queue state. Never derive final host success from SSE or task counts. Missing response, cancellation and interruption may leave work unknown; cancellation is not rollback. Manual retry creates a new reviewed job and fresh secrets. Running jobs cannot be deleted. Deletion removes job/lifecycle/idempotency records while retaining a compact audit event, not a hidden transcript archive.
Only documented static labels, logical host names, fixed hints and numeric detail progress are rendered. Do not recover raw module output, decrypted variables or unsafe diagnostics. A bounded allowlisted structured journal is now retained with the job; rendered console strings and raw streams remain prohibited. Final report bodies are separate, declared and validated.
## Read-only experience: explicit data scope
Inventory Explorer consumes the current Core hierarchy and separate host metadata. All new explorer/activity/insights routes are GET-only and must never call prepare/execute, collect secrets or probe managed hosts. Current inventory is not persisted as a competing database. Group identities are full paths; direct/root membership and repeated host membership are preserved. Recursive counts are distinct hosts, not sum-of-appearance counts. The map is membership, not topology or live health.
Host Activity and Playbook Insights use ONLY retained **AIM WebGUI jobs** and final Core per-target facts already stored with those jobs. Do not collect terminal AIM execution history, external/core-wide history, audit-derived reconstructed results or a separate shadow archive. Use a customer plus exact logical hostname identity; never silently merge renamed/recreated machines.
History queries must use the same owner-or-admin visibility as job detail BEFORE aggregation. Saved plans remain owner-only, including for administrators. Inventory visibility does not confer access to another viewer's job history. Aggregate counts, filter choices, matrix cells and links must not leak hidden jobs. Preserve existing read policy rather than inventing tenant isolation.
Stream all matching retained job rows rather than reuse the latest-100 Jobs overview. Page displayed records and bound graph/matrix output; define time range, modes and coverage. Count one requested host participation per job. Apply is the default; Check is explicit and never evidence of installed changes. Success percentage = successful / (successful + failed + unreachable), with denominator visible; not-started/indeterminate/unavailable/outstanding are separate. Changed values count tasks; any derived metric must say so. No per-host duration from job elapsed times. Deleted jobs disappear from statistics; incomplete/legacy target data remains unavailable, never guessed successful.
A Core outage is not empty inventory or an offline host. Authorized retained history remains available when current inventory cannot be retrieved. Historical outcomes include timestamps and do not claim current health/compliance/software versions. No graph click launches a job.
## UI and mobile conventions
Use Jinja2, HTMX and small self-hosted JavaScript with Bootstrap 5. Keep centralized orange accents, charcoal/slate dark surfaces, sun/moon controls, semantic status chips, visible focus, keyboard navigation and reduced-motion behavior. No persistent special orange outline around Jobs/Saved plans. Non-sensitive theme preference may use browser storage; inventory/history/credentials must not.
Desktop above 760px retains the sidebar. Mobile uses a single compact header: **AIM home link left; light/dark controls then hamburger at the far right, vertically aligned**. The native details/summary menu opens below/right with viewport-bounded internal scrolling. Remove horizontal swipe rails, arrow controls and swipe instructions. Keep Escape/focus return, outside-click close, native keyboard/no-JavaScript opening, and account/logout controls reachable. Do not use ARIA menu roles for ordinary site navigation.
Inventory uses a deterministic linked SVG map and equivalent outline. Phone defaults to branch-focused outline; Map remains available with explicit zoom controls and internal scrolling. Breadcrumbs replace unbounded indentation. Host links open a real activity page. Never require hover, drag or pinch to obtain essential information. Direct host/group pages are bounded, searchable and paged.
Use mobile cards for historical results/matrices. Prevent page-level horizontal overflow. Group selectors retain two columns on narrow screens and aligned selection columns; explicit submitted hostnames remain authoritative. Live output autoscroll changes the console scrollTop, never the window; manual upward scrolling pauses follow. Filters, text labels and errors remain legible at 320px and short landscape heights.
Store/transport UTC, render semantic time[datetime] using browser locale, retain inspectable UTC; reformat initial load, HTMX replacements and pageshow. Schedule input stays explicitly UTC unless a separately tested conversion change is approved.
## Permissions and deployment
Preserve rc8's tested intent: executor primary group is its native account group; aim-web is unit-scoped supplementary group. Config root:aim-web0640; private web state aim-web0700; executor state and both process-home/passwd-home temp directories executor0700; runtime directory executor0711; socket executor:aim-web0660. Keep ProtectHome=read-only, narrow temp write exceptions, NoNewPrivileges and empty capabilities. Wait boundedly for socket readiness.
Core authorization groups, inventory/Vault/private-key ownership, system SSH trust, certificates and proxies remain operator/Core managed. Do not repair them from HTTP. Do not infer OpenSSH known_hosts from HOME: effective SSH configuration and passwd expansion are authoritative. No recursive chmod/chown of /etc/ansible.
Whole-release replacements, independent immutable versions, no Git requirement. Overwrite release-managed WebGUI config as requested; preserve private state. Stage dependencies and public Core metadata before downtime; backup matching source/config/units/DB and handle rollback explicitly. Unknown unit overrides require review. Do not modify either production Python environment for tests. Existing 1.x migration needs --migrate-core; ordinary 2.x updates do not.
## Tests and evidence
Test authentication, request boundaries, Core contract/FD transport, different-UID executor, migrations, existing workflow guards, read-only authorization/aggregates/deletion, >100 retained jobs, repeated membership, same hostnames across customers, outages/empty states, and escaped output. Browser QA covers mobile hamburger/alignment/focus, graph links/zoom, cards, themes, short heights, local timestamps and internal console scrolling. Distinguish real Core metadata from fake native execution and fixture browser assets.
Verify the actual final extracted ZIP through deploy.verify_release, canonical manifest paths and required-file coverage, compile/templates/JS, wheel resources and pristine Core hashes. Never claim skips as passes, fake native tests as SSH/WinRM qualification, fixture events as live HTMX/SSE, or static unit tests as systemd deployment. Keep VERIFICATION.md and machine-readable results aligned with observed evidence.
## Credential dialog and attention - 2.1.0rc9
Use a progressively enhanced native dialog for deliberate owner-initiated credential entry; keep the authenticated full-page form as the no-JavaScript/unsupported-dialog fallback. Use Bootstrap 5 native radio/label button groups, never Bootstrap 4 JavaScript or jQuery. A key-passphrase source choice is allowed only for the exact Core requirement `ssh_key_passphrase_or_customer_vault_value` alongside `vault_password`; an explicit `ssh_key_passphrase` requirement remains required. This is not a Vault/Custom authentication override.
Keep dialog contents outside HTMX-polled fragments. Load the form lazily for the current reservation, never pre-populate secrets or automatically open/focus a password field. Show the reviewed customer, playbook, target count and mode. Preserve focus containment, Escape and explicit Close, focus return after replaced triggers, short-viewport internal scrolling, persistent labels, paste, Show/Hide and Caps Lock hints. A backdrop tap must not accidentally discard typing. Close dismisses the form, not the job.
Clear all marked secret inputs on submission, closure, expiry/revocation and pagehide, including revealed text inputs. Keep submitted secrets out of URLs, storage, logs, titles, status responses and history snapshots. Do not claim clearing DOM/references erases all browser/runtime memory. Preserve five-per-minute submission throttling, existing worker single-claim semantics, five-minute empty reservation and 60-second handoff/start deadline. Do not extend a reservation on a GET or while typing.
Use a monotonic client countdown synchronized to server timestamps for display only. The server remains authoritative. An accepted handoff is not a verified password or completed execution. On an uncertain/lost POST response, clear inputs, lock submission and poll owner-only status; never automatically resend credentials. Reopening an uncertain job in the same page must not offer another POST. Terminal status, cancellation or lost eligibility must close the input opportunity without manufacturing a retry.
Needs your attention is a non-secret, read-only view: your own live credential reservations and, for eligible administrators, other requesters' jobs pending independent approval. It does not reveal other owners' credential forms, automatically approve/execute jobs or use the latest-100 history limit as its population. Existing policy and grants still apply. Keep ordinary execution failures separate from jobs currently waiting on user input.
The canonical credential POST is `/api/v2/runs/{id}/credentials`; retain the shipped `/api/v2/jobs/{id}/credentials` alias. New reservation-status GETs must not return secrets, override scope, renew a deadline, or invoke Core. Tests must exercise the shared rate limit, missing required keys, revoked sessions/grants, expiry, cancellation, duplicate submission, literal passwords, ambiguous acknowledgements and the real existing worker handoff socket. Browser fixtures are not live pinned-asset/CSP/HTTPS/HTMX qualification.
## Core3.3 reports and persistent evidence
The approved contract is Core3.3.0rc8/service-event1.0, aim_output_v1 publisher and aim_operation_result_v1 final result. Negotiate live capabilities; preserve validated result_contract with review. Do not add request output flags, read schemas from Core files or invoke private validators. Revalidate final mode/host/schema/scope/data against the recorded contract. Reports arrive only at finalization. A final event is not a final response; persist one report, never duplicate samples.
Keep execution verdict, native target outcome, report availability and local retention distinct. Native exit0/result_validation stays failed even when all targets succeeded. An unavailable report is not empty/zero/false. Unknown versions stay unknown; pending updates are not installed; excluded services are not failed starts; ignored/rescued native semantics stay intact. Generic supported schemas may render safely, never execute custom code or external references.
Progress is captured worker-side with no viewers, via bounded nonblocking queue/batched committed rows. IDs correlate interleaved tasks; no invented future task list/ETA/percentage. Record durable local cursors and deduplicate(job,run,sequence). Tail omissions, queue/storage loss, crash gaps and last-observed time are explicit. SSE replay checks session/job authorization throughout and cannot replay execution or credentials. Missing final response never becomes success from progress.
Schema5 evidence tables are job-linked with cascade deletion. Journal default20,000 events/8MiB tail; latest checkpoint bounded; report default16MiB subject to reviewed slot bounds. Keep reports out of heavy ordinary job/history reads; load one authorized payload on demand. Parsed Checkmk sections are opt-in; default is labeled metadata_only and not a complete report body. Do not retain a secret cache, terminal history or shadow archive; backups/physical erasure have separate policy.
Escape all labels/report text. Never follow returned paths/URLs or render HTML. Browser data storage remains forbidden for evidence. Preserve working modal/hamburger/theme and internal scrolling; no new privileges/services. Public result framing may grow independently of unchanged request/credential limits. Test full-size/split/torn/duplicate-final transport, all9 declarations, mixed outcomes, no_log/secret canaries, generic/global fixtures, two viewers/reload/revocation, retention pressure/deletion, migrations and matched rollback. Report native/browser/fixture boundaries honestly and update all current guides in the same release.
## Core 3.3.0rc8 patch-wave presentation
Obtain reboot/message/delay/continuation controls from public catalog metadata; do not maintain a second defaults table. Blank means omitted/inherited, not a forced value. Surface the Windows-only continuation flag and its catalog hint (false in rc8); explicit true is never inferred from reboot permission. Review normalized options before any run.
Use only validated recorded patch_summary_v1 fields. A successful wave with continuation_required stays successful and calls for review, not an automatic job. remaining_updates_known=false prohibits presenting pending or an empty list as an authoritative next-wave state; retain original structured JSON separately. True refers to the dated final read-only discovery only. Missing optional fields in older reports remain unknown; validate new data with its prepared schema, not an old schema merely sharing the identifier.
Show pre/post reboot/deferred observations, reviewed delay and cycles when supplied. Core owns bounded HRESULT codes/reasons/messages. Never parse raw failure output or equate install_not_allowed (including 0x80240016) with the separate preexisting_reboot_required preflight result. Native failure, report validation, report completeness and next-wave needs remain separate. No auto-enable reboot/rescan, no generic retry shortcut, no new permissions/services/secret handling.