Skip to Content
Data · Input formats

The discovery interview, told until something shows it.

The discovery interview is the first thing a customer’s team says about its organisation. It is recorded, transcribed and saved as one JSONJSONJavaScript Object Notation: a text format for data, using named fields, lists and values. Configuration files and service messages use it. file. NovusLens uses a language modelLanguage modelSoftware that produces text from instructions and supplied context. NovusLens checks its answers against the records retrieved for the question. to read that transcript and propose a structure of 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. (the units of the organisation) and the dependenciesDependencyA link where one unit needs something from another. A dependency is not a reporting line: it shows where work relies on something else. between them. What the interview says is testimony, so everything it produces lands at the toldToldEvidence that somebody stated the value. It is the weakest level, and it is always attributed to its speaker. rungRungOne of three levels of support for a recorded value: told, shown or measured. The level appears beside the value., the first rung of the evidence ladderEvidence ladderThe three levels of support a record can have, in order: told, shown and measured.. It stays there until a document or a measurement backs it.

An interview is testimony: it fills what nothing else backs, and never overwrites a cell a document or a measurement stands behind.

What it carries

The transcript carries the organisation’s short id, an optional display name and description, and an ordered list of turns. Each turn names a speaker and records what they said. The interview reader reads turns in order and extracts cells, owners, authorityAuthorityWhat a team or agent is allowed to decide or do. For an agent, this comes from a named person or system that grants permission. and dependencies. It records disagreements as disputes, keeping the original account.

Docker commands

For the Compose installation, run commands from the checkout that holds .novuslens.env and compose.yml. Prepare the input described below, then copy it from the host into the running reasoning containerContainerA running program with its own packaged software and isolated environment, managed by Docker on the host.:

./lens exec -- sh -c 'cat > /tmp/interview.json' < interview.json ./lens exec -- python -m conway_mesh.build --transcript /tmp/interview.json

This command keeps input interactive so you can review the proposal and answer the confirmation prompt. Configure a model server in the installer before importing an interview.

Give host paths for automatically uploaded inputs; use /tmp/ paths for files already inside the container. Follow the complete Operations manual for accounts, configuration and command access.

Before you start

You need a saved transcript file in the JSON shape below, and an installation that is running. The interview runs through a local model. The interview reader calls a model endpointEndpointA particular address on a service that accepts a defined kind of request., which defaults to http://localhost:11434/v1/chat/completions, and the model name defaults to gpt-oss:20b. The code reads CONWAY_LLM_ENDPOINT for the endpoint, and CONWAY_BUILD_MODEL (or the older CONWAY_LLM_MODEL) for the model name. This applies to both import routes below, because both run the same interview reader.

The command also needs the meshMeshA set of connected Mycelium services that exchange updates and keep the NovusLens log. node to be reachable. It waits for the node to report healthy before it writes. The node address defaults to 127.0.0.1 on port 8400, from NOVUSLENS_MESH_HTTP_ADDR and NOVUSLENS_MESH_HTTP_BASE.

Fields

FieldRequiredWhat it is
orgYesThe organisation’s short id, lower case, no spaces.
turnsYesA list of two-element lists, [speaker, utterance]. The speaker is a role or a name. The utterance is the transcribed text.
org_nameNoThe display name.
descriptionNoOne sentence about the organisation.

The command reads turns as pairs in order. Each pair is unpacked as a speaker and an utterance. The guide and the connectorConnectorSoftware that reads records from a source system, such as an incident tool. A customer-written file connects those records to teams or services in NovusLens. test both quote this shape, so a page that differs from it would fail the test.

Worked example (illustrative)

The organisation below is an example. It is not a real customer.

{ "org": "harbour", "org_name": "Harbour Logistics", "description": "A freight forwarder: bookings, customs, warehousing.", "turns": [ ["COO", "Three areas matter: bookings, customs and warehousing. Customs holds change authority for anything filed with the border agency."], ["COO", "Warehousing depends on the bookings feed; when it is late the whole day slips."] ] }

How to send it

There are two routes. Use the browser for an organisation that already has a chart, because it records disagreements with the chart. Use the command for a first build against an empty organisation. On a customer installation, create a sign-in credential with the account command after the build.

In the browser

Open /import and choose the transcript file. The page recognises an interview by its shape: a top-level turns list. The browser then proposes the structure. It posts to /api/reasoning/operations/import-org with kind set to transcript, and polls /api/reasoning/operations/import-progress while the local model works through the turns. This can take several minutes, and the page says so. Nothing is committed yet. The proposal is shown for review, and a person confirms it, which posts to /api/reasoning/operations/commit-org.

Against an empty organisation the transcript proposes the structure. Against an organisation that already has an org chart, the import starts from that chart. It adds notes and records disagreements beside the existing chart, keeping the original account. A board viewer is refused, because the board may read these records but cannot change them.

From the command line

From the installation directory:

./lens exec -- sh -c 'cat > /tmp/interview.json' < interview.json ./lens exec -- python -m conway_mesh.build --transcript /tmp/interview.json

The command prints each turn and the paraphrase the interview reader recorded for it, then prints the proposed structure. It then asks commit this structure to the mesh? [y/N]. Only y commits. Any other answer prints not committed. and exits with status 1.

For a run with no prompt, add --yes. The module describes that option as the way the acceptance run and CIContinuous integrationAutomated checks run when code changes, usually including building the code and running tests. auto-confirm the proposal. The command above omits it and waits for your answer.

The command also takes --org, which defaults to the org field in the file, and --host and --port, which default to the mesh node address.

What you will see

When the command commits, it prints a line such as committed N structural commit(s) to conway/commit/<org>. If the org name or description is present, the org name is recorded on the log as an org-meta commit. The command then creates the organisation’s executive account, cxo-<org>, so the twinTwinNovusLens’s model of one organisation, built from records about its teams, services and how they rely on one another. It is only as current as those records. opens in the browser. A failure to create the account prints a note and does not undo the commit. Last, it prints a count of cells, edges, unowned findingsFindingA difference in the records that needs a decision. It includes its sources and can describe a slow handoff, disputed fact or missing owner. and requests for missing documents.

The mapMapThe view of teams, services and their dependencies for the selected part of the organisation. Details appear beside the map. shows the result after the projectionProjectionThe regular pass that brings the read model up to date with the canonical log. It runs every 30 seconds by default. service’s next pass, which the guide puts at about 30 seconds by default.

In the browser, you see the proposal before anything is written. You can see each cell, the edges, the recorded disagreements and the items needing review, and then confirm or discard.

What a second interview does

The guide states these rules. The code writes each cell and dependency through the interview reader’s commit step, and the materialiserMaterialiserThe component that reads recorded changes in order and updates the database. It records its place so it can continue after a restart. decides the outcome. Each row below is the guide’s account. Not every row has been traced line by line in the code.

SituationWhat happens
Stable identityA cell is identified by the interview name, converted to lower case with hyphens. It joins an existing cell when their name words match. There is no version number.
The same transcript twiceEvery cell and dependency is written again at told with the same values. Findings re-open by id. Nothing duplicates.
A cell a document already backsThe document’s label, parent and owners stand: told never overwrites shown. If the interview’s account differs, a provenance-conflict finding opens.
A changed value on a told-only cellThe latest interview wins.
A renamed cellA new name with no shared name words is a new cell; the old one stays. A partial name match joins the old cell or opens a possible-alias finding.
A cell or dependency the second transcript omitsUntouched. An interview cannot say “this list is complete”.
An interview against an existing organisationIn the browser, the import fills empty slots and records differences as contested-structure findings instead of editing the existing chart. The command shown above does not do this: it writes plain told values and relies on the materialiser to preserve higher-rung values. Use the browser import to record a disagreement with a chart.
A wrong answerNo correction route for the transcript itself. Resolve the findings it raised, then re-run a corrected transcript; told-only fields follow it.
When visibleAfter the projection service’s next pass.

Refusals and failures

  • Browser, unrecognised file. A file needs units, turns or cells at the top level. Otherwise, the browser refuses it before upload and lists the accepted shapes.
  • Browser, no organisation id. A transcript with no org in the file, and none given in the request, is refused with no org name — give one, or put it in the transcript. The browser converts the id to lower case with hyphens. The command uses the id as written.
  • Browser, invalid content. A value the parser rejects returns a 400 with the reason in the response.
  • Browser, board viewer. Refused: the board reads these records and cannot change them.
  • Command, malformed file. The command reads doc["org"] and doc["turns"] directly. A missing key stops the command with a Python error. It does not print a named refusal, which the guide’s general claim does not match.
  • Command, not confirmed. Without --yes and without y, nothing is committed and the command exits with status 1.
  • Command, no local model. The turns cannot be read without the model endpoint, so the command cannot build a proposal.
Last updated