Platform · 3. FeatureCrux
FeatureCrux resolves which runtime behaviours are active for a given tenant and request, and records that decision so the behaviour can be reconstructed afterwards. It is internal. There is no public endpoint, no SDK and no account that reaches it; you will never call it, and nothing you build depends on its shape.
It is documented here for one reason and one warning. The reason: the decision record it produces is part of how "why did the system behave that way, for that tenant, on that day" gets answered. The warning: its catalogue of behaviours is partial and under reconciliation, so it is not today a complete inventory of what is configured to run, see 3.8 before you rely on it for anything.
This chapter is explanation, written at the same altitude as the other private systems: contracts and behaviour, not mechanism.
3.1 What it is, and the problem it solves
A retrieval and ingestion stack accumulates behaviours that have to be switchable, per tenant, per class of request, sometimes for one cohort during one evaluation. Without a control plane that state lives in each service's own environment configuration, where it is visible now and invisible afterwards. You can always read what is set today. You cannot read what was set at the moment a particular request was served, which is the only question that matters once someone is asking about a specific answer the system gave three weeks ago.
FeatureCrux exists to make the second question answerable. It resolves the applicable behaviour set at request time, returns it to the caller, and writes the resolved set down against an identifier the request carries.
Three things it deliberately is not:
- Not a customer-facing configuration API. Tenants do not set their own behaviour; operators do.
- Not a deployment or release system. It does not ship code and does not restart anything. It describes what should be active.
- Not an authority on what the running code does. That distinction is the whole of 3.8, and it is the most important thing on this page.
3.2 Position in the architecture, and its consumers
It sits beside the platform rather than inside any customer-facing request contract. A consumer asks it a question at the start of a unit of work and carries the answer forward.
| Consumer | What it does with FeatureCrux |
|---|---|
| The hosted plane (Crux Engine) | Resolves a behaviour set per request and attaches it to the downstream calls that request produces |
| The retrieval substrate (CoreCrux) | Reads the attached behaviour set off the request. It never calls FeatureCrux itself |
| Server-rendered web surfaces | Resolve once per render, to decide which agent-facing affordances to show |
| Internal evaluation harnesses | Resolve a behaviour set per run, then post outcomes back against the decision they were resolved from |
One property of that arrangement matters more than the list: the substrate never calls the control plane. The resolved set travels with the request. A control-plane outage therefore cannot stall retrieval; it can only mean a request arrives carrying no behaviour set, or a fallback one. That is a deliberate coupling choice, and it is why an internal control plane sits in this architecture at all.
3.3 The lifecycle: resolve, decide, observe
Three steps. The third is what makes it a control plane rather than a configuration file.
- Resolve. A caller presents a tenant and a request class. The service returns the behaviour set that applies, each entry carrying its state and where that state came from, a default, or an explicit per-tenant setting. The response also carries a decision identifier, and an indication of which source the catalogue was read from.
- Decide. The resolved set is recorded against that decision identifier, together with the tenant, the request class, what was applied, what decided it and when. This write is asynchronous; see 3.6.
- Observe. Later, an outcome can be posted against the same decision identifier: a graded result from an evaluation run, operator feedback, or a judged score. Because outcomes are keyed to the decision, a behaviour set can be evaluated against how the requests that used it actually turned out.
The loop closes at step three. A behaviour that was turned on for a cohort can be judged on the outcomes of the decisions that carried it, rather than on an opinion.
3.4 What is recorded
Described by what it captures, not by its storage shape.
| Record | What it captures |
|---|---|
| A behaviour definition | Its identity and kind, its default state, which request classes and content modalities it applies to, a pointer to its runbook, its declared dependencies and incompatibilities, and any measured effect recorded for it |
| A per-tenant setting | The tenant, the behaviour, the state chosen, optional parameters, who set it, why, and an optional expiry that is honoured at read time |
| A decision | The decision identifier, the tenant, the request class, the behaviour set as applied, what decided it, when, and how long resolution took |
| An outcome | Which decision it refers to, what kind of observation it is, the observed value, its source, and when it was observed |
Three properties of that model are worth naming, because each one surprises somebody:
- Declared dependencies and incompatibilities are recorded, not enforced. A behaviour may declare that it needs another, or conflicts with another. Nothing at resolve time acts on the declaration. It is documentation carried in data, and it should be read that way.
- A per-tenant setting wins unconditionally, including for a behaviour whose declared scope would not otherwise have applied to that request. That is deliberate. An operator override is an override.
- Retention is not enforced by the service. Decisions and outcomes accumulate. Nothing prunes them on a schedule today, and any statement that they expire after a fixed window describes an intention rather than an implementation.
3.5 The decision-audit story, and its boundary
This is the capability that earns the chapter. Because the resolved set is written down against an identifier the request carries, reconstructing behaviour is a lookup rather than an archaeology exercise. For a given decision you can recover which behaviours were resolved, what state each was in, whether that state came from a default or from an explicit per-tenant setting, and, where an evaluation ran, how the requests that used it scored.
What that record proves, and what it does not. Stated at the same volume as the capability, because a guarantee without its boundary is marketing.
- It is a record of what the control plane resolved. It is not evidence that the runtime honoured the resolution. Those are the same thing only when the catalogue and the code agree on what a behaviour is called, which today they do not reliably do, 3.8.
- It is not transactional with the response. The write is asynchronous and buffered. Under sustained storage pressure the buffer sheds rather than blocking the request. Treat the decision log as a high-fidelity operational record, not as a ledger that is provably complete.
- It is not a receipt, and must never be quoted as one. Receipts are content-addressed or signed records of retrieval and execution that a third party can verify without access to your data. The decision log is an internal operational record with no such property. Do not collapse the two.
3.6 How it behaves when something is wrong
A control plane is documented by what happens when it is wrong, not by what it does when everything is fine.
| When this happens | What the caller sees | What to watch for |
|---|---|---|
| The configuration store is unreachable | A normal successful response, resolved from a bundled fallback snapshot and tagged with the source it was read from | The snapshot is only as current as its last refresh. An outage therefore resolves a narrower set than intended, with a 200 and no error. The source tag on the response is the only signal, and a consumer that does not read it cannot tell the difference. |
| The per-tenant lookup fails but the catalogue read succeeds | Defaults only | There is no field distinguishing "this tenant has no settings" from "the settings lookup failed". Two different states produce one response. |
| A behaviour is defined without any request-class scope | It never appears in any resolution | Silent. An empty scope means "applies to nothing", not "applies to everything", the opposite of what most people assume when they create one. |
| The decision write fails | Nothing. The response has already been sent | Audit rows are discarded, not retried. This is the failure mode that quietly erodes the record in 3.5. |
| A per-tenant setting is changed | The change is not instantaneous | Resolution is cached; a new state takes effect when the cache window turns over, not on write. A flip that "did not work" was most likely read before the turn. |
| The control plane is entirely down | Depends on the consumer | Retrieval continues, because the substrate never calls the control plane. Consumers that fail open serve their own defaults. Consumers that render an interface from the resolved set render nothing. |
The pattern across those rows is one thing: this plane fails open and quiet. That is the right trade for a component that must never be able to take down retrieval, and it is the wrong shape to rely on for alerting. Anything that needs to know the control plane is degraded has to read the source tag on the response, not wait for an error.
3.7 Auth posture
The authentication surface was hardened in July 2026. Three properties, all shipped:
- Mutations always require a token. Defining a behaviour, changing one, setting or clearing a per-tenant state, triggering an evaluation, regenerating the fallback snapshot, every write path requires a valid signed token. There is no unauthenticated write.
- It fails closed, loudly. Where a deployment is configured to require authentication on the request-time paths but has not been given a signing secret, the service refuses to start. It does not log a warning and serve those paths unauthenticated. That was chosen deliberately over the quieter alternative of failing each request at runtime, because the quieter option leaves a window in which the hot path serves without the authentication it was configured to require.
- Token lifetime is required and capped. A token must carry both an issue time and an expiry, and a token asking for a lifetime beyond the service's maximum is rejected rather than silently truncated. Long-lived tokens for this plane are not obtainable.
Whether the request-time paths require authentication is a per-deployment posture, not a property of the software, and this chapter does not state the posture of any particular deployment.
3.8 What it is not an inventory of
As of 2026-07-27, three statements about the catalogue are true, and they are published here because the alternative is that somebody discovers them while reasoning about a live system.
- The catalogue is partial and under reconciliation. It carries a curated set of behaviours, not every switchable behaviour in the platform. It was assembled at a point in time; the code has moved since.
- A catalogue entry is not linked to the code symbol it governs. There is no field recording that binding, and therefore no check that can fail when the binding breaks.
- Most apparent gaps are naming, not absence. Where the catalogue names a behaviour the code does not appear to have, the usual explanation is that the behaviour is real and the code now calls it something else. The feature exists; the registry knows it by an old name.
The failure mode is precise: a stale catalogue makes the registry's "on" and the runtime's "on" two unlinked booleans. The registry can say a behaviour is enabled for a tenant while the switch that actually gates it in the running code is a differently-named one that nobody set. Nothing detects the disagreement, because nothing in the system knows the two were supposed to be the same thing.
What to read instead. Anyone reasoning about what is actually enabled should treat the deployment's own configuration as the authority, for the daemon, that is 5. Configuration reference, which enumerates every environment variable with its default and links each one to the line of source that reads it. FeatureCrux tells you what was intended for a tenant and what was resolved for a request. It does not tell you what the binary is running.
The gap is known, dated and being closed. The work is a recorded binding between a catalogue entry and the configuration symbol it governs, plus a check that fails when that binding goes dead. Until it lands, the paragraph above stands, and this chapter will say so.
3.9 FeatureCrux is not PlanCrux's capability catalogue
Two unrelated things have been called "the feature registry". They share a word and nothing else, and conflating them has already produced wrong conclusions in internal material.
| FeatureCrux | The capability catalogue | |
|---|---|---|
| What it holds | Runtime state: which behaviours apply to which tenant, the decisions resolved from that, and the outcomes observed against those decisions | Engineering documentation: which capabilities exist across the portfolio, their test and audit coverage, and where the gaps are |
| What it is for | Deciding and recording behaviour at request time | Tracking engineering coverage over time |
| When it changes | When an operator sets a per-tenant state | When an engineer audits a capability |
| Who reads it | Platform services, per request | People, and planning tools |
Neither is a source for the other. They share no data, no schema and no endpoint, and a statement about one is not evidence about the other. Where older internal material says "the feature registry" without qualification, establish which one is meant before acting on it.
3.10 What to conclude
- The decision-audit capability is real and shipped. Resolve, record, observe works end to end. The service is tested, and its authentication was hardened in July 2026 with a fail-closed posture and a capped token lifetime.
- The catalogue's completeness is a known, dated gap. It is partial and unbound to the code it names, and that is being closed. It costs nothing to say so and it would cost a great deal to let someone find out by inference.
- The distinction that matters is between a resolved decision and an observed behaviour. FeatureCrux records the first with high fidelity. Only the runtime's own configuration is evidence of the second.
3.11 Grounding, and what is deliberately absent
FeatureCrux is closed and internal, and this chapter carries no source links: the paths would themselves be the disclosure, and unlike the hosted API there is no request you could make to check them. Everything above is a statement about behaviour, about the shape of what is recorded, or about posture.
Deliberately absent, and staying absent: the names of the individual behaviours the catalogue carries, how many there are, its contents, per-tenant settings, hosts, ports, container names, schema names, and the deploy procedure. The catalogue is a map of what the platform is tuning and where it intends to go next. Publishing it would publish the roadmap. That is exactly the class of thing the boundary excludes, and it is why this chapter describes the shape of what is recorded rather than what is in it.
Next: 4. How they fit together, or back to 0. The platform.

