---
title: `nexyron.feature_register`
url: https://nexyron.tech/docs/cypher/procedures/abstraction-platform/registry/nexyron-feature-register
description: nexyron.feature register registers or replaces one feature definition.
---

# `nexyron.feature_register`

## Generic Description

`nexyron.feature_register` registers or replaces one feature definition.

```cypher
CALL nexyron.procedures()
YIELD name, description, parameters, output_columns
WHERE name = 'nexyron.feature_register'
RETURN name, description, parameters, output_columns
```

Abstraction-platform registry procedures create, list, read, and inspect named contracts such as abstractions, features, datasets, snapshots, models, policies, interventions, scenarios, and split policies.

## Consumer-Level Explanation

This procedure is part of the abstraction catalog contract layer. Use it when you want to define a named feature calculation that other runtime procedures can execute for abstraction subjects.

### Parameters

-   `name`: Feature name Required.
-   `abstraction`: Owning abstraction name. Required.
-   `description`: Optional human-readable feature intent.
-   `query`: Required stored single-subject Cypher. It must return `subject_id` and `value`.
-   `output_type`: Optional value type. Use `NUMBER`, `TEXT`, or `BOOLEAN`.
-   `feature_role`: Optional ML role for the feature. Use `predictor` for ordinary input features, `target` for the supervised outcome or label to predict, and `clustering_input` for future unsupervised segmentation inputs. Defaults to `predictor`.
-   `cascade_refresh`: When true, immediately refresh dependent materialized snapshots and datasets after replacing this feature Optional.

### Output Columns

-   `name`
-   `abstraction`
-   `subject_type`
-   `entity_label`
-   `grain`
-   `output_type`
-   `as_of_mode`
-   `refresh_mode`
-   `lookback_ms`
-   `materialized`
-   `version`
-   `status`
-   `dependencies`
-   `tags`
-   `query`
-   `feature_role`
-   `description`

## Example Contract Prerequisite

The executable Cypher blocks on this page query `nexyron.procedures()` so they work in an empty database and stay synchronized with the live procedure registry. A direct `CALL nexyron.feature_register(...)` requires the named abstraction contracts, artifacts, features, snapshots, datasets, models, or policies referenced by that call to exist first; otherwise the runtime correctly fails with an unknown-contract error rather than inventing state.

## Conceptual Explanation

The important thing about `nexyron.feature_register` is that a feature query is now best modeled as a single-subject runtime contract. The owning abstraction defines the full virtual subject set. The feature query accepts one subject from that set through `$subject_id`, computes one parameter or statistic for that subject, and returns `subject_id` and `value`.

Observed-data feature contracts are generated by the post-ingest Rust abstraction generator. Knowledge extraction can add abstraction knowledge, but it does not author observed-data feature contracts.

Feature definitions also carry an ML role. Most features are `predictor` inputs. A `target` feature is the supervised outcome or label that downstream model training should predict for the owning abstraction. Generated target features must be target-shaped: `BOOLEAN` where possible, otherwise a `NUMBER` constrained to a 0..1 probability, propensity, or bounded score. Nexyron keeps at most one `target` feature per abstraction: registering a new target for the same abstraction demotes the previous target back to `predictor`. `clustering_input` is reserved for later unsupervised segmentation workflows and does not have the one-per-abstraction target rule.

Post-ingest feature generation records target evidence and prevents later predictor and clustering parameters from reusing the same source property, temporal stream, object `index_path`, relationship evidence, or aggregation/statistical family used by the target. This prevents target leakage while still allowing the Rust generator to build a broad feature surface from the ingested dataset.

The abstraction builder dry run and health check use that same contract. Nexyron samples up to ten subjects from the owning abstraction source query, substitutes each sampled subject into `$subject_id`, executes the resulting runtime calculation, and validates the returned `subject_id` and `value` columns. That means dry run failures should usually be fixed in the abstraction source query or in the feature's single-subject calculation, not by widening the feature into a full-dataset scan.

Abstraction Builder also validates Cypher variable scope before executing sampled feature rows. `WITH` narrows the available variables, so a feature query that carries only `subject_id` forward and later returns `avg(m.score) AS value` is invalid because `m` is no longer in scope. Keep the node or relationship variable in every intervening `WITH` until its property is consumed, or aggregate/project the property before dropping the variable.

Weak value warnings are confirmed by deterministic dry-run diagnostics. If a feature query uses a relative current-time window, such as `currenttimestamp() - 2592000000`, validation can use the latest available temporal data for the relevant tag/category as context so historical datasets are not mistaken for empty live-current windows.

When a feature is registered manually or by the post-ingest Rust generator, it should compute a real value from direct properties, related nodes, relationship properties, containment paths, temporal histories and rollups, document-style fields, object `index_paths`, or existing abstraction/relation contracts. A contract that only returns `$subject_id` and `null AS value` is not a valid substitute.

Temporal streams are now mandatory planning evidence when they are reachable from the selected abstraction or from contained/member items. If a field is available both as a current node or edge property and as a temporal stream, the post-ingest deterministic generator keeps the temporal stream-derived surface and does not register static direct-property `.current` features. Stream-derived contracts should compute from `nexyron.temporal_history`, `nexyron.temporal_rollup`, declared object `index_paths`, event-time predicates, or ordered temporal sequences rather than shortcutting back to the current field. The Rust-side planner adds deterministic temporal parameters for eligible numeric streams, including latest plus 30-day and 90-day `sum`, `min`, `max`, `avg`, `stddev_samp`, trend, and cadence/inter-event-average metrics. Boolean streams get latest plus 30-day and 90-day counts. Text streams get latest only. For object-valued temporal streams, each declared `index_path` is exposed according to its inferred type under the same numeric, boolean, or text rules.

Persisted feature contracts should normally stay `ASOF`\-free. Snapshot, materialize, and backfill execution can run the same stored query under an injected point-in-time context when an `at` timestamp is supplied. Under that context, direct access to a declared temporal property returns the latest scalar or object value at or before the `ASOF` timestamp, while `nexyron.temporal_history` and `nexyron.temporal_rollup` still return rows or buckets capped to that timestamp.

Relationship-backed abstractions must also plan graph-statistical and algorithmic feature families when the schema supports them. Useful examples include connected counts, ratios, rates, neighbor aggregates, relationship density, path or flow measures, community or cluster membership and size, community density, centrality, bridge-style scores, and cross-abstraction aggregates. The Rust-side planner adds basic connected-count features for selected abstraction relations and matching schema connections, after filtering out anything that overlaps the target footprint. These graph features are additions to scalar node, edge, and stream features; they should not replace direct stored values.

The removed Abstraction Builder LLM feature planner is not a production generation path. Persisted observed-data feature contracts should come from post-ingest Rust abstraction generation or explicit manual registry edits, and persisted feature queries must be complete runtime contracts without sample-only `LIMIT` clauses.

For stage and society features, containment is derived inside the feature query. When a stage feature needs actors, the query should bind the stage from `$subject_id` and match the schema-grounded actor relationship from that stage. When a society feature needs stages or actors, the query should bind the society from `$subject_id`, match contained stages, and then match actors through those stages. Runtime-injected containment-list placeholders are not part of the feature contract.

Containment lookup is source-bounded during dry run. Relation contracts must therefore expose `source_id` as an explicit alias expression that can be filtered before the query runs. A relation query that can only be checked by materializing all source-target pairs is rejected during Abstraction Builder validation rather than being allowed to time out later.

## More Detailed Explanation

In practical queries, start by deciding the row grain you want after the call: one row per node, one row per path, one row per registry object, one row per artifact, or one row per summary. Then keep that grain explicit with `YIELD` and named projections. That is the difference between a useful planner-facing example and a vague call that downstream tooling cannot safely compose. For contract-driven abstraction procedures, the executable examples on these pages intentionally inspect procedure metadata unless the required named artifacts are created in the same example.

## Advanced Example

```cypher
CALL nexyron.procedures()
YIELD name, parameters, output_columns
WHERE name = 'nexyron.feature_register'
RETURN name,
       [p IN parameters | p.name] AS parameter_names,
       output_columns
ORDER BY name
```

## Real Use Cases

-   Register reusable member-retention contracts once, then let snapshots, datasets, models, and policies reference those names instead of duplicating raw Cypher in every workflow.
-   Keep admin and product teams aligned around one shared abstraction contract for members, households, facilities, interventions, and churn labels during quarterly retraining cycles.

## Real Limitations And Tradeoffs

-   This surface is contract-driven. If the registered feature, snapshot, dataset, model, or policy definition is weak, the procedure will faithfully execute that weak contract rather than silently repairing it.
-   A target feature is a registry annotation, not a model by itself. It tells supervised ML workflows which feature represents the label to predict; snapshots and datasets still need to include the feature names they use.
-   Catalog procedures define or expose metadata. They do not by themselves build data, score models, or apply interventions.
-   Generated feature contracts must use `$subject_id` as the only runtime input and derive any related scope through Cypher patterns from that subject instead of scanning the full abstraction set.
-   Health checks sample abstraction subjects rather than proving every possible subject-feature value. They are meant to catch invalid contracts, missing columns, null-only calculations, subject mismatches, and obvious degenerate values before snapshot materialization.
-   Feature generation is expected to produce intent-relevant business signals, not arbitrary schema transforms. Identifier mechanics such as id length, string length, or element-id length are rejected unless the user explicitly asks for text-quality or identifier-hygiene features.
-   Feature values must be statistically or behaviorally meaningful model signals. Raw identity outputs such as the member itself, `subject_id`, `node_id`, `element_id`, UUIDs, identifiers, or raw contact fields are rejected because they identify the row rather than measuring behavior, state, risk, context, containment, or another useful signal.
-   Name, date-of-birth, and birthdate fields are allowed feature candidates when they are schema-grounded and useful for the selected analysis. Categorical business names such as `package_name`, `plan_name`, `campaign_name`, `target_label`, `node_title`, `display_category`, `postcode`, or `postal_region` remain valid when they identify the selected offer, plan, category, label, title, business state, or geographic bucket.
-   Raw contact details such as email addresses, phone numbers, and street addresses are rejected for the same reason. Contact-channel permission and preference fields are different: scalar values such as `email_opt_in`, `text_notifications`, or opt-out status can be valid feature signals when they return consent, notification, or preference state rather than the raw contact value.
-   Automatic observed-data feature generation is owned by the post-ingest Rust abstraction generator. It uses schema evidence, temporal declarations, object `index_paths`, and existing abstraction/relation contracts from the completed ingest.
-   `ASOF` belongs to execution context, not ordinary persisted feature text. Add explicit `ASOF` only for ad hoc point-in-time Cypher outside the registry; feature snapshots and backfills inject the point-in-time context around stored contracts.
-   Removing a feature is an explicit registry mutation through `nexyron.feature_delete`, not an implicit result of a later ingest or registry edit omitting it.
-   Feature names are registry identifiers, not display labels. They should be safe field-like names such as `visit_count_30d`, `churn_risk_score`, or `member.days_since_last_visit`, because selector-style usage depends on names that can appear after a dot, such as `actor(Member:<subject_id>).visit_count_30d`. Names with spaces, colons, angle brackets, parentheses, slashes, punctuation, or title-style display text are invalid.
-   Relationship-derived feature scope is only as good as the schema-grounded path in the feature query and the owning abstraction's subject identity. If the stage-to-actor or society-to-stage path is missing or too broad, dry run and materialization will either fail or faithfully compute the wrong scope.
-   Dry-run health checks report invalid source, relation, or feature diagnostics. They do not invoke the removed LLM repair path.
