# Creating And Editing Template Instances

This guide describes how to create and edit instances from templates with `graccess_cli`, including area creation, area assignment, engine assignment, I/O-related configuration, deployment, and rollback.

Use this guide with:

- `template-parsing.md` - inspect templates before instantiation.
- `template-editing.md` - edit source templates.
- `attribute-parsing.md` and `attribute-editing.md` - inspect and edit instance settings.
- `script-parsing.md` and `script-editing.md` - inspect and edit script-related content.

Run commands from `graccess_cli`. Examples assume the CLI is available as `graccess`. During local development, replace `graccess` with:

```powershell
dotnet run --project src/ZB.MOM.WW.GRAccess.Cli/ZB.MOM.WW.GRAccess.Cli.csproj --
```

## Safety Model

Mutating commands require `--confirm`. Commands that edit an object require `--confirm-target` matching the exact current object name.

Important confirmation targets:

| Command | `--confirm-target` must match |
|---|---|
| `template instantiate` | Source template name |
| `object checkout/save/checkin/undo-checkout` | Target object or instance name |
| `object set` | Target object or instance name |
| `object attribute set/lock/security/buffer` | Target object or instance name |
| `object attribute value set` | Target object or instance name |
| `instance assign-area/assign-engine/assign-container` | Target instance name |
| `io assign` | Target instance name |
| `instance deploy/undeploy/upload/delete` | Target instance name |
| `objects export` | Output file path |
| `galaxy import-objects` | Input file path |

For production work, create or use a test area and test instance first.

## Session Setup

Start a session for repeated work:

```powershell
graccess session start --galaxy ZB --node .
```

With a session active, omit `--node` on logged-in commands. Without a session, add `--node .` to each command.

For LLM-driven instance work, snapshot before and after edits:

```powershell
graccess object snapshot --galaxy ZB --name TestMachine_001 --type instance --llm-json
```

Prefer intent wrappers for IDE concepts:

```powershell
graccess area list --galaxy ZB --llm-json
graccess engine list --galaxy ZB --llm-json
graccess instance assign-area --galaxy ZB --name TestMachine_001 --area Area_Test --confirm --confirm-target TestMachine_001 --llm-json
graccess instance assign-engine --galaxy ZB --name TestMachine_001 --engine AppEngine_Test --confirm --confirm-target TestMachine_001 --llm-json
graccess io assign --galaxy ZB --name TestMachine_001 --attribute DeviceAddress --value D100 --confirm --confirm-target TestMachine_001 --llm-json
```

## Discover Source Templates

Find the exact template name before instantiation:

```powershell
graccess template list --galaxy ZB --pattern '%TestMachine%' --json
```

If the template starts with `$`, quote it in PowerShell:

```powershell
graccess template list --galaxy ZB --pattern '%$Area%' --json
graccess template list --galaxy ZB --pattern '%$AppEngine%' --json
```

Template names differ by System Platform version and galaxy standards. Always confirm the actual template names in the target galaxy.

## Create An Instance From A Template

Use `template instantiate`:

```powershell
graccess template instantiate --galaxy ZB --name TestMachine --type template --new-name TestMachine_001 --create-contained --confirm --confirm-target TestMachine
```

Notes:

| Option | Meaning |
|---|---|
| `--name` | Source template name |
| `--new-name` | New instance tagname |
| `--create-contained` | Create contained objects from the template when supported |
| `--confirm-target` | Must match the source template name |

Verify the new instance:

```powershell
graccess object get --galaxy ZB --name TestMachine_001 --type instance --json
graccess object attributes --galaxy ZB --name TestMachine_001 --type instance --json
```

## Create Areas

Areas are galaxy objects. The CLI has an `area create` wrapper and also supports the underlying `template instantiate` workflow. Prefer the wrapper when it maps cleanly to the target galaxy; fall back to `template instantiate` when you need explicit control over the source template.

Find candidate area templates:

```powershell
graccess template list --galaxy ZB --pattern '%Area%' --json
```

Create an area instance, using the exact area template name returned by the galaxy. If the template is `$Area`, quote it:

```powershell
graccess area create --galaxy ZB --template '$Area' --name Area_Test --confirm --confirm-target '$Area' --llm-json
```

Equivalent lower-level form:

```powershell
graccess template instantiate --galaxy ZB --name '$Area' --type template --new-name Area_Test --create-contained --confirm --confirm-target '$Area'
```

Verify the area:

```powershell
graccess object get --galaxy ZB --name Area_Test --type instance --json
```

Edit an area like any other instance:

```powershell
graccess object checkout --galaxy ZB --name Area_Test --type instance --confirm --confirm-target Area_Test
graccess object attribute set --galaxy ZB --name Area_Test --type instance --attribute Description --value 'Test area' --data-type string --confirm --confirm-target Area_Test
graccess object save --galaxy ZB --name Area_Test --type instance --confirm --confirm-target Area_Test
graccess object checkin --galaxy ZB --name Area_Test --type instance --comment 'Configure test area' --confirm --confirm-target Area_Test
```

If the area template or area attributes differ in the target galaxy, use the parsing docs to identify the supported attributes before editing.

## Assign An Instance To An Area

Use `object set --property area` on the instance:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object set --galaxy ZB --name TestMachine_001 --type instance --property area --value Area_Test --confirm --confirm-target TestMachine_001
graccess object save --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object checkin --galaxy ZB --name TestMachine_001 --type instance --comment 'Assign area' --confirm --confirm-target TestMachine_001
```

Validate area relationships:

```powershell
graccess object query-condition --galaxy ZB --type instance --condition belongsToArea --value Area_Test --json
```

The current CLI resolves named GRAccess objects before falling back to string assignment for object-reference properties such as `area`, `host`, and `container`.

## Create Or Find Engines

Engine creation is also template-driven. The CLI has an `engine create` wrapper and also supports the underlying `template instantiate` workflow.

Find engine templates:

```powershell
graccess template list --galaxy ZB --pattern '%Engine%' --json
```

Create an engine instance only after confirming the correct platform/engine template for the target galaxy:

```powershell
graccess engine create --galaxy ZB --template '$AppEngine' --name AppEngine_Test --confirm --confirm-target '$AppEngine' --llm-json
```

Equivalent lower-level form:

```powershell
graccess template instantiate --galaxy ZB --name '$AppEngine' --type template --new-name AppEngine_Test --create-contained --confirm --confirm-target '$AppEngine'
```

If the galaxy already has a target engine, inspect it instead:

```powershell
graccess object get --galaxy ZB --name AppEngine_Test --type instance --json
graccess object attributes --galaxy ZB --name AppEngine_Test --type instance --json
```

Engine templates and required container/platform relationships vary by System Platform version and galaxy standards. Use export/import or vendor tooling if engine creation requires fields the CLI does not expose yet.

## Assign An Instance To An Engine

Use `object set --property host`:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object set --galaxy ZB --name TestMachine_001 --type instance --property host --value AppEngine_Test --confirm --confirm-target TestMachine_001
graccess object save --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object checkin --galaxy ZB --name TestMachine_001 --type instance --comment 'Assign host engine' --confirm --confirm-target TestMachine_001
```

Validate engine assignment:

```powershell
graccess object query-condition --galaxy ZB --type instance --condition hostEngineIs --value AppEngine_Test --json
```

The current CLI resolves named GRAccess objects before falling back to string assignment for object-reference properties.

## Assign Container Or Parent Object

Use `object set --property container` when the instance should be contained by another object:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object set --galaxy ZB --name TestMachine_001 --type instance --property container --value Area_Test --confirm --confirm-target TestMachine_001
graccess object save --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object checkin --galaxy ZB --name TestMachine_001 --type instance --comment 'Assign container' --confirm --confirm-target TestMachine_001
```

Validate containment:

```powershell
graccess object query-condition --galaxy ZB --type instance --condition containedBy --value Area_Test --json
```

Container, area, and host are separate concepts. Use the property that matches the object model requirement for the template being instantiated.

## Create And Edit Embedded Objects

Embedded objects are contained child templates or instances. In the `TestMachine` family, `$TestMachine` contains `$TestMachine.DelmiaReceiver` and `$TestMachine.MESReceiver`; each `TestMachine_NNN` instance contains `DelmiaReceiver_NNN` and `MESReceiver_NNN`.

Create embedded objects by instantiating the parent with `--create-contained`:

```powershell
graccess template instantiate --galaxy ZB --name '$TestMachine' --type template --new-name TestMachine_021 --create-contained --confirm --confirm-target '$TestMachine' --llm-json
```

Verify parent and child objects:

```powershell
graccess object snapshot --galaxy ZB --name TestMachine_021 --type instance --llm-json
graccess instance list --galaxy ZB --pattern '%021%' --llm-json
graccess object query-condition --galaxy ZB --type instance --condition hierarchicalNameLike --value '%TestMachine_021%' --llm-json
```

If relationship queries do not return the embedded children, fall back to instance list patterns and child naming conventions:

```powershell
graccess instance list --galaxy ZB --pattern '%DelmiaReceiver_021%' --llm-json
graccess instance list --galaxy ZB --pattern '%MESReceiver_021%' --llm-json
```

Edit embedded child instances by targeting the child instance tagname:

```powershell
graccess object snapshot --galaxy ZB --name DelmiaReceiver_021 --type instance --llm-json
graccess object checkout --galaxy ZB --name DelmiaReceiver_021 --type instance --confirm --confirm-target DelmiaReceiver_021
graccess object attribute value set --galaxy ZB --name DelmiaReceiver_021 --type instance --attribute DownloadPath --value 'C:\Recipes\021' --data-type string --confirm --confirm-target DelmiaReceiver_021 --llm-json
graccess object save --galaxy ZB --name DelmiaReceiver_021 --type instance --confirm --confirm-target DelmiaReceiver_021
graccess object checkin --galaxy ZB --name DelmiaReceiver_021 --type instance --comment 'Configure embedded Delmia receiver' --confirm --confirm-target DelmiaReceiver_021
```

Assign or move containment with `instance assign-container` or `object set --property container` only when the target object model supports moving that object:

```powershell
graccess instance assign-container --galaxy ZB --name DelmiaReceiver_021 --container TestMachine_021 --confirm --confirm-target DelmiaReceiver_021 --llm-json
```

Do not assume embedded child tag names are globally derivable from the parent number in every galaxy. Always verify `ContainedName` and `HierarchicalName` with `object snapshot`.

## Assign I/O

I/O assignment can mean different things depending on the template:

| I/O concern | Usual configuration path |
|---|---|
| Host engine | `object set --property host` |
| Area | `object set --property area` |
| Parent/container | `object set --property container` |
| Device/topic/address/reference settings | Attribute values or extension payloads |
| Complex I/O object structure | Instantiate I/O templates, set relationships, or import package |

First parse likely I/O settings:

```powershell
$attrs = graccess object attributes --galaxy ZB --name TestMachine_001 --type instance --json | ConvertFrom-Json
$extended = graccess object extended-attributes --galaxy ZB --name TestMachine_001 --type instance --json | ConvertFrom-Json
$io = (@($attrs) + @($extended)) | Where-Object {
  $_.Name -match '(?i)\bio\b|input|output|source|destination|scan|topic|device|address|reference'
} | Sort-Object Name -Unique

$io | Select-Object Name, DataType, Category, RuntimeSetHandler, ConfigSetHandler
```

Edit simple I/O attributes:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object attribute set --galaxy ZB --name TestMachine_001 --type instance --attribute DeviceAddress --value 'D100' --data-type string --confirm --confirm-target TestMachine_001
graccess object attribute set --galaxy ZB --name TestMachine_001 --type instance --attribute ScanPeriod --value 1000 --data-type int --confirm --confirm-target TestMachine_001
graccess object save --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object checkin --galaxy ZB --name TestMachine_001 --type instance --comment 'Assign I/O settings' --confirm --confirm-target TestMachine_001
```

The exact attribute names are template-specific. Use `attribute-parsing.md` to identify real names before editing.

The current CLI supports scalar attribute values only: `string`, `bool`, `int`, `float`, and `double`. Complex I/O settings such as object references, arrays, structured addresses, or extension-specific payloads may require object export/import or additional CLI value serialization.

## Edit Instance Attributes

For normal instance configuration:

```powershell
graccess object checkout --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001

graccess object attribute set --galaxy ZB --name TestMachine_001 --type instance --attribute Description --value 'Machine 001' --data-type string --confirm --confirm-target TestMachine_001

graccess object attribute security --galaxy ZB --name TestMachine_001 --type instance --attribute Description --security MxSecurityOperate --confirm --confirm-target TestMachine_001

graccess object save --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
graccess object checkin --galaxy ZB --name TestMachine_001 --type instance --comment 'Configure instance' --confirm --confirm-target TestMachine_001
```

For a deeper attribute workflow, use `attribute-editing.md`.

## Deploy, Undeploy, And Upload

Deploy an explicitly named test instance:

```powershell
graccess instance deploy --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
```

Undeploy:

```powershell
graccess instance undeploy --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
```

Upload runtime changes:

```powershell
graccess instance upload --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
```

Bulk deployment commands are available, but use them only with explicit target selection:

```powershell
graccess objects deploy --galaxy ZB --type instance --name TestMachine_001 --name TestMachine_002 --confirm --confirm-target TestMachine_001,TestMachine_002
```

For bulk commands, the confirmation target must match the CLI's target list. Prefer single-instance deployment until the target list behavior is verified in a test galaxy.

## Export Instance Configuration

Export before risky edits:

```powershell
$pkg = '.\instance-snapshots\TestMachine_001-before.aaPKG'
graccess objects export --galaxy ZB --type instance --name TestMachine_001 --output $pkg --confirm --confirm-target $pkg
```

For full-fidelity edits not supported by scalar CLI commands, edit through the supported package workflow and import:

```powershell
graccess galaxy import-objects --galaxy ZB --file '.\instance-snapshots\TestMachine_001-edited.aaPKG' --overwrite --confirm --confirm-target '.\instance-snapshots\TestMachine_001-edited.aaPKG'
```

## Delete Test Instances

Delete only explicitly named test instances:

```powershell
graccess instance delete --galaxy ZB --name TestMachine_001 --type instance --confirm --confirm-target TestMachine_001
```

If the object is deployed, undeploy it first unless the selected force option explicitly allows deletion. The command exposes `--force-option`; the default is `undeployIfDeployed`.

```powershell
graccess instance delete --galaxy ZB --name TestMachine_001 --type instance --force-option undeployIfDeployed --confirm --confirm-target TestMachine_001
```

## End-To-End Example

This creates an area, creates a template instance, assigns area and engine, sets simple I/O attributes, and deploys the instance.

```powershell
$galaxy = 'ZB'
$template = 'TestMachine'
$areaTemplate = '$Area'
$area = 'Area_Test'
$engine = 'AppEngine_Test'
$instance = 'TestMachine_001'

graccess session start --galaxy $galaxy --node .

graccess template instantiate --galaxy $galaxy --name $areaTemplate --type template --new-name $area --create-contained --confirm --confirm-target $areaTemplate

graccess template instantiate --galaxy $galaxy --name $template --type template --new-name $instance --create-contained --confirm --confirm-target $template

graccess object checkout --galaxy $galaxy --name $instance --type instance --confirm --confirm-target $instance
graccess object set --galaxy $galaxy --name $instance --type instance --property area --value $area --confirm --confirm-target $instance
graccess object set --galaxy $galaxy --name $instance --type instance --property host --value $engine --confirm --confirm-target $instance
graccess object attribute set --galaxy $galaxy --name $instance --type instance --attribute DeviceAddress --value 'D100' --data-type string --confirm --confirm-target $instance
graccess object attribute set --galaxy $galaxy --name $instance --type instance --attribute ScanPeriod --value 1000 --data-type int --confirm --confirm-target $instance
graccess object save --galaxy $galaxy --name $instance --type instance --confirm --confirm-target $instance
graccess object checkin --galaxy $galaxy --name $instance --type instance --comment 'Create and configure test instance' --confirm --confirm-target $instance

graccess instance deploy --galaxy $galaxy --name $instance --type instance --confirm --confirm-target $instance
```

Before running this exact sequence, verify `$Area`, `AppEngine_Test`, `DeviceAddress`, and `ScanPeriod` are valid in the target galaxy. These names are examples, not universal System Platform requirements.

## Post-Edit Verification

Verify object records and relationships:

```powershell
graccess object get --galaxy ZB --name TestMachine_001 --type instance --json
graccess object attributes --galaxy ZB --name TestMachine_001 --type instance --configurable --json
graccess object query-condition --galaxy ZB --type instance --condition belongsToArea --value Area_Test --json
graccess object query-condition --galaxy ZB --type instance --condition hostEngineIs --value AppEngine_Test --json
```

If deployed, verify deployment status through available object details or System Platform tooling. The current `object get` output does not emit every `IInstance` status property; extending object details to include `DeploymentStatus`, `DeployedVersion`, validation errors, and warnings is recommended.

## Current CLI Gaps For Instance Work

| Area | Current status | Recommended next step |
|---|---|---|
| Dedicated area commands | Areas are created and edited as normal instances | Add `area create/edit/list` wrappers if desired |
| Dedicated engine commands | Engines are created and edited as normal instances | Add `engine create/edit/list` wrappers if desired |
| Object-reference assignment | `object set` currently writes the supplied value directly | Resolve named objects and assign COM object references when required |
| Bulk property edits | Bulk deploy/undeploy/upload/delete/export exist; bulk `area`/`host` assignment does not | Add guarded `objects set` after single-object assignment is reliable |
| Complex I/O values | Scalar `MxValue` writes only | Add array/reference/structured value serialization |
| Deployment status details | `object get` does not emit all instance status fields | Extend object detail output defensively |
