runbooks inventory workspaces¶
Auto-generated from
runbooks inventory workspaces --helpon 2026-05-21. Source of truth: runbooks PyPI package v1.3.22
Usage: runbooks inventory workspaces [OPTIONS]
6-phase WorkSpaces investigation: discovery, metadata, security, network,
compliance, summary.
Phase 1: workspaces:DescribeWorkspaces -- user, state, compute type, running
mode Phase 2: Bundle type, directory, OS type Phase 3: Volume encryption, IP
access control, last connection Phase 4: Directory VPC/subnet, security
groups Phase 5: Auto-stop timeout, protocol (WSP vs PCoIP), running mode
Phase 6: Cost optimisation analysis and risk summary
READONLY -- no mutations.
Examples: runbooks inventory workspaces --all-profile $AWS_OPERATIONS_PROFILE
--workspace-id ws-abc123 runbooks inventory workspaces --workspace-id
ws-abc123 --region $AWS_DEFAULT_REGION --output json
Options:
--all-profile TEXT AWS profile for centralised-ops account (env:
AWS_OPERATIONS_PROFILE). Resolves in order:
CLI arg > $AWS_OPERATIONS_PROFILE > $AWS_PROFILE.
See aws-profile-semantics.md Rule 1.
-p, --profile TEXT AWS profile name (fallback; default: from
AWS_PROFILE env var)
--workspace-id WORKSPACE_ID WorkSpace ID to investigate (e.g. ws-abc123def)
[required]
--region TEXT AWS region (default: $AWS_DEFAULT_REGION)
--output [table|json] Output format (default: table)
--help Show this message and exit.
A2 Auto-Sync · runbooks workspaces collect --help¶
$ runbooks workspaces collect --help
Usage: runbooks workspaces collect [OPTIONS]
Discover all WorkSpaces across managed accounts. Per-account collection
with cost allocation and decommission scoring.
READONLY -- no mutations.
Examples:
runbooks workspaces collect --all-profile $AWS_MANAGEMENT_PROFILE
runbooks workspaces collect --account-ids ${AWS_ACCOUNT_ID},${AWS_ACCOUNT_ID_2} --output tmp/ws/
runbooks workspaces collect --quiet
Options:
--profile TEXT AWS profile for single-account mode (env:
AWS_PROFILE). Takes precedence over
--all-profile. Region-bound queries.
--all-profile TEXT AWS profile for multi-account fan-out (env:
AWS_MANAGEMENT_PROFILE). Uses Organizations
list_accounts; per-workload profiles from
~/.aws/config. See aws-profile-semantics.md
Rule 2.
--account-ids TEXT Comma-separated account ID subset. Overrides
Organizations list_accounts. Used for
incident triage (known scope).
--output PATH CSV output directory (default:
tmp/cloudops/workspaces/). Filename pattern:
collect-YYYY-MM-DD.csv
--quiet Suppress Rich terminal output. Useful for
cron/CI pipelines.
--help Show this message and exit.
Governance Posture Snapshot¶
WorkSpaces is your virtual desktop CI fleet. 122 WorkSpaces across 7 workload accounts (b2b-energy baseline). Discovery + decommission scoring + monthly cost rollup feed the CMDB service map and FinOps savings dashboard.
| Signal | Verdict | Threshold | Evidence |
|---|---|---|---|
| Total WorkSpaces (reproducible) | 🟢 122 | matches Excel ±1 | collect-<date>.csv row count |
| Org-wide discovery coverage | 🟢 7 accounts | = list_accounts count |
Resource Explorer cross-val (V1) |
| Inactive ≥30d (w1_score>0) | 🟡 tenant-dependent | <20% of fleet | decommission_total_score column |
| Monthly cost rollup | 🟢 captured | $/workspace + total | monthly_cost_usd column |
| Risk category coverage | 🟢 4-bucket | High/Med/Low/None | state + last_* signals |
(verdict thresholds: 🟢 = on target · 🟡 = warning, review · 🔴 = breach, action required)
Overview¶
This command performs a 6-phase investigation of AWS WorkSpaces across discovery, metadata, security, network, compliance, and cost optimization.
Data Coverage: Supports 122+ WorkSpaces across 7 accounts (sourced from enterprise CI data). All examples use environment variables or generic account descriptions—no hardcoded AWS account IDs.
Two Approaches to WorkSpaces Discovery¶
| Aspect | Approach A1: Single Investigate | Approach A2: Org-Wide Collect |
|---|---|---|
| When to Use | Investigate 1 specific WorkSpace or small group by workspace-id | Discover ALL WorkSpaces across org (all accounts, all regions) |
| Profile Type | $AWS_OPERATIONS_PROFILE (centralised-ops account) |
$AWS_MANAGEMENT_PROFILE (Organizations API) + per-workload profiles |
| Scope | Single workspace-id; limited to caller's access | Org-wide; requires Organizations list + per-account loop |
| Command | runbooks inventory workspaces --all-profile $AWS_OPERATIONS_PROFILE --workspace-id ws-xxx |
runbooks workspaces collect --all-profile $AWS_MANAGEMENT_PROFILE (then per-workload loop) |
| Performance | <10s per workspace | 30-120s org-wide (depends on account count) |
| Best For | Targeted analysis, troubleshooting, compliance spot-checks | Baseline discovery, cost analysis, full estate audit |
Approach A1: Single Investigate¶
Profile Semantics: Uses $AWS_OPERATIONS_PROFILE — the centralised-ops account where cross-account WorkSpaces investigation APIs are pre-authorized.
Prerequisites
Ensure $AWS_OPERATIONS_PROFILE is set in your shell environment. Verify with: aws sts get-caller-identity --profile $AWS_OPERATIONS_PROFILE. It must return the centralised-ops account ID.
Basic Usage¶
# Set the centralised-ops profile
export AWS_OPERATIONS_PROFILE=<your-operations-profile>
# Investigate a single WorkSpace
runbooks inventory workspaces \
--all-profile $AWS_OPERATIONS_PROFILE \
--workspace-id ws-abc123def456
Output (6-Phase Analysis)¶
The command returns:
| Phase | What It Checks | Example Outputs |
|---|---|---|
| Phase 1: Discovery | DescribeWorkspaces by ID | User, state (AVAILABLE/STOPPED), compute type (PERFORMANCE/STANDARD) |
| Phase 2: Metadata | Bundle type, OS, directory | Bundle (STANDARD/PERFORMANCE), DirectoryId, OperatingSystemName |
| Phase 3: Security | Volume encryption, IP access, connection history | RootVolumeEncryption, UserVolumeEncryption, LastConnectionTime |
| Phase 4: Network | VPC/subnet, security groups, state | SubnetId, SecurityGroupIds, ConnectionStatus |
| Phase 5: Compliance | Auto-stop timeout, protocol (WSP vs PCoIP), running mode | RunningMode, RunningModeAutoStopTimeoutInMinutes, Protocol |
| Phase 6: Summary | Cost optimization + risk score | MonthlyCost ($/730h), OptimizationScore, RiskScore |
Examples¶
Primary approach: using centralised-ops account¶
# Set operations profile environment variable
export AWS_OPERATIONS_PROFILE=<your-operations-profile>
# Investigate a WorkSpace with 6-phase analysis
runbooks inventory workspaces --all-profile $AWS_OPERATIONS_PROFILE --workspace-id ws-12345abcde
Fallback: using default profile¶
# Investigate a WorkSpace using default AWS profile
runbooks inventory workspaces --workspace-id ws-12345abcde
JSON output format¶
# Generate JSON output for processing or integration
runbooks inventory workspaces \
--all-profile $AWS_OPERATIONS_PROFILE \
--workspace-id ws-12345abcde \
--output json
Multi-region investigation¶
# Investigate WorkSpace in a specific region
runbooks inventory workspaces \
--all-profile $AWS_OPERATIONS_PROFILE \
--workspace-id ws-12345abcde \
--region $AWS_DEFAULT_REGION
Approach A2 · Org-Wide Collect (Canonical)¶
# Single command. No bash loop. No --next-token bugs. No raw aws CLI.
runbooks workspaces collect \
--all-profile ${AWS_MANAGEMENT_PROFILE} \
--output tmp/cloudops/workspaces/
# → tmp/cloudops/workspaces/collect-2026-05-21.csv (22 columns, 122 rows expected)
5 Options (from workspaces.py:259-294)¶
| Option | Envvar | Default | Purpose |
|---|---|---|---|
--profile |
AWS_PROFILE |
— | Single-account mode (known WorkSpace, known host account) |
--all-profile |
AWS_MANAGEMENT_PROFILE |
— | Multi-account fan-out via Organizations list_accounts (org-wide discovery) |
--account-ids |
— | — | Comma-separated subset (override Organizations list — used for incident triage) |
--output |
— | tmp/cloudops/workspaces/ |
CSV output directory (filename pattern collect-<YYYY-MM-DD>.csv) |
--quiet |
— | False | Suppress Rich terminal table — useful for cron/CI |
Output Path & Filename Pattern¶
Filename pattern (UTC) set by workspaces.py:484 (f"collect-{_datestamp()}.csv"). Path is gitignored at tmp/ — outputs do not pollute the repo.
22-Column CSV Schema (from workspaces.py:402-425)¶
| # | Column | Source API Field | Sample Value | CMDB / CSDM Use |
|---|---|---|---|---|
| 1 | workspace_id |
Workspaces[].WorkspaceId |
ws-3j77z0g28 |
Primary CI identifier |
| 2 | directory_id |
Workspaces[].DirectoryId |
d-9067... |
Directory binding (AD/AAD) |
| 3 | bundle_id |
Workspaces[].BundleId |
wsb-... |
Bundle/SKU mapping |
| 4 | username |
Workspaces[].UserName |
[email protected] |
User CI relationship |
| 5 | computer_name |
Workspaces[].ComputerName |
EC2AMAZ-A1B2C3 |
Host CI |
| 6 | state |
Workspaces[].State |
AVAILABLE / STOPPED |
Lifecycle status |
| 7 | running_mode |
WorkspaceProperties.RunningMode |
AUTO_STOP / ALWAYS_ON |
Cost model |
| 8 | compute_type |
WorkspaceProperties.ComputeTypeName |
STANDARD / POWER |
Right-sizing |
| 9 | root_volume_size_gib |
WorkspaceProperties.RootVolumeSizeGib |
80 |
Storage CI |
| 10 | user_volume_size_gib |
WorkspaceProperties.UserVolumeSizeGib |
50 |
Storage CI |
| 11 | protocol |
WorkspaceProperties.Protocols[0] |
PCOIP / WSP |
Display protocol |
| 12 | workspace_properties |
full WorkspaceProperties JSON | (json blob) | Raw audit |
| 13 | tags |
Workspaces[].Tags |
[{"Key":"...","Value":"..."}] |
Cost allocation |
| 14 | account_id |
enriched via Organizations | ${AWS_ACCOUNT_ID} (env) |
Account CI |
| 15 | account_name |
enriched via Organizations | vams-au-metering-elec-mass-security |
Account CI |
| 16 | region |
session region | ${AWS_DEFAULT_REGION} |
Region CI |
| 17 | monthly_cost_usd |
computed | 45.00 |
FinOps |
| 18 | last_known_user_connection_timestamp |
ConnectionStatus.LastKnownUserConnectionTimestamp |
2026-04-15T08:22:33Z |
Activity signal |
| 19 | connection_status |
ConnectionStatus.ConnectionState |
CONNECTED / DISCONNECTED |
Live status |
| 20 | w1_score |
computed (inactivity ≥30d) | 0 / 30 |
Decommission signal (cost-optimization skill) |
| 21 | w2_score |
computed (stopped + cost) | 0 / 20 |
Decommission signal |
| 22 | decommission_total_score |
w1 + w2 (and future w3-w6) | 0-50 |
Aggregate decommission rank |
Worked Example · Reproduce 122 WorkSpaces from Excel Baseline¶
# 1. Run canonical collect (READONLY — pre-authorized by $AWS_MANAGEMENT_PROFILE)
runbooks workspaces collect --all-profile ${AWS_MANAGEMENT_PROFILE} \
--output tmp/cloudops/workspaces/
# 2. Verify total row count
CSV=tmp/cloudops/workspaces/collect-$(date +%Y-%m-%d).csv
ROWS=$(($(wc -l < "$CSV") - 1))
[ "$ROWS" -eq 122 ] && echo "PASS: 122" || echo "FAIL: $ROWS"
# 3. Verify 7 distinct accounts
ACCTS=$(python3 -c "import csv,sys; print(len(set(r[14] for r in csv.reader(sys.stdin) if len(r)>14)))" < "$CSV")
[ "$ACCTS" -eq 7 ] && echo "PASS: 7" || echo "FAIL: $ACCTS"
# 4. Per-account distribution (column 15 = account_name)
python3 -c "import csv,sys; from collections import Counter; print("\n".join(f"{c} {a}" for a, c in sorted(Counter(r[14] for r in csv.reader(sys.stdin) if len(r)>14).items())))" < "$CSV"
Expected Per-Account Distribution (Excel baseline)¶
| Workload Account (account_name) | Expected WorkSpaces |
|---|---|
| vams-au-metering-elec-mass-preprod | 20 |
| vams-nz-multi-fuel-api-non-prod | 2 |
| vams-au-metering-elec-mass-preprod2 | 1 |
| vams-au-metering-elec-mass-sit | 25 |
| vams-au-metering-elec-mass-security | 69 |
| vams-nz-elec-sandbox | 1 |
| vams-au-metering-elec-mass-dev | 4 |
| Total | 122 |
Reproducibility target: rows match (122) + accounts match (7) + per-account distribution within ±1 row → ≥99.5% (Excel/API <1% transient drift acceptable due to API rate-limit timing).
Approach A1-Discovery (Fast ARN Lookup)¶
Claude Command: /inventory:discover
Use /inventory:discover with
$AWS_OPERATIONS_PROFILE for a <10s org-wide WorkSpaces ARN snapshot via Resource Explorer AGGREGATOR.
Use runbooks workspaces collect (Approach A2) for the authoritative 22-column inventory.
Use Case: Org-wide WorkSpaces discovery via AWS Resource Explorer AGGREGATOR index. Fast (~<30s), eventual-consistent, suitable for CMDB delta detection and inventory sync — NOT for APRA CPS 234 audit evidence (use A2 for that).
Profile: $AWS_OPERATIONS_PROFILE (centralised-ops account hosting the aggregator index).
Worked Example¶
# Single command. Resource Explorer AGGREGATOR does the cross-account query.
runbooks workspaces collect \
--all-profile $AWS_OPERATIONS_PROFILE \
--mode discovery \
--output tmp/cloudops/workspaces/
# → tmp/cloudops/workspaces/collect-discovery-2026-05-22.csv (4 columns, 122 rows expected)
Output: 4-Column CSV¶
| Column | Value | Use |
|---|---|---|
arn |
arn:aws:workspaces:au-southeast-1:${AWS_ACCOUNT_ID}:workspace/ws-abc123 |
ARN for CI mapping |
tags |
[{"Key":"Environment","Value":"prod"}] |
Cost allocation + automation |
account_id |
${AWS_ACCOUNT_ID} |
Account CI relationship |
account_name |
vams-au-metering-elec-mass-security |
Human-readable account |
Wall Time: <30s (single aggregator query, <24h eventual-consistency lag documented in CC-ADR-016 v2).
3-Approach Comparison Matrix¶
| Dimension | A1-Investigate | A1-Discovery | A2-Inventory |
|---|---|---|---|
| Profile | $AWS_OPERATIONS_PROFILE |
$AWS_OPERATIONS_PROFILE |
$AWS_MANAGEMENT_PROFILE + per-workload loop |
| API | workspaces:DescribeWorkspaces (single) |
resource-explorer-2:Search (aggregator) |
workspaces:DescribeWorkspaces (per-account) |
| Wall Time | <10s per workspace | <30s org-wide | 30-120s org-wide |
| Output | 22 columns, 6-phase report | 4 columns (ARN focus) | 22 columns, real-time snapshot |
| Freshness | Real-time | ≤24h eventual-consistent | Real-time authoritative |
| When to Use | Deep-dive single workspace | Quick CMDB sync check | APRA evidence, cost reporting |
| APRA CPS 234 | Spot-check only | NOT suitable (lag) | ✓ Audit-grade |
| Failure Mode | AccessDenied if wrong profile | Aggregator not enabled (fail-closed) | Missing per-workload profile (fail-closed) |
Operational Paths · 5 Ways to Generate WorkSpaces Evidence¶
- runbooks CLI (canonical, this doc) —
runbooks workspaces collect --all-profile $AWS_MANAGEMENT_PROFILE - Claude
/aws:workspaces-investigate— agentic per-workspace deep-dive (uses A1) - Raw
awsCLI verify —aws workspaces describe-workspaces --profile $WORKLOAD_PROFILE(per-account, manual fallback) - Jupyter notebook —
notebooks/cloudops/workspaces-fleet-analysis.ipynb(readscollect-*.csv, plots distributions) - CxO dashboard — Vizro/Tableau view of
collect-*.csv+ monthly trends (governance posture)
Each path consumes/produces the same 22-column CSV — the schema is the contract.
Resource Explorer Cross-Validation¶
After discovery via A1 or A2, validate using AWS Resource Explorer for independent confirmation.
ARN Patterns & Resource Types¶
| Service | Resource Type | ARN Pattern | Region | Account Name |
|---|---|---|---|---|
| WorkSpaces | workspaces (directory) | arn:aws:workspaces:${AWS_DEFAULT_REGION}:${AWS_ACCOUNT_ID}:directory/${DIRECTORY_ID} |
Billing account (centralised-ops) | |
| WorkSpaces | workspace | arn:aws:workspaces:${AWS_DEFAULT_REGION}:${AWS_ACCOUNT_ID}:workspace/${WORKSPACE_ID} |
Primary region | Per-workload account |
| Directory Service | directory | arn:aws:ds:${AWS_DEFAULT_REGION}:${AWS_ACCOUNT_ID}:directory/${DIRECTORY_ID} |
Primary region | Workload account (where users live) |
Cross-Validation Query¶
# Using Resource Explorer to validate discovered WorkSpaces
aws resource-explorer-2 search \
--index-arn "arn:aws:resource-explorer-2:${AWS_DEFAULT_REGION}:${AWS_ACCOUNT_ID}:index/default" \
--query-string "resourceType:workspaces" \
--region ${AWS_DEFAULT_REGION} \
--output json | jq '.Resources[] | {Arn, Region, AccountId, LastReportedAt}'
Expected Output (for 122 WorkSpaces across 7 accounts):
[
{
"Arn": "arn:aws:workspaces:${AWS_DEFAULT_REGION}:${AWS_ACCOUNT_ID}:workspace/ws-12345abcde",
"Region": "${AWS_DEFAULT_REGION}",
"AccountId": "${AWS_ACCOUNT_ID}",
"LastReportedAt": "2026-05-21T14:32:00Z"
},
...
]
Profile Semantics & Why A2 Uses MANAGEMENT Not OPERATIONS¶
See aws-profile-semantics.md for full details. Summary:
| Profile Type | Correct Use Case | Why Not for WorkSpaces A2? |
|---|---|---|
$AWS_OPERATIONS_PROFILE |
Centralised-ops shared resources (cross-account WorkSpaces queries) | OPERATIONS account = hub; does NOT have Organizations data |
$AWS_MANAGEMENT_PROFILE |
Organizations API (list-accounts, Control Tower) |
✅ CORRECT for A2 — discovers account list; then delegates to per-workload profiles |
| Per-workload profiles | Account-specific resources (EC2, RDS, WorkSpaces in that account) | ✅ REQUIRED after A2 discovers accounts |
Key Principle: Organizations data lives in the Management account. Workload resources live in workload accounts. A2 bridges both via the discovery → resolve → loop pattern.
Profile Architecture (CC-ORG-015): All WorkSpaces investigation uses
$AWS_OPERATIONS_PROFILE(per-account + cross-account AGGREGATOR). WorkSpaces are account-level resources, not org-level — the Management profile is not required. See profile semantics.
Troubleshooting¶
Cross-Account Silent Zero Issue¶
Problem: describe-workspaces returns [] instead of an error when account access is denied.
Why It Happens: AWS WorkSpaces APIs do NOT always throw AccessDeniedException for cross-account calls. Sometimes they silently return empty results.
Detection & Fix:
# ALWAYS verify caller identity matches expected account
CURRENT_ACCT=$(aws sts get-caller-identity --profile "$PROFILE" --query Account --output text)
TARGET_ACCT="${AWS_ACCOUNT_ID}"
if [[ "$CURRENT_ACCT" != "$TARGET_ACCT" ]]; then
echo "❌ CROSS_ACCOUNT_SILENT_ZERO: Using ${CURRENT_ACCT}, expected ${TARGET_ACCT}"
# Switch to correct account profile
export AWS_PROFILE="correct-account-profile"
exit 2
fi
# Now safe to query
aws workspaces describe-workspaces --profile "$PROFILE" --output json
Empty Results with Valid Profile¶
Problem: runbooks inventory workspaces --all-profile $AWS_OPERATIONS_PROFILE --workspace-id ws-xxx returns no results.
Checklist:
1. ✅ Verify workspace-id is spelled correctly: aws workspaces describe-workspaces --workspace-ids ws-xxx --profile $AWS_OPERATIONS_PROFILE
2. ✅ Verify region: WorkSpaces are region-specific. Set export AWS_DEFAULT_REGION=<your-aws-region> (or correct region).
3. ✅ Verify profile has WorkSpaces read permissions: aws sts get-caller-identity --profile $AWS_OPERATIONS_PROFILE
4. ✅ Verify centralised-ops account: The profile should authenticate to the account where cross-account WorkSpaces APIs are configured (typically a hub/operations account).
Timeout or Slow Responses (A2)¶
Cause: Paginating through large numbers of workspaces across many accounts.
Optimization:
- Reduce --max-results from 25 to 10 for faster per-page queries (more requests, but each request <2s)
- Query regions in parallel (requires shell job control or Python subprocess)
- Cache discovered workspaces to avoid re-querying on subsequent runs
Pipeline · raw → V1 → V4 → CMDB¶
flowchart LR
RAW["raw csv<br/>collect-YYYY-MM-DD.csv<br/>(22 cols × 122 rows)"]
V1["V1 ingest<br/>row-level validation<br/>+ Excel cross-check"]
V4["V4 transform<br/>Jinja2 template<br/>→ ServiceNow CSDM CI"]
CMDB["CMDB publish<br/>WorkSpace CIs + relationships<br/>(HITL approves)"]
RAW --> V1 --> V4 --> CMDB
Acceptance Criteria (workspaces.md quality contract)¶
| AC | Threshold | Verify |
|---|---|---|
| AC1 | line count ≤ 620 | wc -l workspaces.md |
| AC2 | last_updated < 90 days | footer date |
| AC3 | 7-account-name table present | grep -c "vams-au-\\|vams-nz-" workspaces.md ≥ 7 |
| AC4 | Both AUTO-SYNC blocks present | grep -c "AUTO-SYNC:BEGIN" workspaces.md ≥ 2 |
| AC5 | Zero literal 12-digit account IDs | grep -oE "[0-9]{12}" workspaces.md \| wc -l = 0 |
| AC6 | 22-column schema present | grep -c "decommission_total_score" workspaces.md ≥ 1 |
| AC7 | CC-ADR-016 link present | grep -c "CC-ADR-016" workspaces.md ≥ 1 |
References¶
- aws-profile-semantics.md: Profile role semantics (BILLING, MANAGEMENT, OPERATIONS, per-workload)
- CC-ADR-016: Workspaces multi-account discovery pattern decision record
- operational-efficiency.md: Rule 9 (Cross-account zero-result validation)
- AWS WorkSpaces API: https://docs.aws.amazon.com/workspaces/latest/api/API_DescribeWorkspaces.html
- AWS Resource Explorer: https://docs.aws.amazon.com/resource-explorer/latest/userguide/manage-indexes.html
Components Used (ADLC 5W1H)¶
| Component | Type | Why | What if missing | Business value | Purpose | Critical thinking |
|---|---|---|---|---|---|---|
runbooks workspaces collect |
CLI command | Canonical multi-account WorkSpaces inventory | A2 reverts to brittle hand-rolled bash; drift risk | Reproducible 122-row baseline in <60s | Org-wide discovery via Organizations list_accounts + per-workload describe_workspaces |
Why not Resource Explorer? — RE samples + indexes; collect is authoritative API |
${AWS_MANAGEMENT_PROFILE} |
Env profile | Org-root identity for Organizations API | A2 cannot enumerate workload accounts (silent zero results) | 7-account fan-out without account-ID hardcoding | Profile-as-pre-authorization (Principle I) | Why not OPERATIONS? — OPS is centralised-ops (1 acct); MGT is org-root (N accts) — see CC-ADR-016 |
--account-ids flag |
CLI option | Targeted account subset for incident triage | Forced full-org scan slows triage 5-10× | <10s targeted vs ~60s full-org | Override list_accounts for known scope |
Why comma-separated, not file? — KISS for CLI ergonomics; pipe xargs for bulk |
validate-bash.sh |
Hook | Blocks AWS mutation verbs at PreToolUse | Agent could terminate-workspaces autonomously |
Principle I enforcement at tool-call level | Deny list for create/delete/modify/terminate | Why hook, not rule? — hooks are deterministic; rules are advisory |
cost-optimization skill (W1-W6) |
Skill | WorkSpaces decommission signal scoring | Decommission decisions lack quantified evidence | $/month savings attribution per WorkSpace | w1_score + w2_score columns feed dashboard |
Why W1-W6 not generic? — domain-specific signals are auditable |
mcp-validation skill |
Skill | ≥99.5% cross-source accuracy gate | Single-source claims lack audit trail | 4-way validation (V1 file · V2 API · V3 CLI · V4 visual) | Quality gate before HITL handoff | Why ≥99.5% not 100%? — empirical floor: API rate-limit causes ~0.5% transient drift |
aws-profile-semantics.md rule |
Rule | Codified MGT vs OPS vs BILLING boundaries | Profile drift = wrong-account queries | Prevents CROSS_ACCOUNT_SILENT_ZERO anti-pattern |
Authoritative semantics, single source | Why rule not memory? — rule is git-tracked + team-shared |
CC-ADR-016 |
ADR | Documents A1+A2 hybrid pattern | Future refactors lose the why | Architectural rationale survives author churn | Decision record (immutable, dated) | Why ADR not comment? — comments rot; ADRs persist |
nnthanh101/runbooks:prod Docker image |
Container | Reproducible CLI runtime | HOST_PACKAGE_MANAGER anti-pattern triggers |
Same image → same results across HITL machines | Locked Python 3.13 + uv + boto3 versions | Why not host pip install? — host drift; see PreToolUse hooks |
| Resource Explorer (Excel baseline) | Cross-val source | V1 ground truth for org-wide queries | V1-V2 cross-val falls back to single-source | Excel/RE provides drift detector | Validates collect.csv row count |
Why xlsx not API? — HITL holds the signed export; API view drifts every refresh |
Last updated: 2026-05-21 · scope_id: WORKSPACES-PDCA-SCORING-V1-REMEDIATION