diff --git a/TODO.md b/TODO.md
index af560843b..e09d5dd05 100644
--- a/TODO.md
+++ b/TODO.md
@@ -94,14 +94,14 @@ Instance `dmesg`:
| Command | Implemented Flags | Missing Flags | Prerequisites | Basic Logic | Test Cases | Status |
|---------|-------------------|---------------|---------------|-------------|------------|--------|
| `describe-images` | `--image-ids` (format validation only) | `--owners`, `--executable-users`, `--filters`, `--include-deprecated`, `--include-disabled`, `--max-results`, `--next-token`, `--dry-run` | None | NATS `ec2.DescribeImages` → daemon reads AMI metadata from Predastore S3 buckets (ami-*) → returns image list with state, architecture, block device mappings | 1. List all images
2. Filter by image ID
3. Filter by owner (self/amazon)
4. Non-existent AMI returns empty
5. Verify metadata fields (architecture, state, rootDeviceName) | **DONE** |
-| `create-image` | Parsed only (mock): `--instance-id`, `--name`, `--description`, `--no-reboot`, `--block-device-mappings`, `--tag-specifications` | All flags need real business logic (currently returns hardcoded ami-ID). Not wired to gateway. | Instance must exist | Stop instance (unless --no-reboot) → snapshot root volume via viperblock → create AMI metadata in S3 → register as new AMI → restart instance → return ami-ID | 1. Create image from running instance
2. Create with --no-reboot
3. Invalid instance ID (error)
4. Verify new AMI appears in describe-images
5. Launch new instance from created AMI | **PARTIAL** (mock service) |
-| `register-image` | Parsed only (mock): `--name`, `--description`, `--architecture`, `--root-device-name`, `--virtualization-type`, `--block-device-mappings`, `--boot-mode` | All flags need real business logic. Not wired to gateway. Also: `--ena-support`, `--sriov-net-support`, `--tpm-support`, `--imds-support` | Image data must exist in S3 | Create AMI metadata entry in Predastore → assign ami-ID → set state to available → return ami-ID | 1. Register with valid metadata
2. Missing required name (error)
3. Verify registered image in describe-images | **PARTIAL** (mock service) |
-| `deregister-image` | Parsed only (mock): `--image-id` (validated) | Real business logic needed. Not wired to gateway. `--dry-run` | AMI must exist, no instances using it | Mark AMI metadata as deregistered in S3 → AMI no longer available for new launches → existing instances unaffected | 1. Deregister existing AMI
2. Deregister non-existent AMI (error)
3. Verify deregistered AMI not in describe-images
4. Existing instances from AMI still run | **PARTIAL** (mock service) |
-| `copy-image` | Parsed only (mock): `--source-image-id`, `--source-region`, `--name`, `--description`, `--encrypted`, `--kms-key-id` | All flags need real business logic. Not wired to gateway. `--client-token`, `--copy-image-tags`, `--tag-specifications` | Source AMI must exist | Copy AMI data between regions/nodes in Predastore → create new AMI metadata with new ami-ID → return new ami-ID | 1. Copy image within same region
2. Copy non-existent image (error)
3. Verify copied image independent of source | **PARTIAL** (mock service) |
-| `import-image` | — | `--disk-containers` (Format, Url/S3Bucket+S3Key), `--description`, `--architecture`, `--platform` | S3 bucket with disk image | Download disk image from S3 → convert format (VMDK/VHD/RAW→QCOW2) → create viperblock volume → register as AMI | 1. Import QCOW2 image
2. Import RAW image
3. Invalid format (error)
4. Verify imported image launchable | **NOT STARTED** (gateway stub only) |
-| `describe-image-attribute` | Parsed only (mock): `--image-id` (validated), `--attribute` (validated) | Real business logic needed. `--dry-run` | AMI must exist | Read specific attribute from AMI metadata in S3 → return attribute value | 1. Get description attribute
2. Get launch permission
3. Invalid attribute name (error) | **PARTIAL** (mock service) |
-| `modify-image-attribute` | Parsed only (mock): `--image-id` (validated), `--launch-permission`, `--description`, `--operation-type` | Real business logic needed. `--user-ids`, `--user-groups`, `--organization-arns`, `--dry-run` | AMI must exist | Update specific attribute in AMI metadata → persist to S3 | 1. Add launch permission
2. Modify description
3. Invalid AMI (error) | **PARTIAL** (mock service) |
-| `reset-image-attribute` | Parsed only (mock): `--image-id` (validated), `--attribute` (validated) | Real business logic needed. `--dry-run` | AMI must exist | Reset attribute to default value in AMI metadata | 1. Reset launch permission to owner-only
2. Invalid AMI (error) | **PARTIAL** (mock service) |
+| `create-image` | — | `--instance-id`, `--name`, `--description`, `--no-reboot`, `--block-device-mappings`, `--tag-specifications` | Instance must exist | Stop instance (unless --no-reboot) → snapshot root volume via viperblock → create AMI metadata in S3 → register as new AMI → restart instance → return ami-ID | 1. Create image from running instance
2. Create with --no-reboot
3. Invalid instance ID (error)
4. Verify new AMI appears in describe-images
5. Launch new instance from created AMI | **NOT STARTED** |
+| `register-image` | — | `--name`, `--description`, `--architecture`, `--root-device-name`, `--virtualization-type`, `--block-device-mappings`, `--boot-mode`, `--ena-support`, `--sriov-net-support`, `--tpm-support`, `--imds-support` | Image data must exist in S3 | Create AMI metadata entry in Predastore → assign ami-ID → set state to available → return ami-ID | 1. Register with valid metadata
2. Missing required name (error)
3. Verify registered image in describe-images | **NOT STARTED** |
+| `deregister-image` | — | `--image-id`, `--dry-run` | AMI must exist, no instances using it | Mark AMI metadata as deregistered in S3 → AMI no longer available for new launches → existing instances unaffected | 1. Deregister existing AMI
2. Deregister non-existent AMI (error)
3. Verify deregistered AMI not in describe-images
4. Existing instances from AMI still run | **NOT STARTED** |
+| `copy-image` | — | `--source-image-id`, `--source-region`, `--name`, `--description`, `--encrypted`, `--kms-key-id`, `--client-token`, `--copy-image-tags`, `--tag-specifications` | Source AMI must exist | Copy AMI data between regions/nodes in Predastore → create new AMI metadata with new ami-ID → return new ami-ID | 1. Copy image within same region
2. Copy non-existent image (error)
3. Verify copied image independent of source | **NOT STARTED** |
+| `import-image` | — | `--disk-containers` (Format, Url/S3Bucket+S3Key), `--description`, `--architecture`, `--platform` | S3 bucket with disk image | Download disk image from S3 → convert format (VMDK/VHD/RAW→QCOW2) → create viperblock volume → register as AMI | 1. Import QCOW2 image
2. Import RAW image
3. Invalid format (error)
4. Verify imported image launchable | **NOT STARTED** |
+| `describe-image-attribute` | — | `--image-id`, `--attribute`, `--dry-run` | AMI must exist | Read specific attribute from AMI metadata in S3 → return attribute value | 1. Get description attribute
2. Get launch permission
3. Invalid attribute name (error) | **NOT STARTED** |
+| `modify-image-attribute` | — | `--image-id`, `--launch-permission`, `--description`, `--operation-type`, `--user-ids`, `--user-groups`, `--organization-arns`, `--dry-run` | AMI must exist | Update specific attribute in AMI metadata → persist to S3 | 1. Add launch permission
2. Modify description
3. Invalid AMI (error) | **NOT STARTED** |
+| `reset-image-attribute` | — | `--image-id`, `--attribute`, `--dry-run` | AMI must exist | Reset attribute to default value in AMI metadata | 1. Reset launch permission to owner-only
2. Invalid AMI (error) | **NOT STARTED** |
### EC2 - Volume (EBS) Management