一键导入
ontologian-validate
Use when the user runs /ontologian-validate or wants to check ontology YAML schema correctness and referential integrity across all domains.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when the user runs /ontologian-validate or wants to check ontology YAML schema correctness and referential integrity across all domains.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when the user runs /ontologian-add or wants to add a new Object Type, Link Type, or Action Type to an ontology domain.
Use when the user runs /ontologian-analyze or wants to derive an ontology structure from free-form business requirements text.
Use when the user runs /ontologian or wants to see the overall status of the ontology repository — domain list, type counts, last modified dates, and available commands.
Use when the user runs /ontologian-search or wants to search for a keyword across all ontology domains (object types, link types, action types).
Use when the user runs /ontologian-sync or wants to manually sync local ontology/ to the global ~/.ontologian/ directory.
Use when the user runs /ontologian-visualize or wants to see a visual ASCII diagram of an ontology domain's Object Types, relationships, and actions.
| name | ontologian-validate |
| description | Use when the user runs /ontologian-validate or wants to check ontology YAML schema correctness and referential integrity across all domains. |
Validate the YAML schema and referential integrity across all domains. Output a pass message when no errors are found, or a detailed list of errors by domain, type, and field.
Glob ontology/domains/_index.yaml → if missing, output "Ontology is not initialized." and exit immediately.
If arguments were provided, parse them to set an optional domain filter:
/ontologian-validate ecommerce), store it as domain_filter.name does not match domain_filter._index.yamlUse the Read tool to read ontology/domains/_index.yaml.
If the domains array is empty or the file is missing:
No domains registered. Nothing to validate.
Output and exit.
Iterate over the domains array in _index.yaml and read each domain's type data.
All domains use the directory format:
ontology/domains/<directory>/objects/*.md → read each → collect into object_types[]ontology/domains/<directory>/links/*.md → read each → collect into link_types[]ontology/domains/<directory>/actions/*.md → read each → collect into action_types[]
Each file is a single entity definition with no wrapper key.If a domain file cannot be read, add the following to the error list and skip validation for that domain:
[<domain_name>] Cannot read file: <file_path>
For directory-format domains: if a subdirectory is missing or empty, treat the corresponding array as [].
For each domain, store in memory:
domain_data[domain_name] = {
object_types: [...], # empty array if absent
link_types: [...], # empty array if absent
action_types: [...] # empty array if absent
}
Each entity file is a .md file with YAML frontmatter. Parse only the frontmatter (content between the first and second --- delimiters) as YAML.
Wiki link field extraction: The from, to, and target fields may contain either a plain Object Type name or a relative-path Obsidian wiki link:
from: Shipmentfrom: "[[../objects/Shipment|Shipment]]"from: "[[../../ecommerce/objects/Order|Order]]"When reading these fields, extract the Object Type name and resolve the path as follows:
[[<path>|<Name>]] → use <Name> as the type name. Resolve <path> relative to the file's location (ontology/domains/<domain>/<subdir>/) to get the normalized file path.
../objects/<Name> → resolves to ontology/domains/<current_domain>/objects/<Name>../../<other_domain>/objects/<Name> → resolves to ontology/domains/<other_domain>/objects/<Name>[[<Name>]] → use <Name> as both the name and look it up in the current domainStore both the extracted name and the resolved normalized path (if present) for use in validation steps.
Iterate over all type items in each domain and check required fields and allowed values. Add violations to the errors list.
For each item:
| Field | Rule |
|---|---|
name | Required. Error if absent. |
description | Required. Error if absent or empty string. |
Implementation-artifact name check:
After validating name is present, check if the name ends with any of these suffixes (case-insensitive):
DTO, Entity, Repository, Manager, Service, Handler, Base, Abstract, Util, Helper, Factory, Controller
If matched, add a WARNING:
⚠ [<domain_name>] Object Type '<name>'
→ name: '<name>' contains an implementation artifact suffix ('<suffix>').
Object Type names must represent real-world entities, not code constructs.
Rename to the entity it represents (e.g. OrderDTO → Order, UserManager → remove).
If a properties array exists, validate each property:
| Field | Rule |
|---|---|
name | Required |
type | Required. Allowed values: string, int, float, boolean, date, datetime. integer is accepted as an alias for int (not an error). |
description | Optional. If absent, emit a [HINT]: [ObjectType.property] No description. Adding one helps preserve field intent. |
computed | Optional. If true, check for expression. If absent, emit a [HINT]: Computed property '<name>' has no expression. |
Property type heuristic checks (add as WARNINGs):
After validating required fields, apply these name-pattern checks:
| Property name pattern | Expected type | Warning if type is |
|---|---|---|
ends with _at, _date, _time, _on | date or datetime | string, int, float, boolean |
starts with is_, has_, can_, was_ | boolean | string, int, float |
ends with _count, _qty, _quantity, _amount, _total, _price, _cost, _fee | int or float | string, boolean |
Warning format:
⚠ [<domain_name>] Object Type '<name>' > property '<prop_name>'
→ type: '<actual_type>' — name pattern suggests <expected_type> but is declared as '<actual_type>'.
Change to <expected_type> if this field holds a real <date/boolean/numeric> value.
Enum documentation check (status-pattern fields — add as WARNINGs):
For each property where:
type is string ANDname exactly matches any of: status, state, type, kind, mode, stage, phase, category, level
OR name ends with _status, _state, _type, _kind, _mode, _stage, _phase, _category, _level (case-insensitive, e.g. order_status, account_type, delivery_stage)Check if description contains the substring "Allowed values:". If not, add a WARNING:
⚠ [<domain_name>] Object Type '<name>' > property '<prop_name>'
→ description: status-pattern field missing allowed values documentation.
Add 'Allowed values: X, Y, Z' to the description (e.g. "Allowed values: pending, active, cancelled").
Empty properties check (add as WARNING):
If properties is absent or an empty array, add a WARNING:
⚠ [<domain_name>] Object Type '<name>'
→ properties: no properties defined. Object Types should declare at least one property
(typically an identifier). Add properties or verify this is intentional.
Primary key completeness check (add as WARNING / error):
After validating all properties of an Object Type (skip if properties is absent or an empty array — covered by the empty properties check above):
primary: true. Call this pk_count.pk_count == 0: add a WARNING:
⚠ [<domain_name>] Object Type '<name>'
→ properties: no primary key defined. Add primary: true to the identifier property
(e.g. user_id, order_id) so instances can be uniquely resolved.
pk_count > 1: add an error:
[<domain_name>] Object Type '<name>'
→ properties: <pk_count> properties marked primary: true. Exactly one primary key is allowed.
Remove primary: true from all but the identifier property.
For each item:
| Field | Rule |
|---|---|
name | Required |
from | Required |
to | Required |
cardinality | Required. Allowed values: one_to_one, one_to_many, many_to_many, many_to_one |
Link Type missing description (WARNING):
If a Link Type has no description field (absent or empty string), add a WARNING:
⚠ [<domain_name>] Link Type '<name>'
→ description: not set. Every type must have a description for discoverability (Palantir Principle 6).
Example: "A User places an Order" or "An Order contains one or more Products"
many_to_many cardinality advisory (HINT):
If cardinality is many_to_many, add a HINT:
⚠ [<domain_name>] Link Type '<name>' (<from> → <to>)
→ cardinality: many_to_many links often indicate a missing intermediate Object Type.
If the relationship has its own attributes (e.g. created_at, status) or instances need
to be queried independently, consider introducing an intermediate Object Type.
Example: User --[enrolls]--> Course → User --[initiates]--> Enrollment --[covers]--> Course
If this is a simple tag/classification relationship with no relationship-level attributes, many_to_many is acceptable.
For each item:
| Field | Rule |
|---|---|
name | Required |
description | Required. Error if absent or empty string. |
trigger | Required. Allowed values: object_created, object_updated, object_deleted, manual |
target | Required |
manual trigger with no parameters (WARNING):
If trigger is manual and parameters is absent or an empty array, add a WARNING:
⚠ [<domain_name>] Action Type '<name>'
→ trigger: manual actions should declare at least one parameter to document required inputs.
If this action truly takes no inputs, document that explicitly in the action's description field.
Example parameters: approval_reason (string), override_flag (boolean)
object_updated without trigger_condition check:
If trigger is object_updated and no trigger_condition block is present, add a WARNING:
⚠ [<domain_name>] Action Type '<name>'
→ trigger: object_updated without trigger_condition fires on every property change.
Add a trigger_condition.field to specify which field change should trigger this action.
If all-property firing is intentional (e.g. audit logging), document this in the action's `description` field instead of using a wildcard field value.
trigger_condition validation (optional field):
If trigger_condition exists:
trigger is object_updated. If another trigger value is present, add an error:
[<domain_name>] Action Type '<name>'
→ trigger_condition: not allowed when trigger is '<trigger_value>'. Only valid with object_updated.
field is required. If absent, add an error:
[<domain_name>] Action Type '<name>'
→ trigger_condition.field: required field missing.
from and to are optional. Having only field is valid — it means "fire on any change to this field".
If from is provided but field is absent, the error above covers it. Never require from/to.If a parameters array exists, validate each parameter:
| Field | Rule |
|---|---|
name | Required |
type | Required. Allowed values: string, int, float, boolean, date, datetime |
required | Optional. If present, allowed values: true, false. Any other value is an error. |
Parameter with no name: Record as a schema error and skip further validation for that parameter.
If required is present with an invalid value, add an error:
[<domain_name>] Action Type '<name>' > parameter '<param_name>'
→ required: invalid value '<value>'. Allowed: true, false. Omit this field when the parameter is required (true is the default).
After validating all Link Types and Action Types, perform a cross-domain wiki link integrity check.
For each Link Type, check the from and to fields. For each Action Type, check the target field. Apply the following checks only when the field value is a wiki link (matched in Step 3-B); skip plain string values here (they are handled by referential integrity in Step 5).
For each wiki link value found in from, to, or target:
Validate the link format. The value must match one of:
[[../objects/<Name>|<Name>]][[../../<directory>/objects/<Name>|<Name>]]If it does not match either pattern, add an error:
[<domain_name>] <Type Kind> '<name>'
→ <field>: '<value>' is not a valid relative-path Obsidian wiki link.
Expected format: [[../objects/<Name>|<Name>]] (same-domain)
or [[../../<directory>/objects/<Name>|<Name>]] (cross-domain)
Check that the referenced file exists. Resolve the path relative to the file's location, then Glob the resulting ontology/domains/<directory>/objects/<Name>.md. If the file does not exist, add an error:
[<domain_name>] <Type Kind> '<name>'
→ <field>: '<value>' — resolved file not found.
Verify the Object Type name and domain directory are correct.
Check cross-domain dependency declaration. If the resolved <directory> differs from the current domain's directory:
_index.yaml and read its dependency_direction list.dependency_direction, add an error:
[<domain_name>] <Type Kind> '<name>'
→ <field>: cross-domain reference to '<Name>' in domain '<referenced_domain>' is not declared.
Add '<referenced_domain>' to dependency_direction in _index.yaml for domain '<domain_name>'.
Error message format:
[<domain_name>] <Type Kind> '<name>'
→ <field>: <error description>
For directory-format domains, render entity names as file links in error messages:
[<domain_name>] [<TypeName>](ontology/domains/<directory>/<subdir>/<filename>.md): <error_message>
Where:
objects/<Name>.mdlinks/<name>.mdactions/<name>.mdExamples:
[ecommerce] Object Type 'Product'
→ description: required field missing.
[ecommerce] Object Type 'Product' > property 'price'
→ type: invalid value 'number'. (Allowed: string, int, float, boolean, date, datetime)
[ecommerce] Link Type 'places'
→ cardinality: invalid value 'one_to_few'. (Allowed: one_to_one, one_to_many, many_to_many, many_to_one)
[ecommerce] Action Type 'send_welcome_email'
→ trigger: invalid value 'on_create'. (Allowed: object_created, object_updated, object_deleted, manual)
[ecommerce] Action Type 'send_email' > parameter 'index 0': name field missing
Warning examples:
⚠ [ecommerce] Object Type 'Product' > property 'price': No description. Adding one helps preserve field intent.
⚠ [ecommerce] Object Type 'User' > property 'status': No description. Adding one helps preserve field intent.
For each domain, first collect the list of Object Type names (object_names) within that domain.
Cross-domain reference policy:
For each Link Type from/to and Action Type target, first check whether the referenced Object Type name exists in the current domain's type list.
If not found in the current domain, check all other registered domains:
<other_domain>):
_index.yaml entry declares dependency_direction that includes <other_domain>: emit a WARNING (not an error):
⚠ [<domain_name>] <TypeKind> '<name>'
→ <field>: '<value>' is defined in domain '<other_domain>', not '<domain_name>'.
This cross-domain reference is declared via dependency_direction and is intentional.
Consider using a reference ID property instead of a direct link for better decoupling.
dependency_direction including <other_domain>: emit an error:
[<domain_name>] <TypeKind> '<name>'
→ <field>: '<value>' does not exist in domain '<domain_name>' and no dependency_direction
to '<other_domain>' is declared.
Either add '<value>' to '<domain_name>', declare dependency_direction: ['<other_domain>']
in _index.yaml, or use a reference ID property.
Check whether each Link Type's from and to values exist in object_names for the same domain. Apply the cross-domain reference policy above if not found in the current domain.
Check whether each Action Type's target value exists in object_names for the same domain. Apply the cross-domain reference policy above if not found in the current domain.
If trigger_condition exists and field is set, verify that the field exists as a property of the target Object Type.
If not found, add an error:
[<domain_name>] Action Type '<action_name>'
→ trigger_condition.field: '<field_value>' does not exist as a property of target '<target_name>'.
field is set to "*", "any", or any other wildcard/placeholder value, add an error:
[<domain_name>] Action Type '<name>'
→ trigger_condition.field: wildcard value '<value>' is not a valid property name.
Specify the exact property name to watch, or remove trigger_condition entirely to
document intentional all-property firing in the action's description field.
For each domain entry in _index.yaml, check for governance metadata:
| Field | Severity if missing | Warning text |
|---|---|---|
domain_owner | WARNING | Domain '<name>' has no domain_owner. Add domain_owner: <team-name> to the _index.yaml entry. |
stability | WARNING | Domain '<name>' has no stability. Add stability: stable|experimental|deprecated to the _index.yaml entry. |
semantic_version | HINT | Domain '<name>' has no semantic_version. Add semantic_version: 1.0.0 to the _index.yaml entry. |
dependency_direction | — | Optional field. No warning if absent. Validated separately below. |
Allowed values for stability: stable, experimental, deprecated. If set to another value, add an error:
[<domain_name>] _index.yaml
→ stability: invalid value '<value>'. Allowed: stable, experimental, deprecated.
Emit all governance metadata issues as warnings (⚠), not errors. Include them in the warnings list.
dependency_direction domain existence check:
If a domain entry declares dependency_direction: [<name1>, <name2>, ...], verify that each referenced name appears in the domains array of _index.yaml. If a referenced domain is not found, emit a WARNING:
⚠ [<domain_name>] _index.yaml
→ dependency_direction: '<ref_name>' does not match any registered domain.
Registered domains: <list>. Check for typos or missing domain registration.
After collecting all action types across all domains, perform a single-hop circular trigger check:
Build a list of all object_created actions: { domain, action_name, target }.
For each pair of object_created actions (A, B) in the same domain where A ≠ B:
A.target == B.target, these two actions both fire when the same Object Type is created.⚠ [<domain_name>] Action Types '<A.action_name>' and '<B.action_name>'
→ Both use trigger: object_created with the same target '<target>'.
If either action creates a new '<target>' instance, this will cause an infinite trigger loop.
Review each action's side effects to confirm no '<target>' instance is created as a result.
If intentional, document this explicitly in both actions' descriptions.
Verification: Two actions in the same domain both with trigger: object_created and target: User → both are flagged in the same warning.
Within each domain, check for duplicate names within each type category:
object_types[].namelink_types[].nameaction_types[].nameIf duplicates found, add an error:
[<domain_name>] Duplicate Object Type name: '<name>'
[<domain_name>] Duplicate Link Type name: '<name>'
[<domain_name>] Duplicate Action Type name: '<name>'
No errors and no warnings:
✓ All domains passed validation (<N> domains, <N> Objects, <N> Links, <N> Actions)
[i] Tip: Run /ontologian-visualize to render relationship diagrams, or /ontologian-sync to push to the global store.
No errors but warnings exist:
Count warnings by severity before rendering:
✓ Validation passed — <W> warning(s), <H> hint(s)
⚠ <warning1>
⚠ <warning2>
...
If there are zero warnings, omit the warning count and render as:
✓ Validation passed — <H> hint(s)
If there are zero hints (only warnings):
✓ Validation passed — <W> warning(s)
N is the total count across all domains.
One or more errors:
✗ Validation failed — <N> error(s) found
<error1>
<error2>
...
If warnings also exist, append them after the error list:
⚠ Recommendations (<W>)
⚠ <warning1>
⚠ <warning2>
...
Output errors in the order they were collected. Add a blank line between each error item.
object_types, link_types, or action_types is absent, treat it as an empty array.name field should be recorded as schema errors and excluded from referential checks.N error(s) found header must exactly match the number of items in the errors list.warnings, not errors. Do not include them in the error count.