Skip to content

The action register index

When a team call warns you, or a ticker wakes a worker, the message carries a short code (task.finish.open-children, tick.coordinator-tick). Behind each code is a role task: the procedure a worker follows when that code fires. The action register index is the list that answers "which code sends work to which task?" for a whole App, in one place. Read it when a worker was sent to the wrong procedure, when a code says nothing is mapped, or before you change a role and want to know which codes land on it.

To look at it, see Read the action register index. This page explains what you are looking at. The warning side of the register is in Team task warnings.

One row per code

Each row has a code, a state, and where it came from:

  • the task the code resolves to, when there is one;
  • the entry that names the task (a register:<code> node);
  • the Agent that defines that entry, so you can see an override.

What a row shows depends on its state. A MAPPED row has all three. An UNRESOLVED row keeps the entry and the Agent that defines it, and shows the location it could not find a task at, but has no task. An UNMAPPED row has none of the three: the server returns them empty, so the portal leaves the cell blank and the CLI shows -.

Rows come back in code order and the list is paged.

How a code finds its task

Two lookups, one after the other:

  1. Find the entry. The App's Team Agent holds the register in its own system memory. The entry for a code is the nearest register:<code> node on the Team Agent's chain: its own memory first, then its base Agent's, and so on. A child Agent's entry hides its base's. The App's install memory is never searched, so an App cannot override an entry; it customises by installing a Team Agent that extends the shipped one.
  2. Find the task. The entry names a task by its location. That location is resolved through the chain of the asking Agent: its own system memory first, then its base Agent's, up to the base of all Agents. The nearest task at that location is the answer. A coder and a reviewer asking about the same code can reach their own role's procedure, because each resolves it through their own chain.

Nothing is stored. The index is computed each time you read it, so a new entry or override counts the moment it is written.

Who is asking

The task depends on the asking Agent, so every read has one.

  • You can name the Agent. Any caller may name an Agent that is installed in the App, or the Agent of a worker cast into it.
  • If you name none, the server uses your own Agent: the worker session or run you are acting as. A person with no Agent has to name one.
  • An Agent that is not usable for this App (it does not exist, you cannot read it, or it is outside the App) is refused with the same answer in every case, so the refusal never tells you which of those it was.

The read uses your own access throughout. You never see a node you could not read yourself.

The three states

State What it means What to do
MAPPED The entry is sound and the asking Agent's chain has a runnable task at the location. The row names that task. Nothing.
UNRESOLVED There is an entry and it names a location, but either the asking Agent's chain has no task at that location, or the nearest node there is not runnable. A task farther along the chain is never used instead. Add the task at that location on the asking Agent (or a base it extends), or make the nearest node runnable. Whoever manages that Agent does this.
UNMAPPED The nearest entry for the code is malformed: it names no task location. A farther entry for the same code does not replace it. Fix the entry in the Agent that defines it. The index does not say which Agent that is: an UNMAPPED row has no defined by value. Whoever manages the App's Team Agent looks through the Team Agent's chain (its own memory, then its base Agents') for the malformed register:<code> entry. The asking Agent's chain holds tasks, not the register.

"Nearest wins, nothing falls back" is the common thread. It is deliberate: a silent fallback to a farther entry or task would send a worker to a procedure nobody chose.

Why an index can be empty

An empty page does not mean the register is empty. Some reasons are ordinary:

  • the Team Agent's chain has no entries;
  • a code or task filter matched nothing;
  • the offset is past the end of the list.

Others are hidden on purpose. You get the same empty page when:

  • the App has no Team Agent, or has more than one (the platform never guesses which to use);
  • you cannot read every system memory on the Team Agent's chain and on the asking Agent's chain.

The last one is all-or-nothing by design. Leaving out only the rows you cannot see would let a readable base entry sit beside a missing one and reveal that a nearer node exists. So the index never says which reason applies, and an empty page tells you only that nothing was shown to you. If you expected rows, check that the App has exactly one Team Agent and that you can read the Agents on both chains, but do not expect the page to diagnose it.

What it does not do

The index is read-only. It does not run a task, write an entry, or assign anyone. Writing register entries is a separate job for whoever manages the Team Agent.