# Attribute Examples

#### Controlling Attribute Population at Creation

This powerful use case allows you to enforce attribute assignment rules precisely at the creation event, ensuring correct attribute values before the inventory moves further through your workflow, preventing potential discrepancies with subsequent stakeholders.

* **Control custom attribute population on run creation for BUILD procedures (example attribute key ‘Pedigree’)**:

```python
mutation {
  createRule(input: {
    title: "Must Have Pedigree Populated at Run Creation",
    target: RUN,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  run(id: $id) {\n    attributes {\n      key\n      value\n    }\n    procedure {\n      type\n    }\n  }\n}",
    code: "run = context.get('run', {})\nproc_type = ((run.get('procedure') or {}).get('type') or '').upper()\n\nif proc_type == 'BUILD':\n    pedigree_val = next(\n        (a.get('value') for a in run.get('attributes', [])\n          if a.get('key') == 'Pedigree'),\n        None,                    # use None as the default\n    )\n\n    # Missing if it’s None **or** empty/whitespace\n    if pedigree_val is None or not str(pedigree_val).strip():\n        raise ValidationError()\n\n\n\n",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}
```

* **Verify inventory attribute population by referencing part attributes**:

This example checks attributes at the part level to ensure that the inventory instance about to be created is allowed to have the assigned attribute value. In the scenario below, the inventory attribute ‘Pedigree’ cannot be set to ‘Flight’ unless the part-level attribute ‘Flight Worthy’ is marked as ‘Yes’. This rule includes exit paths if the procedure does not exist or is not of type ‘BUILD’.

```python
mutation {
  createRule(input: {
    title: "Run Pedigree Cannot be Flight due to Part Library Not Being Flight Worthy",
    target: RUN,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  run(id: $id) {\n    part {\n      Attributes {\n        key\n        value\n      }\n    }\n    Attributes {\n      key\n      value\n    }\n    procedure {\n      type\n      Attributes {\n        key\n        value\n      }\n    }\n  }\n}",
    code: "run = context.get('run') or {}\nprocedure_type = (run.get('procedure') or {}).get('type')\n\n# Exit early if the run isn't a BUILD or if procedure is missing\nif procedure_type != 'BUILD':\n    return\n\n# Grab run-level pedigree\nrun_attrs = run.get('Attributes', []) or []\nrun_pedigree = next(\n    (attr.get('value') for attr in run_attrs if attr.get('key') == 'Pedigree'),\n    None\n)\n\n# Grab part-level flight-worthy flag (if there's a part at all)\npart = run.get('part') or {}\npart_attrs = part.get('Attributes', []) or []\npart_worthy = next(\n    (attr.get('value') for attr in part_attrs if attr.get('key') == 'Flight Worthy'),\n    None\n)\n\n# Enforce the pedigree vs. flight-worthy rule\nif run_pedigree in ('Flight') and part_worthy not in ('Yes'):\n    raise ValidationError()",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://manual-v2.firstresonance.io/os/ion-actions/attribute-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
