Parent Tree View security, performance, and data integrity
Parent Tree View derives structure only after applying the active Entity root
View predicate and parent-field Field:Read predicate. The hierarchy cannot
be used to discover a hidden parent, child, responsibility, or label.
Security constraints
Section titled “Security constraints”For every record, the server uses the same captured Security Statements plan as ordinary Entity reads:
- lifecycle scope and root
Viewexecute in PostgreSQL before pagination; - the Parent field must pass its
Field:Readrefinement; - role, user, responsibility, field, reference, and captured-clock facts use the same captured Security configuration;
- archived scope additionally requires
ReadArchive.
The structural query receives only the resulting readable parent id. It does not return which statement matched, the responsibility subject, or an activation reason. A conditionally readable Parent field cannot be exposed as a generic client-controlled sort/filter channel; this is a narrow server-owned edge projection.
Visible forest
Section titled “Visible forest”The server first removes unreadable records. It then treats an unreadable, missing, or out-of-scope parent value as absent. The child becomes an effective root. Consequences:
- hidden parents never appear as context;
- a hidden child is absent from
ChildCount; - counts include only eligible visible direct children;
- ancestor closure traverses only visible, readable edges;
- changing archive scope may change both roots and counts.
This behavior favors non-disclosure over reproducing the physical forest.
For a related Details/Drawer block, the server applies the configured relation
as an eligibility scope before it computes effective roots or ancestor closure.
An otherwise readable ancestor outside that relation therefore cannot be
introduced as context. Child requests cannot supply or widen this filter; they
echo the opaque host ContextRevision and the server rebuilds the scope.
Malformed parent values
Section titled “Malformed parent values”| Data state | Runtime behavior |
|---|---|
| Missing parent | Child is an effective root; no parent id is disclosed. |
| Self-parent | The self edge is cut and the row reports SelfParentCut. |
| Finite cycle | One deterministic record (lowest id using invariant ordering) is cut to a root and reports CycleCut. |
| Deep valid chain | Loaded lazily; visual indentation is capped after eight levels while accessible depth remains exact. |
Only the cut row carries a safe issue enum. No warning includes the other record id. V1 has no separate administrator hierarchy-diagnostics endpoint.
Write-time integrity
Section titled “Write-time integrity”V1 intentionally does not add automatic cycle prevention to every Reference
write. Teams that require stricter semantics should add business validation
for allowed parents, maximum depth, or cycle prevention. Concurrent reparenting
must use normal record RowVersion checks and transactions supplied by the
supported record services.
Mandatory index
Section titled “Mandatory index”Every Tree parent field must have a valid, ready BTREE index whose first key is the physical parent column. Runtime rechecks physical shape. It rejects:
- an index with another leading key;
- an expression index;
- a partial index;
- an invalid or not-ready index.
Tree configuration never creates or drops database indexes. Dynamic fields
normally receive their managed automatic index. Package-owned schema must
declare HasIndex and ship an EF migration.
If index drift occurs after configuration, authoring reports
MissingBtreeIndex and runtime returns a typed unavailable error without
executing the hierarchy query. Restore a qualifying index through Entity
Explorer schema management or the owning package migration, then reload.
Performance model
Section titled “Performance model”One request resolves one root or child sibling page and exact child counts for that page. It does not run one count query per row. Server sorting and the parent-leading index keep wide child lookup bounded; lazy loading avoids materializing the complete tree in the browser.
For a related-table child request without a user filter, the server constrains the requested parent and direct children to the already resolved eligibility scope. It does not normalize or materialize the complete related scope before returning that child page.
The V1 release qualification envelope is:
- 100,000 physical fixture rows, approximately 95,000 active candidates before actor-specific access filtering;
- a sibling set up to 25,000 records;
- hierarchy depth up to 100;
PageSize <= 250.
Larger shapes are not performance-qualified by this release. Prefer a
composite (Parent, common-sort-field) index for exceptionally wide branches,
avoid recursive expand-all behavior, and model subtree bulk work as an
explicit server operation rather than repeated UI expansion.
Search cost
Section titled “Search cost”A descendant-only filter needs visible ancestor closure. Selective filters are usually cheaper than non-selective filters, but both must preserve security and exact sibling counts. Changing filter/search invalidates every loaded branch so results from the previous query cannot be inserted.
Operational verification
Section titled “Operational verification”- Read configuration options and confirm the parent option is Ready.
- Bootstrap with active scope and record root count and surface revision.
- Load one wide child page and confirm
HasNextPage. - Search for a descendant and confirm only visible ancestors have
IsAncestorContext = true. - Test as an ordinary reader; compare neither ids nor counts with an admin response in a user-visible error.
- Archive a parent in a test environment and verify the readable child becomes an effective root.
- Repair any
SelfParentCutorCycleCutthrough ordinary governed record updates.
Unsupported assumptions
Section titled “Unsupported assumptions”Do not use root count as a global result count, expose raw parent ids in errors, cache child pages across a surface/query revision, bypass the index check, or treat runtime cycle normalization as domain validation.