DocsWhat was it meant to doThe team graph

The team graph

The graph is what Memnox knows. Everything else, the review queue, the reports, the incident that opens on its own, is a view over it.

It is deliberately small. A graph that models everything models nothing, so Memnox holds six kinds of node and six kinds of tie, and each one earns its place by being something a decision might depend on.

A decision in the middle, the five other node kinds around it, and one tie lighting up at a time. Every node also carries the URL it came from, which is the edge you follow when you disagree with what Memnox believes.

The nodes

Kind

decision

Something the team decided, now binding

person

A human, and every account known to be theirs

system

A service, repository, path or environment a decision constrains

agent

An AI agent registered against the runtime

incident

Something that went wrong, or nearly did

source_event

The Slack thread, pull request or meeting note behind a node

Every node carries a sourceRef, the URL it came from. A node with nowhere to point back to is not stored. There is no unevidenced path into the graph, and an ingestion that cannot compose a permalink is rejected at the normalizer rather than stored with a blank field.

The ties

Relation

affects

This decision constrains that system or path

owns

This person owns that decision

caused_by

This incident was caused by that agent

touched

This incident reached that system

supersedes

This decision replaces an earlier one

evidenced_by

This decision was extracted from that source event

supersedes is the one people underestimate. A team does not delete decisions; it changes its mind. Keeping the old node and pointing the new one at it is what lets you answer "when did we stop doing it the other way, and who decided?", which is the question that actually gets asked.

Reading it

There is no screen that draws this and no route that walks it, deliberately. A graph you browse is a graph you get lost in, and every question worth asking of one has a better answer as a question. Four of them are answered directly, each from a materialized answer rather than a walk:

What does the company state about this? The facts in force, with their provenance and the version chain behind each. Only a verified fact decides anything, and nothing is ever edited: changing one writes a new version and links both ways, so "what was our policy in March" stays answerable.

Why do we do it this way? Every fact carries the evidence it was drawn from, and every edge carries the events that assert it — the column is NOT NULL and an uncited edge is dropped rather than stored. Follow the link and read the original thread. Nobody has to remember.

What can reach this? Every agent that can effectively touch a resource, and the path by which it can, each hop of which was individually permitted. This is the blast radius, and it is the question the graph exists for.

Why was this action decided that way? The verdict, the rule, the rule set, the conditions the decision recorded, and the evidence linked to it — with a count of whatever your clearance did not admit. See working out who caused it.

Scope

A graph is built for a memory, but it may span more than one. A workspace that covers a frontend and a backend in separate memories produces one graph across both, because a decision about the product does not stop at a repository boundary.

The graph records both the memory you asked about and every memory it was actually built from, so a graph that reached wider than you expected says so rather than looking like one memory's answer.

Three scopes nest, and everything is filed under them: an organization is the billing and identity boundary, a workspace is a part of the business the console groups work under, and a memory is a body of context that answers as one. A workspace holds one memory or several, which is why the frontend and the backend above still produce a single graph.

Two more words are worth pinning down, because both read as a scope and neither is one. A team is a named group of people inside a single workspace: the workspace is the work, the team is who does it, and putting somebody on a team is what grants them the workspace. And the project: line in a policy file names the runtime's own governance scope, which repositories share by declaring the same name; it is what a repository belongs to rather than the console record above it.

People are resolved, never assumed

A person node is one human with several accounts attached, a Slack member id, a GitHub login, a Jira account. Email is the only evidence strong enough to merge on, and everything else is a candidate until it matches one.

This matters far more than it looks. Author trust at ingestion is a lookup against these people: an event whose author resolves to a known person in the workspace is trusted, and an unrecognised or absent author is tainted. Getting identity wrong therefore does not produce a cosmetic bug, it produces a wrong trust decision.

See Access and identity.

Node ids are stable

A node id is kind:normalized-key, so decision:no-pii-in-logs. The same decision keeps the same id across rebuilds, which is what makes a link to it worth pasting into a ticket.