Skip to Content
ArchitectureProjection and read modelThe conway_graph command line
Architecture · Read modelRead modelThe database tables used by the map, Ask and Find. NovusLens rebuilds these tables from its history of recorded changes.

The conway_graph command line, and what each step changes.

Run Python commands inside the configured reasoning containerContainerA running program with its own packaged software and isolated environment, managed by Docker on the host., as in the Docker demo, and use its private meshMeshA set of connected Mycelium services that exchange updates and keep the NovusLens log. addresses.

The read model is the set of PostgresPostgresThe database software that stores the tables read by the NovusLens screens, along with document bodies, access records and protected personnel records. tables that the web application and the reasoning service query. The conway_graph commands migrate, rebuild and check those tables. They also manage viewer accounts and load the in-product GuideGuideThe help pages inside NovusLens. They explain the pages, input formats and tasks in the version you use. They are product instructions, not evidence about the organisation.. The forget-org command also erases an organisation when a customer asks for that. Several commands change or delete data, so read each section before you run it.

Left to right on the top row is the rebuild path. A heavy outline marks a command that deletes data.

What you will achieve

Use this page to choose a command, check whether it changes or deletes data, and recognise its successful output. You will also know how to run the related modules that share the same database and mesh address.

Before you start

  • A database. Every subcommand needs a database. migrate can start with an empty one. The command reads DATABASE_URL from the environment. When it is not set, a development run falls back to a local development database on 127.0.0.1 port 5433. The customer profileDeployment profileA setting that selects customer or development behaviour. Customer mode refuses development credentials and uses the signed-in session as the identity. has no such fallback. There, DATABASE_URL must be set, and the command stops with a configuration error if it is not.
  • The schemaSchemaThe declared structure of data: which fields or tables exist and which values they accept.. Run migrate before anything else on a new database. Every other subcommand checks the schema first and stops if a migrationMigrationAn ordered change to a database's tables or rules. Applied migration files are recorded so the same file is not run again. is pending.
  • A mesh node, for some commands. materialise (and materialise --full), requeue, and the two analysis modules described below read the mesh log from a running node. They take --host and --port. For materialise, requeue and misalignment the defaults are 127.0.0.1 and 8400; keyperson defaults to the installation’s configured mesh address. The commands engine, retry, show, create-viewer, update-viewer, viewer, guide, finding-scope and forget-org do not contact the mesh.
  • Run from the installation directory. Use ./lens graph for a running Compose installation.

The commands

Every subcommand is listed below. Flags marked required have no default. The defaults are the values the code uses when the flag is omitted.

CommandFlags (default)What it does
migratenoneApplies each SQLSQLStructured Query Language: the language used to read and change records in a database. file in migrations/ that is not yet recorded in schema_migrations, in filename order. It is the only command that runs before the schema check, so it works on an empty database.
resetnoneEmpties the derived read-model tables with one TRUNCATE. It does not touch the mesh log. See the warning below.
materialise--org (required), --host (127.0.0.1), --port (8400), --full (off)Reads the organisation’s commits newer than its cursorCursorA saved position in a sequence of records. A program uses it to continue from where it stopped. from the mesh log and applies each one to Postgres. --full rescans the whole log and applies only the entries that the applied-event ledger lacks. This is the recovery for late-arriving entries. The command refuses an organisation that has been forgotten.
engine--org (required)Computes critical path lengthCPLCritical path length. The total coordination weight of the longest chain of dependencies in the model. NovusLens reports it as index points, not elapsed time. (CPL) for both layers. Prints told, shown and measured evidence counts, and records a history point. It takes no mesh address.
requeue--org (required), --hlc (required, integer), --host (127.0.0.1), --port (8400)Re-applies one quarantinedQuarantineA holding area for a log entry that could not be applied. The entry keeps its error and waits for a retry or an operator. entry, identified by its hlc value. The entry is read back from the mesh log, not from the quarantine copy. Its findingFindingA difference in the records that needs a decision. It includes its sources and can describe a slow handoff, disputed fact or missing owner. is then marked resolved.
retry--org (required)Re-attempts the organisation’s quarantined entries that are due, and returns the count recovered. An entry whose attempts have reached six (MAX_RETRY_ATTEMPTS) is left for requeue.
show--org (required), --viewer (required)Prints the organisation’s cellsCellA box on the map that stands for a team, service, supplier or AI agent. It is a unit you can inspect, not necessarily a department or a person. and CPL rows, as JSONJSONJavaScript Object Notation: a text format for data, using named fields, lists and values. Configuration files and service messages use it. with --json. It writes one query_audit row that records the viewer and the query show:<org>.
viewer--viewer (required), --role (required; one of cxo, bu-owner, infra, operator, board), --org (required; * for the operator role), --scope-cell (none), --passphrase (none)Creates or updates an actor in actor_map. A passphrase is stored only as a pbkdf2_sha256 hashHashA fixed-length fingerprint calculated from content. Comparing fingerprints helps detect changes and match records.. Omitting --passphrase leaves an existing credential unchanged. --scope-cell names the subtreeSubtreeOne unit and every unit nested beneath it in the organisation's hierarchy. root for a bu-owner.
guide load--path (config/guide.json at the repository root)Loads the release’s Guide pages. The whole set is replaced, so a page the release no longer carries is removed.
guide statusnone (--path is accepted but not used)Prints the number of Guide pages, the release and when they were loaded.
forget-org--org (required), --reason (required), --by (operator), --yes (off; must be given), --allow-reuse (off)Erases one organisation from the read model and the Postgres-primary stores, and marks it forgotten. The mesh log keeps its commits. See the warning below.
finding-scope--org (required)Read-only. Counts the organisation’s findings by scopeScopeThe work, data, activity or access that a rule, statement or calculation covers. For access, it names the records an account can see. For team measures, “Own operations” covers the selected unit. “Including descendants” adds the units beneath it. class, and lists the findings that have no declared scope so that they can be repaired. --json prints the result as JSON.

migrate is the first step on a new installation. The init service also runs it first. To rebuild from the log, run reset, then materialise, then engine. The ops script uses this order for meridian, the fictional Meridian GridMeridian GridThe fictional demonstration organisation used by the demonstration walk and its sample data. Nothing about Meridian Grid describes a real company. organisation.

Run the commands

On an installed host, run the commands through ./lens rather than from a developer shell:

./lens graph create-viewer --help

./lens graph <subcommand> and ./lens connectors <subcommand> run in the reasoning service with docker compose exec. create-viewer, update-viewer and keyperson are ./lens graph subcommands. ./lens exec -- <command> runs any other command in a running service.

Two cases have their own route:

  • The init service applies the migrations and then loads the Guide before the other services start.
  • ./lens forget-org <org> --reason '<why>' --yes runs forget-org in a running reasoning or projector service.

The other modules and the projection worker

Three other modules use the same database and mesh address. They are not subcommands of conway_graph.

  • ./lens graph keyperson --org <org> surfaces key-person riskKey-person riskA finding about a team on the measured critical path with one to four people represented in the records. It never names those people. findings; it is also python -m conway_graph.keyperson. It takes --host and --port, whose defaults come from NOVUSLENS_MESH_HTTP_ADDR and NOVUSLENS_MESH_HTTP_BASE (mesh-0 and 8400 in the installation), else 127.0.0.1 and 8400. It waits for the mesh node to answer before it analyses the organisation. The finding is an alert for a person to review, not advice. The identities stay sealed.
  • ./lens exec -- python -m conway_graph.misalignment --org <org> surfaces team and domain boundary misalignments. It takes the same --host and --port, with the same mesh wait. The findings are evidence for people to resolve, not a verdict.
  • ./lens exec -- python -m conway_reasoning.project runs the projectionProjectionThe regular pass that brings the read model up to date with the canonical log. It runs every 30 seconds by default. loop. --interval defaults to 30 seconds; values below 5 are refused. --org selects one organisation, otherwise all are processed. --once runs one pass and exits. Mesh defaults are --mesh-host 127.0.0.1 and --mesh-port 8400. With --once, it exits with status 1 if the database is unavailable. Without it, the loop retries with a back-offBackoffA delay before retrying a failed operation. The delay usually grows after repeated failures to avoid making an outage worse.. The Compose service projector starts it. The projection page describes what each pass does.

What you will see

Each command prints a short line on success. That is the output of --plain. The default, --rich, prints the same line in colour on a terminal. It can add detail and a next: command. --json prints one document instead: ok, command and the fields of the result. A refusal exits 1 and prints its message on standard error. Under --json, a refusal is a document with ok: false and error. --wizard asks for each flag in turn and needs a terminal. It asks on standard error, so standard output keeps only the result.

CommandSuccessful output
migrateapplied: <names>, or applied: nothing — up to date
resetread-model wiped (rebuild with: materialise + engine)
materialiseapplied <n> commit(s) from the mesh log
requeuerequeued hlc=<n> (<kind>) for <org> — applied
retryrecovered <n> quarantined entr<y or ies> for <org>
engineOne CPL line per layer with a critical pathCritical pathThe dependency chain with the greatest total coordination weight in the map. It identifies a structural constraint. It does not state elapsed time.. A fidelity: line gives told, shown and measured counts, plus excluded score slots.
show<org>: <n> cell(s), a line per CPL layer and a table of cells; --json gives cells and cpl keys
viewerviewer '<handle>': role=<role> org=<org> — credential set or — credential unchanged
guide loadguide: <n> page(s) loaded for release <release> (<n> stale removed)
guide statusguide: <n> page(s), release <release>, loaded <time>
forget-orgforgot '<org>': <table> <n>, …, then a line listing what still remains
finding-scopethe counts by class, the findings that need repair and a note; --json gives by_class, needs_repair and note keys

The show command returns the cells and CPL rows for the organisation. The --viewer is recorded in query_audit, but the command does not filter its output by the viewer’s role or scope.

When something goes wrong

  • The database is not running. The command stops with a message that says nothing is listening on the port and gives the command to start the database. On the colima runtimeRuntimeThe software that runs a model or agent. A model runtime answers model requests; an agent runtime carries out the customer's agent actions., the message gives a pg_isready check to run inside the runtime.
  • The database does not answer. The command stops with a message that says the connection timed out. This is usually the port-forward between the host and the runtime, not the database. The message gives a check to tell the two apart.
  • DATABASE_URL is not set in the customer profile. The command raises a RuntimeError. Run the command with ./lens graph or ./lens exec --, which run inside a service that sets it.
  • Migrations are pending. Every subcommand except migrate stops with a RuntimeError that names the pending migrations and the migrate command. Run migrate, then retry.
  • materialise on a forgotten organisation. The command stops with a message that the organisation is marked forgotten and nothing rebuilds it from the log. A customer’s erasure is final.
  • forget-org without --yes. The command stops and asks you to re-run with --yes. Nothing is deleted.
  • forget-org with a blank reason. The reason is required. A blank one raises a ValueError and nothing is deleted.
  • requeue with an unknown hlc. The command raises a LookupError when there is no quarantined entry at that hlc, and when the log no longer holds that entry.
  • The mesh node is not answering. materialise, requeue, keyperson and misalignment wait up to 30 seconds for the node to report healthy, then fail. Check that the node is running on the --host and --port you gave.

Read the projection page for how the rebuild works, and the schema page for the tables that reset and forget-org touch.

Last updated