Skip to main content

Simulated user archetypes

An archetype describes a type of user — accounting, system administration, management, development, sales, a domain controller — through the workflow of their day: a sequence of abstract actions, each with its own temporality, linked to one another. An archetype is always a working day: threats live in the scenario library.

The workflow names no technology. This is deliberate: when the archetype is instantiated on a community, the log generators are picked, and the system knows which event types of each technology realise each action. That crossing is what makes the workflow usable, and the Coverage tab shows it before any instantiation.

The vocabulary of actions​

The catalogue holds 32 actions, drawn from the names actually present in the 470 event types of the corpus. It lives in code (packages/shared-types/src/activity.ts) and not in the database: an action created from the screen would have no event type facing it, and coverage inference only knows these slugs.

FamilyActions
AuthenticationLocal sign-in, Sign-out, Lock / unlock, Connection to a server, Cloud authentication, Second factor, Authentication failure
ProcessesApplication launch, Administration console, Script execution, Scheduled task, Development toolchain
Network and collaborationWeb browsing, Mail, Instant messaging, Video conference, SaaS application usage, VPN connection, File transfer
Name resolutionDNS resolution
Files and documentsDocument opening, Creation or modification, File deletion, Internal sharing, External sharing

Mail and chat are filed under the NETWORK category rather than under one of their own: an action's category only serves the grouping in the interface, the coverage table is what has authority.

Connection to a server is the only action putting two entities into play: it will be skipped if the simulated population holds no server.

The temporality of an action​

Every action carries a window in the day (in minutes since midnight), active days, a probability of happening on a given day, a random jitter, and one of three temporalities:

TemporalityWhat it describesExample
Once per dayOne occurrence drawn inside the windowArrival at the office, 08:00–08:15
RecurringOne occurrence on average every n minutesMail, every 6 min from 08:15 to 18:00
Burstn draws grouped inside the window4 meetings during the day

The jitter is not decorative: without it, a whole population would sign in to the very same second.

The window is read in the population's local time, not in UTC: an archetype does not know where the people playing it live, it is the bench's — or the community's — population that carries the time zone. “08:00” therefore means 08:00 for them.

Chaining​

A transition A → B reads: B only starts after A, and each of its occurrences follows a gesture of A. If A did not happen — its probability draw failed — B is skipped. No connection, no session.

That is what lets a working day be described: no mail before arriving at the office, no evening session without the VPN.

Chaining takes precedence over the window​

The chain is the skeleton of the day; the declared schedule is only a preference. Three rules follow.

The window slides, it does not refuse. If B's schedule has already passed when A happens — B closes at 10:00, A arrives at 20:00 — B's window slides while keeping its declared duration, instead of being skipped. The action does happen, and the trial preview reports it: Shifted actions. The only remaining case for a skip is when there is no day left at all.

Each occurrence of B waits for a gesture of A. A document modification follows an opening, and an opening only unlocks one modification. When A only happens once — arrival at the office — there is nothing left to wait for after the first gesture: B then resumes its own pace, and mail every 8 minutes stays mail every 8 minutes.

Waiting thins out, and that is accepted. Two chained recurrences do not produce the volume their cadences would announce separately: “every 25 min, after an opening that happens every 20 min” produces less than 25 minutes promise, since every due date waits for its trigger. That is the price of correlation — and the counterpart of a day that reads.

The sequence is verified against the emitted instant, jitter included: an action jittered by +40 minutes still comes before those it unlocks.

After the first gesture, or after the last​

An arrow carries a mode, which says which of A's gestures opens B.

ModeWhat it describes
after the first gestureThe default, and the long-standing behaviour: B starts at A's first gesture, and each of its occurrences follows one.
after the last gestureB waits for A to be finished. It then has a single anchor — the last gesture — then resumes its own pace.

The second one serves to close a sequence. A sign-out chained “after the first” to the CRM lands in the middle of the series, and the CRM carries on an hour after the departure: the day closes before its end. “After the last” places it where it makes sense.

The mode is set by picking the arrow: the properties panel describes it and offers the toggle. Without JavaScript, it is set in the Chaining list. An arrow set to “after the last” carries the label on the graph — the others stay bare, so that the only one saying something different stands out.

The graph must remain acyclic. A cycle would make the day unsolvable: no action could ever start. The editor refuses the link before saving, and the backend refuses it too.

Drawing a chain​

Every card carries two dots in the archetype's colour: at the bottom, the departure, at the top, the arrival. You link the bottom dot of one card to the top dot of another — by dragging, or by clicking one then the other. The arrow that appears carries a head: it states the direction, and therefore which of the two actions waits for the other.

To undo a chain, pick its arrow — it thickens — and press Del.

A refused chain does not vanish silently: the reason is shown above the graph, in full screen as well as in full page.

Forks​

A fork is a brick of the graph that picks, for each user and each day, which of the paths that follow it happens. Every arrow leaving it opens a path, and every path you link dilutes the others: two paths, one day in two each; three paths, one day in three. It is what is needed to say “now and then, in the evening, they open the VPN and check their mail”.

A path is everything the fork is the only one to reach: its actions leave together or not at all. That is what distinguishes it from a chance placed on each node: three actions with a one-in-three chance each would give one evening in three without a VPN connection, and the whole sequence would only happen one day in twenty-seven.

  • Rarity is never entered: it is read from the number of outlets. A fork also carries empty outlets, which count in the draw and lead nowhere: one path and two empty outlets make “one day in three”. A fork with a single outlet always keeps it — the editor says so.
  • The fork composes with the action's own chance: the path is taken one day in seven, and on that day an action at 0.5 still has a one-in-two chance.
  • An action that two paths of the fork both reach — a junction — happens after whichever path was taken. An action that another parent also reaches is not removed with the path either: a fork only removes what it alone reaches.
  • A fork is transparent to timing: the chaining that enters it decides when its paths start, and the arrows leaving it carry no mode — it has no gesture of its own.
  • On the graph, a fork is a dashed card with a diamond; every arrow leaving it carries its share — 1/3 —, and each empty outlet shows as a dotted stub below the card.
  • The trial preview reports the draw — taken for 9 of 25 users — even when a path is taken everywhere. Without that, a path falling for part of the population would read as having produced nothing.

Removing a fork contracts the graph: what led to it now leads to each of its paths, which become unconditional. The chain drawn around it stays whole.

Per day or per hour​

A fork has a cadence. Per day, the path is picked once for the whole day. Per hour, a path wins each hour: the fork shares the twenty-four hours between its outlets — with neither overlap nor gap —, and an empty outlet leaves hours with none of them.

This is the shape of an attacker, who does one thing at a time and changes from hour to hour. Rarity would not say it: six campaigns drawn “one day in six” each would give a day with no campaign at all one time in three, and two simultaneous campaigns almost as often. See Attacker background noise.

  • Each hourly fork rotates on its own: two hourly forks of the same day do not change path in step.
  • An action whose window meets none of its path's hours is skipped and named: the reason says which of the two causes applies — no hour won, or hours outside the window.
  • A junction after several paths of an hourly fork waits for a gesture of each of them — they all live the same day, at different hours. The editor warns of it.
  • Placing an action behind a fork moves no timestamp in the rest of the day: the draw lives in its own stream, and the hourly filter applies after placement — it retains, it does not replay.

Where a gesture takes place​

Every action carries a place: at the office, the ordinary case, or off-site — remote work, mobility. This is not a property of the catalogue action: checking your mail happens at the office as well as at home. It is a property of the node, because it is the workflow that says where you are at that point in the day.

What the place changes in the logs:

  • at the office, the user egresses through the public IP of their geographic site — the same for all their colleagues, as behind a real corporate NAT;
  • off-site, they egress through their own (user.desktop_public_ip), which belongs to them alone;
  • the city and the country, however, follow the user in both cases. One technology alone is an exception, and it is the right answer: Zscaler's location reverts to Road Warrior, the product's own term for a roaming workstation.

All of this applies to an outbound gesture. A gesture aimed at a corporate machine — an RDP or SSH session on a server, a Kerberos ticket, access to a share — crosses no NAT: its log is written by the joined machine, which sees its client on the internal network. The place still plays a part there, but between two other addresses: user.desktop_ip at the office, and the personal address as soon as the gesture starts elsewhere.

The place sits on the action and not on the fork, even though the sales rep's remote-work evening follows one. A fork is a rarity, not a place: an archetype working permanently from home would have no fork to hang it on. Nor is it inferred from the graph — “everything downstream of a VPN connection” would be wrong as soon as a VPN is raised from a branch office.

On the graph, an off-site gesture carries an “Off-site” line. No dashed border, no double frame: those belong to forks and to super-archetype calls.

The screen​

/archetypes lists the archetypes; each one opens three tabs.

Workflow​

The graph is drawn on a canvas taking the full width of the screen: one node per action, one edge per chain. It unfolds full screen (Enlarge the graph, Esc to leave) for as long as it takes to organise a busy day.

The action library sits on the canvas, top left: the 32 actions are filed there by category — Authentication, Process, Network, File, DNS, Alert — and only one category is open at a time. Below them, the Structure group holds the Fork brick. The whole panel folds back onto its header when the graph needs the room. Dropping an action selects it: its properties open at once.

Chains are drawn on the graph, by linking cards with the mouse (see Drawing a chain). There is no panel to describe them: reading two dropdowns to say which card follows which other, when both are right there in front of you, was the sleight of hand that had to go.

Below the canvas, the properties panel only sets the selected action: temporality, window, cadence, days, probability, place. Tout voir en tableau renders the whole day, one row per action, and Back to the selection closes it. The two views are never displayed together, but they read the same state as the canvas — they cannot diverge. Picking a fork shows its outlets and the share of each; picking an arrow rather than a card substitutes the chaining's properties, including its mode.

The Forks card lives below the graph, in both modes: there you name a fork, pick its cadence — per day or per hour —, set its empty outlets, and remove it. Its paths, on the other hand, are drawn on the graph like any chain.

Without JavaScript, the canvas does not mount: the library is then displayed in the page flow, with all categories unfolded, and the table becomes the only way to edit — Place column included. The Chaining panel — “After … start …” — reappears below the table: with no graph to work with the mouse, it becomes the only path again, and that is where each arrow's mode is set and a fork's paths are linked. The whole remains fully functional, including the add, remove and chain buttons. The tabs, which are buttons, are doubled by ?onglet=… links.

An action shown in amber in the library is realised by no event type: dropping it into a workflow will produce no log.

Saving reaches the communities that play the archetype within the minute. Assigned to an entity, or a super-archetype that one of those calls: the community's day plan goes stale, and the next tick rebuilds it. Only the minutes not yet sent change — what already left stays as it left — and the counters of the community's “Day of …” card follow. Renaming counts too, since the name labels the gestures; the Description and Colour do not touch the day, and touch no community.

Coverage​

The crossing we asked for: one row per workflow action, one column per selected technology. Each cell gives the number of event types realising the action on that technology, and unfolds onto their list.

  • A filled cell means the technology sees every occurrence of the action: there is no observation ratio, and a ticked technology that realises the action produces a message on every gesture. Of several event types listed, the heaviest one describes the gesture — the others wait for the ambient layer specific to each technology.
  • The gestures that start a process — application launch, scheduled task or service, administration console, development toolchain — are all described by the technology's process-creation log: an agent does not see who launched the binary, it sees a process starting. All selected technologies then name the same executable, the same path and the same process identifier. Script execution is the exception: three technologies carry a dedicated log, which describes the gesture more precisely.
  • A “None” cell is a gap: the action will produce no log on that technology. That is not an error in itself — it is what you need to see before instantiating the archetype.

The technology selection lives in the URL: the crossing is shareable through a link.

Identity​

Name, description and display colour.

Where coverage comes from​

The source corpus carries no notion of action. Coverage is therefore inferred from the name of each event type at import time, on the same principle as the category (inferActionCoverage, in packages/log-engine/src/authoring/activity-coverage.ts): ordered patterns, first match wins, and no action when nothing settles it — an invented action would pass for a fact.

Of the corpus's 470 event types, 529 coverages are inferred and 26 event types stay without an action. None of them is a defect:

  • 13 are the business event types of the three alertHeavy generators (CrowdStrike Falcon, Microsoft Defender XDR, SentinelOne Identity). They are excluded from the per-minute flow by architectural decision: their business coverage must stay empty, otherwise an “accounting” archetype would make them emit continuously.
  • 13 describe the machine's own operation — agent-log, endpoint-stats, health-check, scan-initiated, filtering-platform-listen, Cortex XDR's rpc. They translate no user gesture and will never have an abstract equivalent.

The trap of the name: an audit log is not a session​

Inference only reads a name, and two very different gestures sometimes carry almost the same one. Netskope's audit-login-success event type is the example: it carries “login-success”, but it is not a workstation sign-in — it is the tenant audit log, recording that an administrator signed in to the Netskope console ("type": "admin_audit_logs", "user_category": "admin"). Filed under “Local sign-in”, it made an administration console open on every simulated user's arrival at the office.

It therefore belongs to Administration console, like the other gestures of that console — sign-out, administrator account modification, inline policy deletion, password change. Those four do not exist in the source corpus: they are written in the repository (packages/database/prisma/seed/netskope-admin.ts) and seeded next to the corpus, like the catalogue of web destinations.

The lesson goes beyond Netskope: when an inference pattern is wrong, the fix belongs in the rule — and its per-technology map, frozen as a snapshot, then shows what it moved elsewhere.

Correcting a coverage​

The Actions tab of an event type (/generators/:id/event-types/:id) ticks the actions it realises. Saving marks the coverage as corrected (MANUAL), and the import no longer recomputes it: a correction survives the next pnpm db:seed. Without that distinction, editing would make no sense — everything would be undone at the next import.

Putting an archetype to the test​

The Coverage tab says what could realise each action; it does not say what the day looks like. That is the role of test benches: “Try this archetype” opens a bench preset on it, where you pick a population, technologies and their intake keys, then see the day before actually sending it.

The server a gesture joins​

Some gestures put two entities into play: the user acting, and the server they join. The catalogue says so, and it also says with what requirement.

ActionRequirementDefault role
Connection to a serverWithout a server, the action is skippednone — the archetype decides
Local sign-inOptionaldomain controller
DNS resolutionOptionalDNS server
Public website visitOptionalweb server

The last three are surprising, and that is the point: the log describing those gestures is not emitted by the workstation. The event type Windows keeps for a sign-in is 4768, a Kerberos ticket request that the domain controller logs. The BIND line of a resolution is written by the resolver. The W3C line of a visit is written by the web server. Without a peer, those logs could name none of those machines.

The targeted role​

Every workflow node can target a precise role — that is the “Server reached” column of the table, and the row of the same name in the properties panel. Left on “catalogue role”, the node takes the one the action proposes; that is what keeps an archetype written before this setting meaningful.

The role is inferred from the name of each machine at import: SRV-DC-01 is a domain controller, ZION-DNS-01 a DNS server, SRV-JUMP-01 a jump host. This is not a convention being added — it is already how the source project's BIND generator picked its resolver. A machine whose name announces no role receives none: thirteen of the 110 servers in the demonstration populations are in that case, and the datasets screen lets you fix it.

When the role does not exist in the population​

Three demonstration populations out of six have no domain controller. The Directory administration archetype still plays there: the gesture falls back on the other machines rather than being skipped. But it falls back while saying so — the preview's “Servers reached by default” card names the node, the missing role, and the number of machines it falls back on. Refusing would make the profile unplayable on half the populations; staying silent would pass an RDP server off as a domain controller.

The demonstration archetypes​

pnpm db:seed creates the demonstration archetypes if they are absent: the super-archetype System noise, the business days Accounting, IT — system administration, Management, Development, Sales, Support and remote assistance, Directory administration, DNS and network operations and Office work and shares, the Public website visitor, and one archetype per server role on a shared Windows server base. They are never rewritten: a demonstration archetype edited from the interface survives the next seed, just like a template edited by hand.

The server archetypes​

Each of the sixteen server roles is claimed by exactly one archetype, so every machine whose name announces a role plays a day. Three of them play journals of their own: the domain controller (directory replication), the DNS server (zone transfers and maintenance, recursive-resolution failures, DNSSEC, RPZ reloads) and the backup server (the nightly job, one machine after the other, each followed by its restore point).

The thirteen others — remote desktop, file, print, web, database, time… — have no journal of their own in the source corpus: no W32Time, no PrintService, no TerminalServices, no SQL Server log. Their archetype only plays the Windows server base, which every server archetype calls: the antivirus health report, once an hour, and the service of the role opening its listening port. That last log is where the role shows — TermService on 3389, SMB on 445, http.sys on 443, SQL Server on 1433. A role that does not say which service it runs (application, monitoring, time…) names the RPC endpoint mapper on 135, which listens on every Windows server. Each of these archetypes says so in its description, rather than promising a print server where only a health report leaves.

Sales illustrates the three mechanisms of this page. Its sign-out waits for the last gesture of its CRM and its mail — otherwise it would land at 5 pm while the CRM runs until 6 pm. Its Evening VPN fork — one path and two empty outlets, one day in three — opens onto remote access, evening mail and evening CRM: the three leave together, or none leaves. And those three gestures are marked off-site: they egress through the sales rep's personal address, while their day egresses through the office's — within the same simulated day, for the same user.