Repository navigation
docs: policy baseline plan (GPO, Intune, Linux) and visualization prompts #1502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
81cb896
docs: policy baseline plan (GPO, Intune, Linux) and visualization pro…
claude c78e36a
docs: tighten visualization prompt 2 after the first render
claude 806e6cc
docs: answer review on the policy plan and the prompts
claude 6a7b270
docs: prompt 4, before/after of a simulated change
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # Visualization prompts — where the stack is strongest (2026-10-12) | ||
|
|
||
| READ BY: anyone asking an image model (GPT image, etc.) for a picture of the | ||
| current state; refresh this file before reusing it after a large merge. | ||
|
|
||
| Rule for every prompt below: an image model draws whatever it is told is | ||
| there. So each prompt names only what has shipped, and marks research as | ||
| research. The evidence column is for the human; do not paste it into the | ||
| prompt. | ||
|
|
||
| ## What has shipped (evidence) | ||
|
|
||
| | capability | evidence | | ||
| |---|---| | ||
| | Directory simulation with version history: AD (LDIF) and Entra (Graph JSON) observed read-only, one history, undo as a new version | dir-sim; image/restore/revert #1473; Lance log D-DSP-2 #1485 | | ||
| | Group membership, direct and transitive (flattened: the intermediate groups are not returned, so a drawn path Anna → GG_Vertrieb → GG_CRM_Users is research) | #1458; Graph groups + `transitiveMemberOf` observed (HubSPO wishlist 19) | | ||
| | Address claim vs delivery kept apart; in Stalwart a distribution list grants delivery only, and security-group membership is not send-as | dir-sim delivery work; Stalwart #13, #14 (`groups_of` = SID chain only). The dir-sim backend is a build feature, not yet selectable in Stalwart config | | ||
| | LDIF export and a read-only LDAP server over a simulated version | #1469, #1453 | | ||
| | One authorization rule shared by Spear, MedCare, a2ui and OGAR: only the signed-in subject holds roles; delegated login read from the token's `act` chain | `rbac_plug::SubjectRoles` + `with_act_claim` #1491; OGAR #356; Spear #25 | | ||
| | Group → role grants in a versioned policy, unread ≠ empty | `GroupRoles::from_policy` #1486 | | ||
| | Mail server and mail hub on that directory: Stalwart resolves recipients via dir-sim; Spear scopes mailbox access by owner | Stalwart dir-sim backend; Spear IAM | | ||
|
|
||
| Research / proposal only (draw dashed, labelled "Forschung"): CE64 | ||
| hypothesis layers and NAL polyfill (#1496, plans only), PLN/Shannon attention | ||
| (#1497), Hyperon/MeTTa projection (#1498), NARS evidence/fission (#1499), | ||
| Rubicon volition (#1500), class-method hot-plug (#1501), policy baselines | ||
| GPO/Intune (plan `policy-baseline-integration-v1`). | ||
|
|
||
| ## Prompt 1 — one-page capability map | ||
|
|
||
| > A clean, modern one-page capability map in German, light background, | ||
| > flat vector style, for an IT decision-maker. Title: "LanceGraph — was heute | ||
| > läuft". Center: a column labelled "Verzeichnis-Simulation (nur lesend)" | ||
| > with four stacked tiles: "Active Directory (LDIF)", "Entra ID (Graph)", | ||
| > "Versionsverlauf mit Rückgängig", "LDAP-Server (nur lesend)". To the right, | ||
| > a tile "Eine Berechtigungsregel für alle Anwendungen" with three small app | ||
| > icons labelled "Spear (Mail-Hub)", "MedCare", "a2ui", and a small badge | ||
| > "angemeldete Person hält Rollen; Vertretung aus Token-Kette". Below it a | ||
| > tile "Mailserver Stalwart: Zustellung aus dem Verzeichnis" with a note | ||
| > "Verteiler = Zustellung, keine Berechtigung" and a small grey badge | ||
| > "noch nicht per Konfiguration wählbar". At the bottom, a separate | ||
| > dashed area labelled "Forschung, noch nicht gebaut" with small grey tiles: | ||
| > "Hypothesen-Schichten", "Aufmerksamkeit (PLN/Shannon)", | ||
| > "Hyperon/MeTTa", "Willensbildung (Rubikon)", "Klassen-Methoden-Hotplug", | ||
| > "Richtlinien GPO/Intune". Solid colour only for built items; grey and | ||
| > dashed for research. No numbers, no percentages, no logos of real vendors | ||
| > other than plain text names. | ||
|
|
||
| ## Prompt 2 — the strongest screen: access path with history | ||
|
|
||
| > A Windows-style admin application screenshot, German UI, title bar | ||
| > "LanceGraph — Verzeichnis-Simulation". Left: a directory tree with | ||
| > "contoso.local [AD]" and "contoso.onmicrosoft.com [Entra ID]", both marked | ||
| > "nur lesend"; under Entra ID show only "Benutzer" and "Gruppen". Center: a | ||
| > user "Anna Müller" with fields "Objekt-GUID" (a GUID) and, separately, | ||
| > "Ort (DN)"; a field "Cloud-Identität: verknüpft über Sync-Anker". A table | ||
| > "Mitglied von" lists only security groups, with column "Art" showing | ||
| > "direkt" or "verschachtelt" (never "über" a named group). Below it, a separate box | ||
| > titled "Verteiler: Zustellung, keine Rechte" listing "vertrieb@". Right: a | ||
| > panel "Zugriffspfade" whose path Anna → GG_Vertrieb → GG_CRM_Users → | ||
| > "Rolle: CRM-Leser (Richtlinie v3)" is drawn dashed in grey with the caption | ||
| > "Pfad-Erklärung: geplant". Top: a version timeline of observed | ||
| > versions as solid dots; from one of them a dashed side branch labelled | ||
| > "Simulation: Abteilungswechsel" leaves the main line. No planned or future | ||
| > versions. A button "Rückgängig als neue Version". Status bar: "Simulation — | ||
| > es wird nichts an AD oder Entra geschrieben · Änderungen als Antrag | ||
| > exportieren". No column called "zuletzt genutzt", no device policies. | ||
|
|
||
| Known misreadings from the first render (2026-10-12): "keine Berechtigung" | ||
| was drawn as "you may not view this"; the distribution group was listed among | ||
| memberships; the simulation was drawn on the observed timeline next to a | ||
| "geplant" version; the DN was labelled as the object id; Entra roles and | ||
| applications appeared although nothing reads them. | ||
|
|
||
| ## Prompt 4 — before/after of a simulated change (the strongest view) | ||
|
|
||
| What backs it: two versions of one history (the observed one and a simulated | ||
| one), each read as a `View`; group changes are the set difference of | ||
| `groups_transitive` on both views; mail effects come from the mail chain | ||
| (`members_transitive_through` mail-enabled); role effects from the versioned | ||
| group-role policy. What does not back it: the intermediate groups of a path, | ||
| usage dates, recommendations. | ||
|
|
||
| > A Windows-style admin application screenshot, German UI, title | ||
| > "LanceGraph — Verzeichnis-Simulation". Top: a timeline of observed | ||
| > versions as solid dots; from the last one a dashed branch labelled | ||
| > "Simulation: Abteilungswechsel Vertrieb → Marketing". No planned versions. | ||
| > Center: user "Anna Müller", field "Abteilung" showing "Vertrieb" struck | ||
| > through and "Marketing". A tab "Vorschau Änderungen" with a table | ||
| > "Auswirkungen der Simulation" and columns "Änderung", "Gruppe", "Art", | ||
| > "Folge". Rows: red "entfernt GG_Vertrieb (direkt, gesetzt)", red "entfernt | ||
| > GG_CRM_Users (verschachtelt, abgeleitet)", green "hinzugefügt GG_Marketing | ||
| > (direkt, gesetzt)", green "hinzugefügt GG_CMS_Editors (verschachtelt, | ||
| > abgeleitet)", grey "unverändert GG_Standort_Berlin". Each row says whether | ||
| > the simulation set it or it follows from nesting. Below, a separate box | ||
| > "Zustellung (keine Rechte)" with one row "vertrieb@ — erhält keine Mails | ||
| > mehr". Right: two columns "Vorher" and "Nachher", each listing roles only: | ||
| > "CRM-Leser (Richtlinie v3)" struck through on the left, "CMS-Redakteur | ||
| > (Richtlinie v3)" on the right; no group chains between them. Status bar: | ||
| > "Simulation — es wird nichts an AD oder Entra geschrieben · 2 entfernt · | ||
| > 2 hinzugefügt · Änderungen als Antrag exportieren". No "zuletzt genutzt", | ||
| > no "Entfernen empfohlen", no Entra roles or applications in the tree. | ||
|
|
||
| ## Prompt 3 — architecture, one rule in many apps | ||
|
|
||
| > A minimalist architecture diagram, German labels, white background, thin | ||
| > lines. Left: two sources "AD (LDIF)" and "Entra ID (Graph)" with arrows | ||
| > labelled "nur lesen" into a box "Verzeichnis-Simulation (versioniert)". | ||
| > From it, an arrow labelled "Mitgliedschaft (direkt und transitiv)" into a box | ||
| > "Berechtigungsregel: nur die angemeldete Person hält Rollen". A small token | ||
| > icon labelled "Anmelde-Token mit Vertretungskette (act)" feeds the same box. | ||
| > From the rule box, three arrows to "Spear", "MedCare", "a2ui", and one arrow | ||
| > to "Stalwart Mailserver" labelled "Zustellung". No arrow points back into | ||
| > AD or Entra. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| # Policy baselines across GPO, Intune and Linux — v1 | ||
|
|
||
| **Status:** PROPOSAL (2026-10-12), D-PBL-0..7. Nothing is authorized past | ||
| D-PBL-0 until the operator makes the three decisions it names. | ||
| Origin: the "Richtlinienverwaltung" panel of the identity console mockup | ||
| (2026-10-12), which shows one setting per row with a value and a status per | ||
| target (GPO, Intune, Linux). Nothing in OGAR or lance-graph reads policy | ||
| today (`grep -i 'intune|gplink|grouppolicy'` over OGAR, lance-graph and Spear | ||
| returns nothing), so the panel shows data that does not exist yet. | ||
|
|
||
| ## Overview | ||
|
|
||
| The panel's premise: Intune can be shown in GPO terms, so that an | ||
| administrator who knows Group Policy sees each Intune setting under the | ||
| name they already know, and GPO, Intune and Linux line up in one row. Part | ||
| of this is real. Intune's "Administrative Templates" are ADMX-backed, and | ||
| Microsoft's Group Policy analytics maps GPO settings onto MDM CSPs, so a | ||
| documented mapping exists for some settings. For many it does not. And a | ||
| "value per target" hides three questions that must not be merged: | ||
|
|
||
| | question | GPO answer | Intune answer | | ||
| |---|---|---| | ||
| | **configured** — what does the policy object say? | `groupPolicyContainer` + SYSVOL files | configuration policy + its settings | | ||
| | **assigned** — who is it aimed at? | `gPLink` on OUs/domain/sites, link flags, security filtering, WMI filter | group assignments and exclusions | | ||
| | **observed** — what does a device actually have? | not observable centrally; per-machine RSoP only | per-device status reports | | ||
|
|
||
| This is the same separation the directory work uses (address claim ≠ | ||
| provisioning conflict ≠ delivery resolution; unread ≠ explicitly empty). | ||
| The panel's "Abweichung auf 3 Geräten" is an *observed* fact and can only | ||
| exist in the Intune column. A GPO column can state *configured* and | ||
| *assigned*, never "compliant". | ||
|
|
||
| ## Constraints carried over | ||
|
|
||
| - **Read-only.** Nothing writes to AD, SYSVOL, Graph or Intune. The console's | ||
| "Bearbeiten" is a change to a simulated version, exported as a proposal. | ||
| - **Encoders hold raw records** (the `ogar-ad` / `ogar-az` pattern): no | ||
| derived "effective" value is stored in an observation. | ||
| - **No HTTP in the encoders.** Recorded Graph JSON and LDIF/SYSVOL files are | ||
| the inputs; fetching is a separate example or tool, like `az_ingest.rs`. | ||
| - **Data, not literals.** The GPO↔CSP mapping is read from its published | ||
| source, never re-typed into a Rust table. | ||
| - **Concepts are minted in `ogar-vocab`** through the hot-plug path; no | ||
| local classid. | ||
| - **Unread is not empty.** A source that was not read yields "nicht gelesen", | ||
| never "kein Wert" and never "konform". | ||
|
|
||
| ## Checklist | ||
|
|
||
| - [ ] **D-PBL-0** Decisions (operator): canonical setting key; home crate; | ||
| Linux source. Mint the policy concepts in `ogar-vocab`. | ||
| - [ ] **D-PBL-1** Intune read: encode configuration policies, their settings | ||
| and assignments from recorded Graph JSON into raw records. | ||
| - [ ] **D-PBL-2** GPO read: `groupPolicyContainer`, `gPLink`, `gPOptions` from | ||
| LDIF; `Registry.pol` and `GptTmpl.inf` from SYSVOL files. | ||
| - [ ] **D-PBL-3** Setting identity: load the published GPO↔CSP mapping as data; | ||
| unmapped settings stay visible in their source's own terms. | ||
| - [ ] **D-PBL-4** Assignment resolution over the directory simulation. | ||
| - [ ] **D-PBL-5** Observed state: Intune per-device status; GPO marked | ||
| "not centrally observable" unless RSoP exports are supplied. | ||
| - [ ] **D-PBL-6** Console projection: the panel reads D-PBL-1..5, empty where | ||
| no source exists. | ||
| - [ ] **D-PBL-7** Linux (PARKED until D-PBL-0 names a source). | ||
|
|
||
| ## D-PBL-0 — decisions needed | ||
|
|
||
| 1. **Canonical setting key.** Options: (a) the CSP path (Intune-native, covers | ||
| settings with no GPO equivalent); (b) the ADMX `class/category/policy` | ||
| name (GPO-native, matches the mockup's wording); (c) both, with the key | ||
| being whichever source the setting came from and the mapping as an edge. | ||
| Recommendation: (c). A forced single key turns every unmapped setting into | ||
| a guess. | ||
| 2. **Home.** Options: (a) extend `lance-graph-dir-sim` (policies live beside | ||
| the directory they target, one version history); (b) a sibling | ||
| `lance-graph-policy-sim` that reads a dir-sim `View` for assignment. | ||
| Recommendation: (b). Policy history changes on a different cadence from | ||
| the directory, and dir-sim's observation schema should not grow a second | ||
| family. | ||
| 3. **Linux source.** No directory holds Linux configuration. Candidates: an | ||
| inventory export from a configuration-management tool, or an agent. | ||
| Recommendation: park until a customer names the tool they run. | ||
|
|
||
| Concepts to mint (names indicative, the vocabulary owner decides): | ||
| `policy_setting`, `policy_object`, `policy_assignment`, `baseline`. | ||
|
|
||
| ## D-PBL-1 — Intune read | ||
|
|
||
| Encoder in `ogar-az` (new module, same shape as `group.rs`): input is | ||
| recorded Graph JSON for configuration policies and their settings, the | ||
| ADMX-backed administrative-template policies, and the assignments of each. | ||
| Device objects are needed for device-group assignment. `ogar-az` encodes | ||
| users and groups only, and dir-sim's `observe::from_graph` skips every other | ||
| object kind, with `members_transitive` returning users only. So devices need | ||
| a population and a device-group membership path in dir-sim too; until they | ||
| exist, a device-targeted assignment resolves to "unbekannt", never to | ||
| "nicht zugewiesen". | ||
|
|
||
| Assignment targets can carry an assignment filter (filter id and | ||
| include/exclude type). The filter is captured raw with its definition; D-PBL-4 | ||
| evaluates it against device properties or reports the assignment as | ||
| unresolved. | ||
|
|
||
| Endpoint names and API versions (several are beta-only) are to be verified | ||
| against current Graph documentation when the encoder is written; this plan | ||
| does not pin them. | ||
|
|
||
| **Gate:** a recorded tenant export round-trips into records whose raw values | ||
| equal the JSON; an assignment with an exclusion group keeps the exclusion as | ||
| its own record (disable run: drop exclusions → test red). | ||
|
|
||
| ## D-PBL-2 — GPO read | ||
|
|
||
| `ogar-ad` already parses LDIF. Add `groupPolicyContainer` attributes | ||
| (`gPCFileSysPath`, `versionNumber`, `flags`, extension GUID lists), and on | ||
| OUs/domain `gPLink` (with its per-link disabled/enforced flags) and | ||
| `gPOptions` (block inheritance), and `gPLink` on site objects in the | ||
| configuration partition, with the subnet/site objects needed to place a | ||
| computer in a site. The GPC's `gPCWQLFilter` and the referenced WMI filter | ||
| object are captured raw. New pure parsers for SYSVOL: `Registry.pol` | ||
| (binary) and `GptTmpl.inf` (INI). Security filtering needs the GPC's | ||
| security descriptor; if that attribute is not exported, record "filtering | ||
| not read", never "applies to all". | ||
|
|
||
| **Gate:** a fixture `Registry.pol` parses to the same key/value set as an | ||
| independent reader; a link marked disabled is kept and flagged, not dropped. | ||
|
|
||
| ## D-PBL-3 — setting identity | ||
|
|
||
| Load the mapping from its published form (the ADMX-backed CSP definitions | ||
| and Group Policy analytics output) as data. A mapping row records its | ||
| source and whether it is exact or partial. Settings without a mapping are | ||
| shown under their native key with "keine Entsprechung". | ||
|
|
||
| **Gate:** a setting present in both sources joins only through a mapping | ||
| row; removing the row splits it into two rows (disable run red). | ||
|
|
||
| ## D-PBL-4 — assignment resolution | ||
|
|
||
| GPO: OU subtree (dir-sim `subtree`), link order and precedence (local, site, | ||
| domain, OU), enforced links and block inheritance, then security filtering. | ||
|
AdaWorldAPI marked this conversation as resolved.
|
||
| Site links apply only when the computer's site is known; otherwise the | ||
| site-scoped part is "unbekannt". A WMI filter is evaluated only against | ||
| device inventory that answers its query; without it the GPO's assignment is | ||
| "abhängig von WMI-Filter", never "zugewiesen". | ||
| Intune: transitive group members via dir-sim, minus exclusions. When a | ||
| setting is configured by both GPO and Intune on one device, report the | ||
| conflict and the device's declared precedence setting if read; do not pick | ||
| a winner without it. | ||
|
|
||
| **Gate:** precedence fixtures with enforced + blocked links reproduce the | ||
| documented order; a device-targeted assignment with no device population, a | ||
| filtered assignment without device properties, and a WMI-filtered GPO each | ||
| resolve to an explicit unknown state (disable runs red). | ||
|
|
||
| ## D-PBL-5 — observed state | ||
|
|
||
| Intune per-device setting status from its reports. GPO: "nicht zentral | ||
| beobachtbar" unless RSoP exports are ingested per machine. The console's | ||
| drift count is computed only from observed records. | ||
|
|
||
| **Gate:** a GPO-only setting can never display a drift count; a device with | ||
| no status report displays "nicht gemeldet", not "konform". | ||
|
|
||
| ## D-PBL-6 — console projection | ||
|
|
||
| The panel reads D-PBL-1..5. Each cell names its source. Columns with no | ||
| reader (Linux before D-PBL-7) render empty with the reason. | ||
|
|
||
| ## Open points | ||
|
|
||
| - Whether Microsoft's mapping data can be fetched and stored without a | ||
| separate operator decision (not discussed here). | ||
| - Settings expressed only as scripts or custom OMA-URI: kept raw, never | ||
| interpreted. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.