72 KiB
ASSESSOR project guidance
Implementation plan
- Read
docs/IMPLEMENTATION_PLAN.mdbefore architecture changes, broad refactors, persistence changes, importer/profile work, or server-readiness work. - State which plan phase the requested work belongs to and keep the change within the user's requested scope.
- Preserve the currently working local application while moving toward the documented browser/server target architecture.
- Do not mark a milestone or phase complete until its acceptance criteria have been verified.
- After a material, verified implementation step, update the plan's status, decisions, risks, and change log in the same change. Do not rewrite historical decisions silently.
- If the requested implementation conflicts with the plan, explain the conflict and update the plan only with the user's agreement or when the request explicitly supersedes it.
ASSESSOR product version
package.jsonis the single source of truth for the visible ASSESSOR product version. Header, About dialog and backend health response must continue to read that shared value; keep the rootpackage-lock.jsonentry and version contract tests synchronized.- Reassess the product version after every material, verified implementation batch. Increment the patch version for backward-compatible corrections and refinements, the minor version for a backward-compatible capability release, and the major version only for an intentionally breaking product or deployment contract.
- Do not increment the product version for documentation-only edits, test-only maintenance, unfinished work or every individual commit. Batch related work into one release version and record the decision in
docs/IMPLEMENTATION_PLAN.md. - A version change is complete only after the product-version UI/API tests and both production builds pass. Historical reports retain the version they documented at creation time and must not be rewritten.
Binding agreements and rule conflicts
- Treat documented user decisions, this file, and the implementation plan as binding acceptance criteria. Before changing an affected behavior, identify and preserve every relevant agreement; later work must not silently weaken, replace, or bypass it.
- If a requested change conflicts with a binding project rule, security boundary, or documented decision, stop that conflicting part and tell the user which rule blocks it and why. Do not implement a quiet approximation. Change the governing rule only after the user explicitly agrees, or when the request explicitly supersedes it.
- Every regression fix for a documented agreement must add a synthetic behavioral test for the exact user interaction that regressed, not only a lower-level helper or adjacent route. Keep that test as a permanent acceptance check.
- When requirements appear ambiguous, distinguish the supported interaction paths explicitly. Do not claim an agreement is fulfilled when only one path satisfies it and another normal path exposes different behavior.
Architectural boundaries
- Keep format parsing, structural analysis, semantic mapping, normalization, comparison, persistence, and presentation separated.
- Preserve original source values and provenance; normalized values must not destroy source data.
- Known tool profiles must extend the generic import pipeline rather than bypass it.
- Every new or extended scanner profile must first check its supported report formats for a usable native overall score. Declare
securityScoringin the profile with exact mapped properties, overall scope, scale, direction and result-population semantics, or an explicit reason why no usable native score is available. Native values take priority over calculated pass rates through the shared scoring engine; never infer overall-score semantics from an arbitrary field named score, a category score or a finding weight. Preserve source values and file/run provenance, version extraction changes and verify native priority, missing/invalid/conflicting values and safe fallback with synthetic fixtures. Seedocs/SCORING_MODEL.md. - React components must not contain source-specific parsing or direct database logic.
- Treat Tauri as the current local shell and a possible optional future shell. Do not make new domain logic depend on Tauri when a platform-neutral boundary is possible.
- The target deployment is an internal browser application with a backend and PostgreSQL. The browser must not access the database directly.
Canonical local PostgreSQL
- The single canonical local ASSESSOR datastore for this workspace is the existing Docker Compose project
assessor-2_0, containerassessor-2_0-postgres-1, databaseassessor, and volumeassessor-2_0_assessor-postgres-dataon127.0.0.1:5432. - Every local App/Backend start must reuse that datastore. Never create an alternative ASSESSOR database, Compose project, PostgreSQL volume, or fallback port for this workspace.
- If the canonical datastore is unavailable or port
5432is occupied by a different container, stop and report the conflict instead of spawning or selecting another database. docker-compose.postgres.ymlmust keep the canonical Compose project name and external volume binding. Never delete, replace, recreate, or initialize the canonical volume as an empty datastore.- Before an approved persistence migration or destructive database operation, create and verify a backup. Unrelated Docker applications, containers, and volumes remain out of scope.
Binding ASSESSOR design language
- Explicit user correction 2026-09-18: the current, user-approved Data Hub, Work, and Pathfinder screens are the binding visual references for ASSESSOR's Ableton-inspired design language. This applies to every view, explicitly including Client Info, and to proposals, generated images, prototypes, and production implementation.
- Before any visual task, read
.claude/skills/assessor-ui/SKILL.mdand the relevant current components andsrc/styles/ui-tokens.css. The approved views and these current project agreements take precedence over older skill examples, copied asset templates, and superseded Client Info exceptions. - Use Data Hub for flat square tiles, full-circle donuts, compact action buttons and branding; Work for list/detail hierarchy, typography, badges and reading surfaces; Pathfinder for stable filter/work/detail zones and compact controls. Preserve these approved views as references; do not redesign them as a side effect of Client Info work.
- Keep the current neutral theme surfaces, transparent segments, flat tiles, subtle separators, local Inter typography, shared 20px panel inset and shared control geometry. Reuse existing tokens and components. Do not reinterpret Ableton as a new palette, a literal copy of another application, or a return to obsolete UI dimensions.
- Use the shared yellow/amber roles for primary actions and persistent selection, with the explicitly blue table-row reading marker documented below; blue remains the keyboard-focus role elsewhere. Use semantic status colors for the established status and data-visualization roles. A tool or graph-category color does not authorize a new selection or button color. No gradients, decorative shadows, glass effects, hover lift, generic rounded dashboard cards, new navigation shell, new logo, or Client-Info-only visual theme. The 2026-09-25 user rollback removes the short-lived donut-ring shadow exception; arcs remain solid colors without gradients.
- Improve quick comprehension through grouping, alignment, readable labels, a small set of relevant overview values and existing detail/disclosure patterns. Never shrink body text or structured data below their agreed roles to fit more content, stretch sparse tiles across unused space, or invent metrics to populate a layout.
- All mockups must use the approved views as actual visual references, preserve the existing shell and metric meanings, and clearly identify synthetic example data. A rejected generated image is not a design reference. The three generic Client Info mockups rejected on 2026-09-18 are explicitly not approved.
- Visual acceptance: a Client Info proposal or implementation must be recognizable as the same application as Data Hub, Work and Pathfinder even without its logo. Check the shared surfaces, typography, buttons, selection, spacing and donut geometry at normal application zoom; inspect both themes for implementation. Distinguish a documented rule, a proposal and an implemented/verified UI change.
UI typography
- Use the locally bundled Inter variable font as the application typeface. Do not introduce view-specific display, condensed or serif families; hierarchy comes from size and weight. Explicit user exception: paths use the shared technical-path textbox and local system monospace stack; other content remains Inter. Do not download additional fonts.
- Use only the visual weights Regular 400, Semibold 600, and Bold 700. Bold is reserved for branding and exceptional emphasis.
- Use the semantic typography roles: H1 56px/600, H2 32px/600, H3 18px/600, detail titles 20px/600, H4 16px/600, continuous prose and readable tile values 16px/400, structured table/Grid/Raw Data content and informational field labels 14px/400, compact control labels and metadata 12px, badges 11px, and buttons/controls 13px/600.
- Preserve normal title case for H1-H4, field labels, and buttons. Uppercase is limited to compact table headers, badges/categories, and the ASSESSOR wordmark.
- Explicit user decision 2026-09-20: the smallest text intended to communicate application information is
14px; this includes table cells, table headings, tile content and informational field labels. Readable values and continuous prose use16px. For example, the Client Info Directory tile rendersDomainat 14px andsevenkingdoms.localat 16px. Do not demote either role to a metadata or compact-control token merely to fit more content. - Compact interface text such as button captions, technical metadata, badges and comparable control annotations may use a smaller type size. These exceptions must not carry primary table, tile, field-label or prose information.
- When adding or changing styles, preserve this distinction instead of reducing content text to a compact UI-label token.
UI panel spacing
- The Work panel is the binding spacing reference: content inside every rounded main panel starts
20pxfrom each outer edge. - Use
--panel-content-insetthrough its compatibility alias--panel-inset; do not introduce local substitute values for existing or future main panels. - Apply the inset exactly once on the view's root content container. Split panes and edge-to-edge structures belong inside that inset and must not add a second outer inset.
- Keep the 20px outer inset at responsive breakpoints unless the user explicitly changes this standard.
UI Finding Reader first read
- Explicit user decision 2026-09-25: every Finding Reader states within seconds what is wrong and what to do. Directly below the setting or rule heading, a
Problemblock (Summaryfor a passed result) with the outcome-colored marker and a separateNext stepblock with the orange--next-step-accentmarker precede all explanatory text; both markers use--marker-width. Background (description, technical explanation, rationale) follows openly, references and documentation after it; work tracking and Additional Information stay collapsed at the end. - Scanner profiles declare their first-read fields in
presentation.firstRead; React components never name scanner-specific fields. Use only retained source values: a missing field removes its line and nothing is summarized, rephrased or invented. Counts come from explicit source counts or linked result tables; a result row is red or green only where the source marks it (CIS-CAT criterion/evaluated rows with the finding outcome,resultSheetRowStatusCellsmarkers). Split a long remediation only at a paragraph boundary and keep the rest complete behindFull remediation. An imported documentation link is offered only as a plain https URL withnoopener noreferrer. - Explicit user decision 2026-09-25: every documented standard Windows code shown as text carries its meaning directly after it, in muted regular text: well-known SIDs, standardized domain RIDs (
S-1-5-21-<domain>-500/512/...; the domain part is never resolved), User Rights Assignment constants (SeNetworkLogonRight->Access this computer from the network) and registry type codes (4->REG_DWORD). The single list lives insrc/shared/windows-codes.tsand is applied centrally byPathText; the original code stays unchanged and authoritative, unknown or customer-specific codes stay plain, and a meaning already stated next to the code is not repeated. - Maester's native test result (ResultDetail) stays in Results only (2026-09-25 decision); its first read shows the source-marked row counts and the https documentation link. GPO findings use the GPO problem summary rules above.
- Explicit user correction 2026-09-25: when a scanner's first-read remediation explicitly introduces a PowerShell command, render that command in its own readable, contained block beneath the explanatory sentence. Keep the original command text complete and copyable, do not rewrite its parameters or split the remaining remediation before the original paragraph boundary, and retain the full source field unchanged.
UI Pathfinder graph text and details
- Explicit user correction 2026-09-25 supersedes the earlier Pathfinder
Off/Labels/Textmodes and in-graph node cards: node text starts on; the toolbar has only theTexttoggle for turning that text off or on. Selecting, deselecting, marking, extracting, or hovering a node must not change the text setting.Reset viewrestores text on. Keep graph nodes and their compact text in the graph, while node information and actions appear only in the rightDetailspanel. Do not render hover or selected-node cards over the graph. - Explicit user extension 2026-09-25: the right
Detailspanel shows the same severity-colored Finding hexagon as the Work tile next to a Finding title. Add concise, source-backed context there when available: native source status, tool, exactSource Rule ID, category and MITRE ATT&CK IDs. Omit missing fields; do not place a Finding hexagon or Finding facts on relation nodes. Keep the full Finding and evidence available through the existing Work and Results actions. - Explicit user correction 2026-09-25: the Pathfinder action is named
Extract Path. It is available only for a selected graph node and isolates that node, its directly connected nodes, and only their connecting edges. A filter orMark allbranch alone must not trigger extraction of the whole graph or broaden the selected path.Exit Extract Pathrestores the prior graph selection and view. This supersedes the earlier broad-branchExtractbehavior;Mark allkeeps its separate branch semantics. - Explicit user correction 2026-09-25: Pathfinder Details facts must give values a readable column at the normal inspector width. Do not cap that column to a fraction of its own auto width or break ordinary words and numeric values inside a line. Wrap multiword values at spaces; allow long unbroken technical identifiers to scroll within their own value area without clipping adjacent content.
UI DB Structure table flow
- Explicit user correction 2026-09-25: every table button in the DB Structure data-flow diagram opens that table's columns and relationships in the shared floating popup, instead of adding an inline detail section below the diagram. Referencing-table buttons inside the popup navigate to that table within the same window; Close and Escape dismiss it and leave the flow intact. This supersedes only the inline-detail placement from the DB-Structure flow implementation. The separate layered table dictionary retains its disclosure behavior.
- Explicit user correction 2026-09-25: DB Structure omits the redundant introductory
Database dictionary/Relational schemacopy block above the metrics and the explanatory sentence beneathData flow. Keep the schema status and refresh action, metric tiles, flow heading, table buttons, popup and dictionary disclosure.
UI Work filter context
-
Explicit user extension 2026-09-18: the Work toolbar's
CSV,MDandHTMLbuttons export the complete current filtered/sorted Work record set, including the same linked and embedded Results used by the Results window. Marking alone does not select export rows;My Workspacerestricts them only when active, alongside ordinary filters and drilldowns. Use exactly two content columns,Soll-ZustandandAbweichungen, with source-backed remediation/verification, original technical facts, scoped GPO provenance, and explicit missing-evidence notices. Preserve neutral verdicts and review-versus-rescan boundaries. Build the frozen projection only on export, not on navigation. Oversized CSV cells use explicitly identified continuation rows of the same finding without truncation. This view snapshot is separate from the curated Arbeitsgrundlage indocs/REPORT_STRATEGY.md. -
A unique
Source: Scanselection is a semantic tool context even when Work remains on the project-wideAll Recordssheet. Visible and active facets must follow the selected tool context rather than the aggregate sheet profile. -
Explicit user correction 2026-09-25: changing
Source: Scaninside Work, including back toAll, starts the newly selected source with the clean Work default. Clear the previous search, status override, other facets, record-ID/path restriction andMy Workspacerestriction, restore the standardDeviationstatus and normal sort, then apply the selected source. Keep the current Work view mode and current client/timeslot. This applies to an in-Work source change, not to an incoming Client Info or Pathfinder drilldown before the user changes Source. -
For a GPO-only Work context, whether reached through the dedicated GPO sheet or
Source: Scan = GPOs, show onlyResult Status, the available GPO facetsBaseline,Comparison,Conflict,Description source,Diagnostics,Duplicates,Imported,Policy section,Policy type, and the permanent finalSource: Scancontrol. Do not show CIS, severity, category, MITRE, target, result-message, review, or scanner-specific facets. -
Explicit user correction 2026-09-17 supersedes only the category exclusion in the preceding GPO-context rule:
Categoryis a permanent GPO Work filter in both supported entry paths, including when its only current value isGPOs. Keep it directly afterResult Status. Severity, CIS, MITRE, target, result-message, review and scanner-specific facets remain excluded from the GPO-only context;Source: Scanremains last. -
Explicit user extension 2026-09-17: Work also exposes a distinct
Security Domainfacet immediately afterCategory. It must use the exact shared Client Info security-domain catalog and record assignment, never a second filter-only categorization. It is available in mixed Work and both GPO entry paths; a pure GPO scope maps toGPO & Baseline. Domain selection and Client Info drilldown must therefore select the same record identities, while ordinary active Work filters continue to apply.Source: Scanremains last. -
Explicit user correction 2026-09-18:
Security Domainalways offers all eight Client Info catalog entries in catalog order, including selectable zero-hit domains in mixed Work and both GPO entry paths.Unclassifiedremains an additional option only when present in the loaded sheet. Counts respect the other active filters; a zero-hit selection must not silently remove itself, the active status, or another still-valid facet selection. A Client Info domain-deviation drilldown uses this visible domain facet rather than a fixed record-ID path, so the user can change domains in Work. Explicit review-only and individual-finding paths retain their separate scope semantics. -
Explicit user decision 2026-09-17 supersedes the previous six-value list: the GPO
Result Statuschoices are exactlyAll,Deviation,Passed,Not configured,No baseline rule,Not comparable,Conflicts, andDuplicates. Keep the seven non-All choices selectable at zero hits; never merge scanner-only status vocabularies into a GPO-only context.Deviation,Passed,Not configured,No baseline ruleandNot comparablematch the authoritative rolled-up policy verdict;ConflictsandDuplicatesmatch the corresponding diagnostic category flags. One policy setting may therefore belong to bothDeviationandConflictsorDuplicates. -
Explicit user decision 2026-09-17:
No baseline ruleis the score-neutral verdict for a retained customer setting whose resolved technical identity has no applicable Microsoft baseline recommendation in the compared baseline set. Every aggregated customer state must reach Work under exactly one verdict: an evaluated verdict where a baseline rule exists, otherwiseNo baseline rule. It is distinct fromNot configured, which is a recommended baseline setting absent from the analyzed backup set, and it must never be presented as a deviation, remediation obligation or score input. A diagnosticConflicts/Duplicatesflag marks such a setting without replacing its verdict; unresolved identities stay out of this verdict and takeNot comparableinstead. -
Explicit user decision 2026-09-17:
Not comparableis the score-neutral verdict for a retained customer setting whose delivery mechanism has no comparable technical policy identity. Today this is always a Group Policy Preference. Never resolve a preference into a policy identity and never compare it with a Microsoft baseline recommendation: its action, item-level targeting and apply-once semantics differ from a policy setting, so a baseline verdict over it would be invented. Keep the retained CSE, action and item-level targeting readable in the agreed GPO columns; do not add a GPO Work column or facet for them. Identical or differing preference instructions are not proven duplicates or conflicts, soNot comparablecarries no diagnostic flag. The observation-level unresolved-identity gap reporting stays in place and must report each observation once with its authoritative resolver reason, never restated a second time by snapshot aggregation. -
Never infer a GPO verdict from comparison prose, historical results, baseline text, guidance or evidence. Use only the authoritative rolled-up policy verdict and explicit conflict/duplicate flags. A foreign
Passstring must not make a not-configured, review or failed policy setting matchPassed. -
When the selected tool context makes an existing facet filter invalid, remove that incompatible filter so it cannot remain invisibly active. Removing the tool restriction restores the appropriate aggregate facets without changing source data.
-
Explicit user extension 2026-09-17: also offer
GPO backups with failing settingsin the GPO Work context. Its all-counted and individual-backup selections use the Processing tile's exact project/assessment/backup-instance identity and select source-linked Fail comparisons, not inferred per-backup verdicts. Keep all contributing evidence, conflict/duplicate flags and historical evaluation readiness intact; Source: Scan remains last. This extends the facet list above.
UI Result DB filter consistency
-
Explicit user decision 2026-09-25: Result DB API and JSONL retain the actionable per-tool finding, public rule ID when validated, result/severity, available scanner guidance, and the GPO comparison's concrete technical Ist-/Sollwert and baseline. Do not invent an Istwert absent from the source. Concrete person, account, tenant, customer and system identities remain outside this disclosure projection. Non-public system SIDs use stable result-local placeholders throughout nested policy values and baseline variants; public Windows SIDs remain readable. CIS-CAT control numbers and verified public policy guidance must not be mistaken for private IPs or accounts. Keep complete originals in internal analysis.
-
Explicit user correction 2026-09-20: in linked CIS-CAT Results evidence, an evaluated source row must follow the actual finding outcome. Highlight the confirmed configured row with the shared green match treatment when the finding outcome is
Pass, and use the red violation treatment only when the outcome isFail; unknown, neutral or unavailable outcomes must not be guessed into either state. The criterion row remains the separately identified expected state. -
Explicit user correction 2026-09-18: Result DB uses the shared Work vocabulary for its GPO
Result Statusfilter and details:Deviation,Passed,Not configured,Conflicts, andDuplicates;Review requiredremains an independent unresolved result. Stored classification/query values stay unchanged. Status facet counts must honor all other active filters, including Deviation; only their own status selection is excluded to keep alternatives reachable. Selecting or clearing a status must never silently reset Deviation. Selected zero-hit values stay visible and removable. This supersedes the earlier Result DB exception that ignored and automatically cleared Deviation. Result DB still counts individual comparisons, while Work counts rolled-up settings; no extra public observation types or invented statuses are introduced.
GPO Registry baseline comparison
- Treat retained
Registry.poldelete-value,delete-all-values, andcreate-keyinstructions as explicit, comparable target states rather than unavailable baseline values. The comparison remains scoped to imported backup configuration and must never claim effective endpoint registry state. - A delete-value requirement passes when that value is absent from the analyzed backup set or explicitly deleted, and fails when the value is set. A delete-all-values requirement passes only when no value is configured below that key or the delete-all instruction is explicit; any retained configured child value fails it. A create-key requirement passes when the key is explicitly created or a retained configured child proves its presence, and fails when the key is absent.
- A typed empty
REG_SZorREG_EXPAND_SZis a present value. Compare its registry type and exact empty content; never convert it to missing/unavailable. Missing required presence is Fail, while ordinary missing value recommendations remain score-neutralNot configured. - Preserve contributing child-state IDs and observation provenance for key-level comparisons. Unsupported Registry.pol special operations remain
Review required; do not guess their semantics.
GPO analysis and scoring scope
-
Explicit user decision 2026-09-17: the Finding Reader must immediately show contributing GPO backup instances and attribute every retained operation/value to its source, including deletion instructions. Group by exact project/assessment/backup-instance identity, not title, registry value or observation count; retain source-local sequence and never present different GPOs as one execution chain. Show retained native GPO/backup IDs; do not infer missing friendly names from paths. This inline source attribution supersedes any earlier Results-only hiding of these sources, while Results remains available for variant comparisons.
-
Explicit user decision 2026-09-17: render that inline attribution as one flat table with the columns
GPO source,Operation,Data,Type, andEvidence, one row per exact backup identity, a compact status marker, and expandableShow source details. The expansion retains full GPO/backup identity, source-local sequence, safe evidence reference, key, value name and every original instruction. Bold Operation and Data. MarkConflicting contributiononly when the retained current baseline variants independently prove that single source member differs; mark alignment only when every retained variant independently matches. Do not derive source markers from historical evaluations, multiple instructions inside one backup, GPO precedence or endpoint effectiveness. -
Explicit user correction 2026-09-17 supersedes the flat table presentation above: show each exact GPO backup identity again as a complete, vertically stacked source section with Evidence, source-local sequence and every original instruction immediately visible. Use a restrained red background and red leading accent for a source section only when the retained current baseline variants independently prove that single source member differs. Keep aligned, unassessed and ambiguous sections neutral; retain the same historical, precedence and endpoint-effectiveness boundaries.
-
Explicit user correction 2026-09-17 supersedes the whole-section red treatment above: keep every GPO source section neutral and apply the restrained red background only to the exact displayed field value proven different from every retained current baseline variant. Highlight
Operationfor an operation mismatch,Datafor a data mismatch andType codefor a registry-type mismatch; several fields may be marked only when each is independently proven. Do not highlight a whole source, heading, path, key, value name or conflict badge, and do not guess a field when variants disagree about the cause. -
Explicit user correction 2026-09-25 supersedes the always-visible source sections above in one case only: when the Finding Reader's first-read problem summary is shown and several GPO backups retain literally the same instruction (registry key/value-name letter case aside), the complete source sections sit in a collapsed
Show the N identical source instructionsdisclosure below the source count and notice. The problem summary states the shared value and names every contributing backup; nothing is removed, and field-specific red value markers are unchanged inside the disclosure. A later 2026-09-25 correction extends this to different instructions: the visible value overview names every distinct instruction with its contributing backups, and the complete sections sit in a collapsedShow the N source instructionsdisclosure. A single source and historical or unstructured comparisons keep every source section immediately visible. -
Explicit user decision 2026-09-25: the GPO first-read
Problemblock and the separateNext stepblock each carry one leading marker at the shared--marker-width. Problem uses the outcome color (--outcome-failfor Fail,--outcome-passfor Pass, neutral otherwise); Next step uses the orange--next-step-accentrole, which reuses the existing--sev-highorange. No other status fill. -
Explicit user extension 2026-09-17: every proven GPO source-value deviation must receive the same restrained red value treatment. Keep registry-policy differences field-specific for
Operation,DataandType code, including simultaneous differences. For other comparable GPO value kinds, or when all retained variants prove a difference but no one field is the common cause, mark the displayed source value as a whole without asserting a narrower cause. Review-required, unassessed and aligned values remain neutral; never color the whole source section, heading, evidence path or diagnostic badge. -
Explicit user decision 2026-09-25 supersedes only the neutral treatment of aligned values in the preceding rules: wrong settings are red and correct settings are green, so right and wrong are visible at a glance. Green uses the same restrained value treatment with the success color and requires the same proof as red in the opposite direction: a whole value matching every retained current baseline variant, or a principal-set member present in the expected value of every retained variant. A value or member that matches only some templates, review-required, unassessed and historical values stay neutral; never guess from GPO precedence, endpoint effectiveness or an inferred role. The rule applies to the GPO source sections, the Finding Reader problem summary and the GPO conflict/duplicate variants in Results (a variant is colored only when every one of its sources has the same proven relation). Apply it to other scanner Results only where the source proves correctness per value or row; CIS-CAT keeps its existing evaluated-row treatment.
-
Explicit user correction 2026-09-17: a principal-set is a collection comparison, not one indivisible value block. Mark only configured principals absent from every retained current baseline variant. A principal also present in the expected baseline remains neutral even when neighboring principals deviate. If the deviation consists only of a missing expected principal, do not color an existing configured principal as its substitute; the expected-baseline block remains the evidence for that absence.
-
For versioned member comparisons, derive the Conflict flag from the retained authoritative customer state, not from a set-value-only subset of original instructions. Reduced-identical contributions from multiple backups may be Duplicate; multiple earlier instructions inside a single backup are not duplicate GPOs or independent current conflicts. Keep these diagnostic flags separate from the policy verdict and preserve historical evaluation readiness.
-
An additional indeterminate GPO must not hide an independently proven difference between other GPO backups. Retain that diagnostic only when distinct, unambiguous backup contributions of the same technical setting prove different supported signatures also present in retained compared values. Exclude the whole uncertain backup from that proof; its earlier writes may remain in retained values and must not be mistaken for separate GPOs. The overall verdict remains Review required.
-
Explicit user decision 2026-09-25: a GPO backup whose own
GPReport.xmllists no enabled link to the domain or an OU is shown asNot linked(source badge and note,No effectline in the problem summary when every contributing GPO is unlinked, count in GPO Processing). Retain only link counts, never OU or domain names. It is a backup-report fact, not effective device state, and it changes neither verdicts, conflict/duplicate flags nor the score. Backups processed before metadata parser 1.4.0 show no link status until reprocessed. The measured decision of the same date not to introduce a per-GPO target role stands; no role is derived from links beyond this presentation. -
The operational GPO assessment is misconfiguration-first and limited to customer settings that are actually configured, technically comparable and in the explicitly applicable Microsoft-baseline scope. Do not turn every recommended but absent baseline setting into an operational finding, remediation obligation or score penalty. A complete-baseline rollout is a separate, explicitly commissioned hardening track.
-
Not configuredremains a score-neutral policy verdict.DuplicatesandConflictsremain visible, mutually distinct diagnostic categories on a policy setting; they are not alternative verdicts that can suppressPassed,FailorReview required. -
Roll member comparisons up once per technical policy-setting identity. If at least one independently comparable, in-scope configured member value is a valid
Fail, the whole policy setting verdict isFail, while its conflict/duplicate flags remain visible. If every applicable member passes, the policy verdict isPassed. If member applicability, precedence or comparison is unresolved, useReview requiredrather than inventing a fail. Source multiplicity, duplicate rows and diagnostic flags must never multiply the setting's score weight. -
Label the GPO score as conformance of configured, comparable in-scope settings. Never describe it as full Microsoft-baseline compliance, baseline coverage or proof that all recommended settings are implemented.
-
Keep absent recommended settings available under
Not configuredfor transparent inspection, but exclude them from Priority Findings, default remediation scope and score unless the user explicitly starts a separate baseline-hardening scope. -
Not configuredis scoped to the analyzed GPO backup set: if an applicable baseline recommendation has no observed configured value in that set, keep it filterable asNot configuredeven when the import is a selected subset. Retain a scope-limit diagnostic and never turn this into a domain-wide or effective-device absence claim without complete collection evidence or RSoP/GP Results.
UI table row marking
- Explicit user decision 2026-09-25: clicking any data row in an application table marks the entire row so its cells remain visually connected during horizontal scrolling. This includes native tables in Work, Client Info and Results windows and the row-based Result DB table. Header and virtualization spacer rows are not selectable.
- Keep one reading marker per table until another data row in that table is clicked. Explicit user correction 2026-09-25 supersedes the yellow row color only: use the dedicated blue
--table-row-markingand its translucent surface in both themes. This row-reading exception does not change the yellow selection role of tiles and controls or the separate blue keyboard-focus role. Preserve existing pass/fail/evidence colors and text. Marking must not replace an existing row action such as opening details, following a link or resizing columns. Virtualized Work Grid rows restore their marker when scrolled out and back.
UI segments and tiles
- Treat segments and tiles as a binding two-level visual grammar independent of their content. A segment is a transparent grouped layout; a tile is a flat, square-cornered surface inside it.
- Use only the shared
--segment-*and--tile-*tokens for segment surfaces, borders, radii, insets, gaps, tile surfaces, shadows, widths, hover states, and selected contours. Do not create view-local substitute geometry. - Segments are visually transparent and have no visible border or shadow. They retain
--segment-radius, one uniform inset, and one uniform gap as shared layout geometry. - Tiles use the common white or theme-equivalent surface without a visible normal-state border, radius, or shadow. Hover changes the surface only and must not add a decorative contour, lift, or translation.
- Explicit user correction 2026-09-20: in the light theme, tile surfaces use the shared neutral gray
--tile-surfaceinstead of pure or near white to reduce glare; the current approved value is#F5F5F7. Keep the surrounding app surface, input surface and established hierarchy distinct; do not reproduce this with view-local overrides. - Explicit user correction 2026-09-25 supersedes the no-visible-border rule above for the light theme only: because the approved light tile surface and app background differ only slightly and neither color may change, every tile carries one neutral 1px hairline through the shared
--tile-bordertoken (#DCDDE3). The dark theme keeps--tile-border: transparent, where the surface luminance step separates tiles. Keep every surface color unchanged. The hairline is a neutral contour, not a status, selection or focus signal: persistent yellow selection and blue keyboard focus stay distinct, hover changes only the surface (--tile-surface-hover, slightly lighter) and keeps the same contour, and shadows, lift and gradients remain excluded. Dividers inside a tile use--tile-divider; do not darken the global--border-subtle, which also draws the approved Work list separators. Apply the contour only through these tokens, never through view-local values. - Explicit user correction 2026-09-25: the Client Info
Datatile's nestedDeviationsdonut action has no visible rectangular contour. Keep the outerDatatile's shared contour; the donut uses the transparent shared segment-border role in both themes. Its blue keyboard focus outline remains available. - Status color belongs only in a small accent line, marker, data visualization, or selected contour. Never fill the complete tile with a status color.
- Keyboard focus and selected tiles use the shared functional focus or selected outline. Action tiles and add tiles use the same flat geometry as content tiles.
- Explicit user correction 2026-09-20: the persistent yellow outline of the selected Data Hub tenant tile is one hairline thicker than the shared 2px selection outline, composed from
--bw-emphasisplus--bw-hairline. This is a scoped Data Hub tenant-selection exception; keyboard focus remains the separate shared blue 2px outline, and no other tile-selection width changes. - The persistent marking and selection color is the shared yellow
--marking-colorin both themes, except for the explicitly blue table-row reading marker documented above. Purple must not be used for selected contours or markers. Blue is otherwise reserved for keyboard focus, while green, red, orange, and severity colors remain domain status signals rather than selection colors. - Keep unused segment space intentionally empty: lay tiles out from the start at their shared compact or content width and never stretch a partial final row merely to fill the container.
- Explicit user correction 2026-09-20: the Data Hub result-donut row and the client/add-tile row below share the exact same six-column track geometry at wide widths. Every column start, width and gap must align vertically without cumulative horizontal offset; all six result donuts remain on one line. At narrower widths both rows return to the same compact responsive tile contract.
- Tile content must never cross the tile boundary or cover a neighboring tile. Nothing may be clipped, clamped, truncated, or replaced by an ellipsis. Text and actions reflow inside the tile; media scales within the available inner area. If content does not fit, enlarge or reflow the tile.
- Avoid line breaks in compact tile labels where practical. If wrapping is necessary, wrap only at word boundaries: never split ordinary words or numeric values across lines. Use a wider or responsive tile whenever a complete word or value cannot fit.
- Explicit user decision 2026-09-20: purple/violet is removed as a UI role entirely, not only as a selection color. The
--accent/--accent-hover/--accent-active/--accent-on/--accent-subtletokens insrc/styles/ui-tokens.cssmust not resolve to a violet value and must not be read wherever the consuming rule means keyboard focus (use--focus-ring) or active/selected state (use--marking-colorand its existing selection/marker roles). A tool- or graph-category tone (for example the PKI chart tone) that previously reused--accentgets its own dedicated, non-violet, non-focus, non-marking category color instead of being retargeted onto focus or marking roles. This closes the drift documented in Client Info/Work/Pathfinder screenshots reviewed 2026-09-20, where the same segmented-tab-selection component rendered amber in one view and violet in another because--accentwas simultaneously documented (supersededassessor-uiskill text) as meaning both "primary action / active view / selection" and used in code for:focus-visible, conflicting with the yellow-marking/blue-focus rule above.
UI donut charts
- Every donut chart uses the same full 360-degree geometry: a continuous neutral-gray track and a colored clockwise value arc starting at 12 o'clock.
- Explicit user correction 2026-09-25 supersedes the 2026-09-24 image-reference presentation: restore the prior donut design with titles outside the rings, the prior compact Data Hub ring size, and no ring shadow. Preserve each metric's count/percentage or score semantics and the meaning of segmented distributions. Keep the later explicit loading-state behavior so pending values are not shown as zero.
- Donut arcs use flat ends and the shared
--donut-ring-stroke,--donut-track, value, and typography tokens. Do not introduce 270-degree gauges, open gaps, rounded arc caps, or local substitute geometry. - Explicit user correction 2026-09-25: calculate every donut arc from the unrounded share. A positive share below 2% also receives a narrow, flat, same-tone radial mark so it remains visible at the compact ring size; a true zero has no mark. A positive share that rounds below 1% is labeled
<1%, never0%. Keep the exact share in the arc and existing count/score semantics in the readout. - Explicit user correction 2026-09-20: every count/percentage donut places the absolute count as the bold first line and the percentage as a regular-weight second line below it. Every donut readout, including score rings, keeps a visible safety gap from the inner edge of the ring at every supported ring size and value width. A score ring such as Overall Score retains its score-specific
/100semantics instead of inventing an absolute count. - Center the complete two-line readout as one unit inside the ring without letting either line shift horizontally. Keep every text element fully within the clear inner area and never let it touch or overlap the ring at any supported value width.
- Multi-segment distributions retain their categorical segments, but use the same track, stroke proportion, start position, centered value treatment, and shared tokens as single-value donuts.
UI Client Info dashboard
- Explicit user correction 2026-09-20: the former Client Info
Priority Findingstile is namedData, sits to the left ofDomain Information, and shows the totalDeviationsvalue plus the separate additional-result-state row only. Do not show duplicateCriticalorHighsummary values in that tile. The remaining deviation value occupies the full header width and is a keyboard-accessible button that opens Work with the standardDeviationfilter. - Explicit user correction 2026-09-18 supersedes the previous Client Info visual exception:
.client-command-centerfollows the same Ableton-inspired ASSESSOR language as the approved Data Hub, Work and Pathfinder. Client Info may organize its own domain content, but has no exception for palette, surfaces, tiles, typography, controls, selection, branding, spacing or chart geometry. Existing--client-info-*roles are legacy implementation details, not authority for a separate visual theme; reuse the shared roles when bringing this view into conformity. - Treat Client Info as one connected executive security-posture canvas, not as a collection of unrelated report cards or a spreadsheet. Its stable reading order is overall posture, security domains, Data and Domain Information, then source evidence.
- Keep environment facts in a compact evidence rail, using the same neutral theme-aware tiles as Data Hub. Wrap at readable widths instead of forcing one tiny-text row. The former mandatory dark-tile treatment is superseded by the 2026-09-18 correction.
- Explicit user correction 2026-09-20 supersedes the separate evidence rail above: AD Domains, Entra Tenant, User Accounts, Computer Objects, Domain Controllers and GPOs live inside the
Datatile as one flat 3-by-2 fact grid, retaining their existing glyphs. Do not render a separate top-level Environment Facts tile row. The six facts are not nested tiles; use transparent cells and subtle separators insideData. - Present Overall Score and Security Domains together on one shared posture surface. Overall Score is the dominant visual anchor; domain scores form a visibly connected branch or spine beside it and must not look like a conventional data table.
- Explicit user correction 2026-09-20: at wide desktop widths, the posture surface and action rail each use exactly one half of the available row width. This supersedes the earlier two-to-one proportion. Every tile aligned in one row must always share the same height and bottom edge; never use intrinsic-height staggering within a row. This also supersedes the earlier instruction to keep the posture surface shorter than the action rail.
- Explicit user correction 2026-09-25 supersedes the earlier action-rail geometry:
Datasits to the left ofDomain Informationin an exact 50/50 row with identical height. The separateAssessment Gapstile is removed; the authoritativeGapscount and its Work drilldown remain inData. The adjacent posture surface has the same bottom edge as this row. Domain Information contains every fact from the Environment DetailDirectorygroup—Domain, NetBIOS name, Forest, Domains, domain functional level, forest functional level, schema version, domain created and Entra ID—plus the separately requested domain-controller count. All values come only from the same normalized Environment Snapshot. Missing facts remain an em dash and must never be inferred as zero. - Explicit user correction 2026-09-25: In
Domain Information, show the Domain first across the full width, then pair NetBIOS name with Forest, Domains with Domain controllers, Domain functional level with Forest functional level, DC OS with Schema version, and Domain created with Entra ID. This changes only presentation order; keep the source-backed values and unknown-value semantics. - Explicit user correction 2026-09-20: the Overall Score block does not repeat a textual score status below the ring and does not repeat the critical-finding count already present in Priority Findings. Assessment Coverage uses at most 70% of the Overall zone and never exceeds the shared compact tile-content width; it must end before the curved domain connectors, which may never cross its label, bar or supporting count.
- Explicit user correction 2026-09-20: the Overall Score block also omits the secondary
UnassessedandLowest domain pass ratefields completely, including their divider container. The unassessed count remains visible asGapsin Data; domain pass rates remain visible on their individual Security Domain nodes. - Explicit user decision 2026-09-18: preserve the thin curved fan connections from Overall Score to every displayed Security Domain during the Ableton-style alignment. They are a binding visual feature, not optional decoration. Derive their endpoints from the rendered ring and domain nodes and remeasure on resize/content changes. Preserve the existing stacked narrow-screen fallback; never keep desktop coordinates on a stacked layout.
- Explicit user correction 2026-09-25: Security Domain rows are compact enough for all eight domains to fit beside Data without clipping. Domain names use the shared H3 role; the score node and right-hand deviation or review count remain, without the former metadata line. The Overall Score ring is a keyboard-accessible entry to Work's clean remediation default: clear prior search, source, domain, severity, record-ID and workspace filters, select
Deviation, and open the standard Work overview. - Explicit user correction 2026-09-20: Every displayed Security Domain row carries a subtle amount bar in its own shared grid column between the longest rendered domain label and the widest rendered amount. Keep the shared gap on both sides so a bar can never grow into text or behind a number. All bars share one right edge and extend left from that edge. The later color correction supersedes the preceding categorical-color decision: every amount bar uses the exact current semantic color of the Overall Score donut and changes with that score's critical, medium, passed, or unknown tone. Do not use selection, focus, per-domain score, or a separate palette. Bar width is that row's displayed deviation amount divided by the sum of the displayed domain amounts; review-only rows use their already-displayed review amount. Keep the exact right-aligned number visible as the authoritative value, make the bar decorative and hidden from assistive technology, and never change counts, scoring, classification, or drilldown semantics to produce the visualization.
- Explicit user correction 2026-09-25: Within each Client Info Security Domain row, center the domain name, amount bar and amount number vertically on the center of that row's score circle. They belong to one grid row; do not let the circle span an unused second row that shifts the other elements upward.
- Explicit user correction 2026-09-20 supersedes the transparent Client-Info donut treatment above: the total
Deviationsdonut in Client Info'sDatatile uses the exact Data Hubdatahub-reference-knobvisual variant, including its tile surface, dimensions, spacing, title and hover state. Data Hub and Client Info derive its count and percentage denominator from the same selected mixed-timeslot project sheet, including assessment-bound GPO/policy observations as well as scanner records; never calculate the Data Hub value from scanner run IDs alone. The complete donut remains a keyboard-accessible action to Work with theDeviationfilter. - Explicit user correction 2026-09-25 supersedes only the Client Info
Datadonut dimensions and spacing in the preceding rule: expand its ring to the largest size that fits above the result states and environment facts without increasing the shared tile height or clipping content. Keep the Data Hub donut component, external title, colors, value semantics, hover state and Work interaction. - Explicit user extension 2026-09-20: Client Info's Operating systems table shows PingCastle's row-bound
Nb Active,Nb Inactive,Nb EnabledandNb Disabledcounts besideNb OS. Join each value only to the exact retained report, source table and row of that operating-system entry; never derive one state from another, borrow a value from a different row or add overlapping inventories. Missing values render as an em dash. Other scanners and older imports remain visible without invented state counts. - Keep Client Info immediately scannable: Environment Detail starts collapsed with its evidence/restriction counts visible; the Accepted Risks master/detail summary remains visible, while its complete context, controls, approval, evidence and decision history are individually expandable. Disclosure must remain keyboard accessible and must not change source data, scoring, risk decisions or drilldown identity.
- Explicit user correction 2026-09-20: every Environment Detail tile heading, including Source Overview and Operating systems, carries one restrained existing ASSESSOR line glyph before its title. All fact groups reuse Source Overview's list spacing and row padding for one consistent, airy rhythm; fixed tile heights, the four-column grid and internal scrolling remain unchanged.
- Explicit user correction 2026-09-20: Accepted Risks adopts the Data Hub
Manage Clientmaster/detail interaction and geometry. The fixed-width, independently scrolling navigation on the left owns the register heading, count, selection and compact state/date rows; the equally tall information pane on the right owns the selected risk, summary and expandable detail groups. Yellow marks persistent selection, risk state remains a separate text-and-dot signal, Arrow Up/Down/Home/End move the selected risk, andOpen findingopens that exact record in Work. At narrow widths the panes stack without horizontal overflow. - Explicit user correction 2026-09-20: Accepted Risks adopts the Data Hub
Manage Clientmaster/detail interaction and geometry. The fixed-width, independently scrolling navigation on the left owns the register heading, count, selection and compact state/date rows; the equally tall information pane on the right owns the selected risk, summary and expandable detail groups. Yellow marks persistent selection, risk state remains a separate text-and-dot signal, Arrow Up/Down/Home/End move the selected risk, andOpen findingopens that exact record in Work. At narrow widths the panes stack without horizontal overflow. - Explicit user correction 2026-09-20: Accepted Risks reuses the Data Hub client-detail geometry one-to-one: a fixed compact selection rail at the left using
clamp(420px, 27vw, 520px), the information surface at the right, and the established stacked narrow-screen fallback. Do not reintroduce a proportional wide list column. - Keep Data and Domain Information in the dedicated action rail. Use status color only for finding markers, score arcs, score nodes, and progress bars; avoid large colored fills and nested card stacks.
- Explicit user correction 2026-09-20 supersedes the standalone Source Overview rail: source scores live inside the expanded
Environment Detailas one compact plain list with separators, never as tiles. Preserve every source's actual versioned ASSESSOR score contribution, method label, native context and Work drilldown. A run/file-bound native score takes priority when supported and pass rate is the fallback; PingCastle uses the explicit100 - native riskconvention and retains raw risk as secondary context. Never insert a raw lower-is-better risk value directly into the overall scale. Followdocs/SCORING_MODEL.md; Security Domain values are pass rates, not a decomposition of the mixed-method index. - Explicit user extension 2026-09-20 supersedes only the preceding container geometry: all expanded Environment Detail groups form an equal four-column tile grid.
Source Overviewoccupies one group tile while its individual source entries remain the agreed plain separated list, never individual source tiles. The six fact groups and Operating systems each occupy one tile. Every tile is exactly three quarters of the currently rendered Overall Score tile height; derive that height from the rendered element and keep overflow inside the affected tile with a scrollbar. Preserve four columns on narrow layouts through horizontal grid scrolling rather than changing tile width or column count. - Explicit user correction 2026-09-25 supersedes the preceding Environment Detail disclosure and tile geometry: remove the disclosure heading and keep all eight group tiles permanently visible. Use compact square tiles at the shared compact width, wrapping with available space. Show only one or two source-backed overview facts per tile; complete facts, source contributions, original sections, observations and operating-system tables remain available through the tile's
Resultsaction. Keep source drilldowns and scoring methodology reachable from Source Overview Results. Never clip tile content or shrink informational labels below 14px and values below 16px. - Explicit user correction 2026-09-25 supersedes the Source Overview tile in the preceding rule: remove that tile entirely, leaving seven permanent square environment tiles. Keep the full source-score contributions, source-linked Work drilldowns, restricted-section explanation, original scanner evidence and scoring methodology accessible from a compact
Resultsaction besideOverall Score. Directory's compact preview shows the source-backed domain count so its value fits without splitting the domain name; the full name remains in Domain Information and Directory Results. - Explicit user correction 2026-09-25 supersedes the seven tiles' compact width and single-fact preview above: use twice the shared compact tile edge and show the initial source-backed hard facts in a space-efficient two-column layout. Inventory shows all eight facts, including enabled/disabled accounts and the assessed host, directly in its tile. Directory shows its first six facts; its remaining facts are visible in Domain Information and Directory Results. Source metrics shows up to eight available metrics, while Results retains the complete list. Operating systems shows available group totals and first source rows; its full table remains in Results. Keep 14px information labels, 16px values, natural growth for longer content and no clipping.
- Explicit user correction 2026-09-25 supersedes the earlier H3 Security Domain names and larger Domain Information/Environment tile headings: every Client Info dashboard tile except Overall Score follows Data's 16px title/value and 14px informational-label roles. Bring Data's own 12px informational labels up to the binding 14px minimum. Give each fact in Domain Information and the seven environment tiles a separate flat cell with the same subtle separators as Data; each Security Domain row also receives a subtle cell contour. Preserve the current source-backed content, interactions, semantic chart colors, 14px minimum for information and natural growth without clipping. The Accepted Risks master/detail workspace remains its separately agreed Work-style reading surface.
- Explicit user correction 2026-09-20: Source Overview never renders a
Tabular Datatile. Generic tabular imports remain available through their supported data and filter paths, but they are not a security-scoring source tile. - Unknown or unavailable facts render as an em dash and never as an inferred zero. Keep the dashboard English-only and omit explanatory prose that does not support an immediate first-meeting statement or action.
- The content hierarchy, score semantics, source provenance and drilldowns remain binding. Their layout must use the shared ASSESSOR components and tokens; a connected briefing layout does not permit a dedicated palette or geometry. Source Overview, Environment Detail and Accepted Risks obey this same rule, including their collapsed, expanded and selected states.
UI branding position
- Use the Data Hub header as the binding position reference for the ASSESSOR logo, wordmark, and version.
- Keep the brand container geometry identical across every application view; do not add area- or view-specific brand padding, margin, alignment, height, or transforms.
- Switching views must never move the logo, wordmark, or version.
UI backend connection state
- Data Hub, Result DB and DB Structure must present a checking or unavailable local backend through the shared ASSESSOR dialog rather than an embedded page banner.
- Keep that dialog dismissible so the user can inspect the underlying view. The application continues its existing automatic health checks; reconnecting removes the offline branch without requiring a reload.
- Keep the copy limited to the affected capability and the automatic connection check. Do not expose response bodies, project data or imported content in this technical connection state.
Navigation and rendering performance
- Explicit user correction 2026-09-25: begin preloading Data Hub's six result summaries while the client overview metadata is loading, before a client is selected. Reuse completed and in-flight summaries across selections and Data Hub revisits. Keep speculative requests and retained values bounded, prioritize a selected scope, and key reuse by repository revision plus exact project/assessment/scan scope. Refresh on import/data/GPO changes; stale responses must never overwrite another selection. Load summaries only, not complete source models into the browser.
- Treat area switches as a performance-sensitive path. Measure the first visit and repeated visits separately after the workspace has loaded; distinguish main-thread rendering from asynchronous API readiness. Use the local procedure in
docs/architecture/navigation-performance.md. - Share expensive filtering, sorting and facet counts between their consumers. Component-local
useMemodoes not survive an area unmount. Use bounded, dataset/sheet-owned caches with immutable input identities and all semantic dependencies (profile, dataset, reviews, filters, search, sort and timeslot/path scope); never cache solely by a reusable entity ID. Verify invalidation as well as reuse. - Build raw text, detailed result projections, graph layouts and other large derived content only when the corresponding view needs it. Virtualized views must not serialize or derive presentation fields for every offscreen record. The initial render must also be bounded by the viewport plus overscan.
- Large native selectors must not mount thousands of unused options during area navigation. Show the current selection immediately and prepare the complete option list before pointer opening or keyboard focus; verify keyboard access and selection preservation. Construct export payloads only after the export action.
- Classify shared headers once per derivation, normalize sort keys once per record, and count facets in a shared pass. Rejected numbered column groups must not trigger repeated scans of all their siblings. Stop category eligibility checks once their cardinality limit is exceeded, while preserving exact counts for eligible facets.
- Retained views mount on their first activation. While hidden, freeze their input context and stop geometry observers and animation frames; resume with current inputs when activated. Reset retained state when the workspace scope changes. Keep selections and original source values intact.
- Polling an unchanged health/status value must return the existing state instead of rerendering the application. Do not introduce keep-alive polling or data caches without explicit freshness and invalidation behavior.
- For performance fixes, add behavioral cost checks (for example, zero source-field reads on an unchanged repeat visit, bounded mounted rows, and fresh results after changed inputs). Record wall-clock measurements as observations rather than fragile CI assertions; run browser comparisons without simultaneous builds or load tests.
- Follow the privacy-safe testing rules below. Local opt-in measurements may contain only area names, durations, counters and technical states; no report text, tenant identifiers, filenames, external telemetry or production instrumentation.
Security and verification
-
HTML attribute readers must advance monotonically across boolean, quoted, unquoted, malformed, and long valueless attributes; do not use unanchored
name=valuesearches that retry every suffix. Resolve repeated internal IDs/names through an import-local index tied to the exact protected markup, preserving duplicate diagnostics, target order, and source offsets. Guard character work and complete source coverage with synthetic regressions; validate timeout fixes in the built isolated worker without raising its time or memory limits. -
Context-only extractors must not consume finding tables elsewhere in the same workbook. Compose them with the generic table extractor, keep original table indices, and verify summary, findings, and supporting sheets together through canonical projection and result linking.
-
Embedded scanner globals must be located lexically outside strings, comments, HTML attributes, and other raw-text containers. Missing IDs, unreadable payloads, conflicting assignments, repeated IDs, and declared-count mismatches require explicit diagnostics. A declared empty report is distinct from an unreadable nonempty report; explicit null result tables with zero results are valid.
-
Keep native detail timestamps at their full precision and preserve exact source values and field paths, including explicit nulls and unknown fields. Derived display fields reference their real input objects; never invent native paths for generated compatibility columns. Test source-path resolution and detail-cell equality, not only row counts.
-
Scanner coverage must be verified against independently counted source records and source status totals, not just a successful parser return. Preserve declared totals and emit a diagnostic when they disagree with individual results; never drop records to make totals agree.
-
Preserve XML attributes as exact name/value pairs with attribute-level source paths, including namespaces, zero, false and empty values. Explicitly empty leaves must remain distinguishable from absent data; never reconstruct attributes from an ambiguous display serialization.
-
Lexical HTML readers must respect quoted attribute boundaries, raw-text elements and malformed/unquoted attributes without treating tooltip markup as visible tags. Sanitize complete attributes, not attribute-like strings inside other values. Bounded excerpts must not expose a partial trailing tag or discard subsequent source sections. Verify table/section coverage as well as clean cell text in both runtimes.
-
Missing native rule IDs must fail explicitly. Diagnose repeated IDs even when an established first-presentation policy retains one finding. Compare matched counts by category, not catalog size; preserve the original counters and distinguish a declared empty report from an announced but unreadable result set.
-
Embedded report data is inert input. Support only an explicitly bounded static data grammar; never evaluate scripts, calls, getters, spreads, computed properties or template substitutions. Unsupported or malformed recognized reports must fail explicitly instead of becoming successful zero-finding imports. Keep production/browser and server behavior aligned.
-
Mapping rules for ambiguous labels must include their table or candidate context. In Maester,
ResultbesideStatusis evidence; nativeResultwithout a separate status column is the status. Preserve original values and exact source paths through both variants. -
Retain scanner-level metadata separately from findings, including unknown nested fields. Distinguish scanner-runtime machine information from assessed-environment assets. Version extraction/mapping changes and recommend reimport without rewriting historic imports.
-
Apply
docs/REIMPORT_POLICY.mdto every importer and profile change. Any change to recognition, parsing/extraction coverage, persisted context/evidence, finding identity, mapping, normalization, status/outcome/severity/IOE, completeness diagnostics, or newly captured score inputs must add an append-only processing manifest version and mark affected historical imports for reimport. Presentation-only changes over already retained facts do not require reimport. -
A reimport may replace scanner-derived records only. Preserve complete client-owned review objects, including future fields and accepted-risk data, through a unique scanner/rule/asset identity. Keep the prior review and surface a persistent unresolved state when matching is absent or ambiguous; never guess by title or position.
-
Preserve local-only behavior until a server transition is explicitly implemented and documented.
-
Do not introduce external uploads, telemetry, CDN assets, network APIs, shell access, or broader Tauri capabilities without explicit user approval and a security-model update.
-
Treat imported HTML, XML, Excel, JSON, and CSV files as untrusted input. Never execute active content from imported files.
-
Use
npm testandnpm run buildas the baseline verification commands for relevant changes. -
Preserve unrelated user changes and keep implementation-plan updates factual and concise.
Client Info table interaction correction (2026-09-25)
- All Client Info Results categories use the same table interaction: retained base tables, including historical imports without presentation metadata, are immediately readable inline. Do not replace them with repeated
Open tablebuttons or anAdditional source tablesgate. - Preserve original column values and native section/table headings; do not add invented
Table N of Mtitles. Historical flattened source prose belongs in a separateSource textdisclosure, with the retained text still accessible. - Explicit user correction 2026-09-25 supersedes the
Source textdisclosure above: omit that generated control and historical flattened prose from Client Info Results. Preserve the stored source text. Never display importer-generatedTabelle N,Table N, or ordinal suffixes as native headings, whether they arrive through table title, name, subsection observations, row-count labels, or a linked popup/inline target. If no native table heading is retained, show the complete table under its section heading without inventing a replacement. Structured native explanatory prose remains visible. - Native links inside table cells open their exact target as a popup; native links outside tables expand their target inline. Resolve all links within the exact scan-run and import-file identity, and retain every table in a linked target. Missing historical link metadata must never be reconstructed from table order, counts, or guessed group names.
- Apply the shared 14px table/field-label and 16px value/prose roles, 20px window inset, compact fact cells and contained horizontal table scrolling in both themes. Regression tests must open each category through its actual Results action.
Privacy-safe testing
- Treat all real tenant, customer, project, scan, finding, and imported-file data as sensitive.
- Never inspect, extract, log, quote, summarize, screenshot, or otherwise expose real file names, finding titles, field values, raw report content, or rendered report text during testing or debugging.
- Use synthetic fixtures for content-level, parser, importer, mapping, and UI tests.
- Against a real running application, verify functionality only through content-free technical signals such as HTTP status, health state, anonymized counts, boolean DOM state, control availability, and element existence.
- Do not read
innerText, response bodies containing domain data, or screenshots of populated views merely to prove that a feature works. - If real content inspection is genuinely unavoidable, stop and obtain the user's explicit permission for the minimum required scope before accessing it.
- Remove temporary browser profiles and test artifacts immediately after an approved real-application check.