OpenHound Entity Panels
Use this skill to update an OpenHound extension's extension/schema.json with
curated info panels.
For implementation, read references/panel-authoring.md. For a repository-wide migration, also read references/entity-agent-contract.md. Read GUIDE.md for installation, orchestration, and runtime testing.
Required Outcome
Unless the user narrows the scope, update every object in node_kinds and
relationship_kinds.
Every node kind must have:
description, titledDescription, at position 1.inbound_traversable_relationships, titledInbound Traversable <Platform> Relationships, at position 2.outbound_traversable_relationships, titledOutbound Traversable <Platform> Relationships, at position 3.- One or more node-specific Cypher investigation items at later contiguous positions.
Put all useful source-description sections in the single Description item and retain their section titles as level-two Markdown headers. Do not create one accordion per prose section.
The two relationship-summary items are mandatory even when one direction has no edges. Their query must cover every direct relationship of the extension that is traversable in the stated direction. Render only one guarded dynamic Explore link in the success state; do not add a prose introduction or visible edge inventory. Record the exact inventory in fragment metadata so completeness remains reviewable. An empty direction still gets a link whose selected-node query deliberately returns no paths. Derive the platform label from repository metadata, preferring the configured extension short name and then the schema namespace.
Each later investigation item covers one concrete investigation goal for the
selected node. Derive its title, scope, and query from the node description,
incident relationships, and relevant files under extension/saved_searches.
Prefer two or more items when evidence supports distinct goals; do not
manufacture filler merely to reach a count.
For a role-like node, useful separation might be:
Role Assignments and Grant Sources, anchored on inbound assignment and grant paths.Accessible Resources, anchored on outbound resource-access paths.Administrative Capabilities, when distinct administrative edges justify a separate investigation.
These are examples of investigation design, not universal titles. Use concise
noun phrases or short action labels, following BloodHound conventions such as
Active Assignments, Approvers, Members, and Roles. Investigation titles
must not be questions: do not end them with ? or lead with question forms such
as Who, What, Which, Where, When, Why, How, Can, Does, Is,
or Are. A request, session, connector, resource, token, or other node kind
needs labels specific to its own graph semantics. Never create Related Entities.
Unlike nodes, relationship descriptions are divided by source section. Every
level-two (##) heading becomes one relationship accordion in the same order.
Map ## General Information (or ## General) to general, titled General,
at position 1. Use the other H2 text as the panel title and a lowercase
URL-compatible semantic key such as abuse_info, opsec_considerations, or
references. Remove the H2 line from the panel body while retaining H3 and
deeper subsections, including cleanup or reverting instructions, inside their
parent panel. Do not merge separate H2 sections, create an empty panel, or
leave an H2 heading inside relationship panel Markdown. Preserve source order,
use contiguous positions, and never create a relationship related_entities
item or generated node-selection query.
Evidence Priority
Inspect these sources for each kind:
- Its complete object in
extension/schema.json. - Its matching file under
descriptions/nodesordescriptions/edges. - Every relevant JSON file under
extension/saved_searches. - Supplemental graph documentation under
docs/graph, when present. - Kind declarations and collector/model code that emits the entity.
- Tests and other saved Cypher that establish graph semantics.
Use descriptions as canonical prose. Use saved-search names, descriptions, and queries as evidence for investigative questions, path shapes, predicates, optional context, and useful limits. Search the saved-search directory by node kind, incident relationship kind, neighboring kind, and concepts named in the description.
Do not copy a global saved search unchanged. Reframe the relevant slice around the selected node instance, preserve meaningful predicates, remove unrelated branches, and keep the resulting panel focused on one question. Multiple saved searches may support one panel, and one broad saved search may inspire several selected-node panels.
Do not invent behavior, properties, endpoints, or graph semantics. Record
missing or contradictory evidence as an assumption. Do not copy
repository-relative .md links or Mermaid blocks into panel Markdown.
Node Query Design
Before drafting a node fragment:
- Inventory the node's incident relationships, direction, neighboring kinds,
and
is_traversablevalues. - Inspect saved searches that contain the node or those relationships.
- Populate the mandatory inbound and outbound summaries with every direct traversable extension relationship, including an explicit empty state.
- Write down the distinct investigation goals a user would have after selecting this node.
- Group relationships by goal and intent, not one accordion per edge.
- Select the smallest query shape that serves each goal while keeping the selected node visible in the returned path.
A query item must:
- have a semantic key and human title specific to the node kind;
- use a concise non-question title;
- use ordinary words in its Explore-link text to explain what the view returns, without exposing node-kind or relationship-kind identifiers;
- contain exactly one Cypher query;
- anchor the selected node by exact label and stable
objectid, using one escaped%ssubstitution in the dynamic query; - use only schema-defined node and relationship identifiers;
- bind and return at least one path variable so Explore can visualize results;
- retain evidence-backed
WHERE, variable-length, orOPTIONAL MATCHbehavior when it materially answers the question; and - put each Cypher operation such as
MATCH,OPTIONAL MATCH,WHERE,RETURN, andLIMITon a new line in the query string; and - end with
LIMIT 500.
An evidence-backed query may include a non-traversable descriptive relationship when it provides useful investigation context. Do not describe it as an attack path or traversable edge.
Dynamic Explore Panels
The schema authoring surface supports markdown.content. Template execution
inside that string is a separate target-runtime capability. Schema upload does
not prove template support; a target without template execution can display
{{ ... }} literally. This skill authors dynamic Cypher panels only. Verify
the exact target with the entity-detail rendering probe in
panel-authoring.md before deployment. If the target is unavailable or fails
the probe, stop and report that dynamic entity panels cannot be validated; do
not create a fenced-query fallback.
Every relationship summary and investigation item must provide a guarded
Explore link generated from the selected node's .Properties.objectid:
- never use
.NodeIDas anid,node_id, orobjectidproperty; - normalize
objectid, guard the blank case, and escape backslashes before single quotes; - construct the complete query before
b64enc | urlquery; - put each Cypher operation on its own line by using
\ninside theprintfstring; - use the exact node label on the selected node and every endpoint whose kind is unambiguous from graph evidence; when an endpoint spans several kinds, use their verified common platform/base label if one exists, and leave it unlabeled only when no safe common label exists;
- end every query with
LIMIT 500; - use
/ui/explorewithexploreSearchTab=cypher,searchType=cypher, andcypherSearch; and - render a useful fallback when the stable identifier is absent;
- render no success-state text except one Markdown Explore link; and
- write the link label in ordinary product/domain words rather than graph identifiers.
Repository-Wide Orchestration
Use one agent per node kind and one agent per relationship kind. Never assign multiple kinds to one entity agent. Waves may be needed for concurrency.
Read repository instructions and inventory the extension:
python3 docs/og-docs-automation/skills/openhound-entity-panels/scripts/entity_panel_tool.py inventory --repo-root .Create an isolated temporary run directory with one fragment path per kind.
Spawn one entity agent per inventory item using
references/entity-agent-contract.md.Review each node agent's complete direct-traversable relationship inventory, investigation goals, saved-search evidence, and panel metadata.
Assemble into a candidate, never over the source schema:
python3 docs/og-docs-automation/skills/openhound-entity-panels/scripts/entity_panel_tool.py assemble \ --schema extension/schema.json \ --fragments <run-directory> \ --output <candidate-schema.json>Validate and inspect the candidate before applying it through the normal repository editing workflow.
Re-run validation and the extension's schema consistency and test commands.
The coordinator owns inventory, prompt consistency, target capability evidence, cross-node query quality, merge, and final validation. Each entity agent owns exactly one kind.
Supported Schema and Markdown
Each accordion uses only:
- a lowercase URL-compatible section key;
- a non-empty
title; - a unique positive integer
position; and markdown.content.
Do not emit section-level query or props, or put position inside
markdown.
Use the upload-safe Markdown subset in panel-authoring.md: no raw HTML or
comments, tag-shaped placeholders, fenced-code info strings, GFM task lists,
aligned tables, unsafe link schemes, or ordered-list blocks beginning above 1.
Node Cypher panels must use the guarded dynamic Explore-link form; fenced
Cypher queries are not supported by this skill.
Scope Boundaries
- Change only entity panels and directly related skill, test, or validation files.
- Do not rewrite source descriptions to simplify generation.
- Do not change graph kinds, IDs, direction, traversability, collector behavior, or emitted properties without a separate request.
- Preserve unrelated and user-authored work.
Validation
Run:
python3 docs/og-docs-automation/skills/openhound-entity-panels/scripts/entity_panel_tool.py validate --schema extension/schema.json
git diff --check
pwsh docs/og-docs-automation/scripts/Test-SchemaConsistency.ps1
Also run repository-specific tests in the instructed isolated environment.
Validation must establish:
- every node has Description at position 1, mandatory inbound and outbound traversable platform summaries at positions 2 and 3, and at least one later node-specific Cypher investigation item;
- both relationship-summary queries cover every direct traversable extension edge in their direction, with empty inventories proven by fragment metadata;
- investigation titles are concise semantic labels rather than questions;
- every verified dynamic query is anchored to the exact selected node label,
binds and returns a path, uses known relationship kinds, puts operations on
separate lines, and ends with
LIMIT 500; - each node fragment's
query_panelsmetadata exactly matches its sections, query relationship kinds, purpose, and repository evidence; - relationship panels map every source H2 section to exactly one accordion in
source order, contain General first, retain deeper subsections within their
parent, and contain no
related_entities; - panel fields, Markdown, JSON, schema consistency, and repository tests pass.
The validator requires dynamic links for every node summary and investigation.
Also prove hydrated content has no literal template delimiters or
template_error, decode generated links, and execute representative queries.
Without runtime evidence, do not claim dynamic-link validation or substitute
fenced queries.