acumatica-cli 0.34.0__tar.gz → 0.36.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/PKG-INFO +89 -66
  2. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/README.md +88 -65
  3. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/pyproject.toml +1 -1
  4. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/pyproject.toml.orig +1 -1
  5. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap.py +17 -18
  6. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/cli.py +417 -277
  7. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/client.py +206 -20
  8. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/config.py +130 -75
  9. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/extract.py +22 -19
  10. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/output.py +21 -1
  11. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/reconcile.py +0 -2
  12. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/run.py +101 -20
  13. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/seed.py +380 -87
  14. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/seed_catalog.yaml +49 -49
  15. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/state.py +29 -3
  16. acumatica_cli-0.36.0/src/acumatica_cli/templates/README.md +60 -0
  17. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/overlays/README.md +13 -21
  18. acumatica_cli-0.36.0/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +17 -0
  19. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/tenant.py +99 -13
  20. acumatica_cli-0.34.0/src/acumatica_cli/templates/README.md +0 -62
  21. acumatica_cli-0.34.0/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +0 -12
  22. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/__init__.py +0 -0
  23. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
  24. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap_project.xml +0 -0
  25. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/firstlogin.py +0 -0
  26. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/inventory.py +0 -0
  27. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/models.py +0 -0
  28. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
  29. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/10-subaccounts.yaml +0 -0
  30. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/20-accounts.yaml +0 -0
  31. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/40-ledger.yaml +0 -0
  32. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/50-gl-preferences.yaml +0 -0
  33. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/60-ledger-company.yaml +0 -0
  34. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/90-uoms.yaml +0 -0
  35. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/91-company-packaging.yaml +0 -0
  36. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/company.yaml +0 -0
  37. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/credit-terms.yaml +0 -0
  38. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/features.yaml +0 -0
  39. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/segmented-key.yaml +0 -0
  40. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/05-numbering-sequences.yaml +0 -0
  41. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/10-reason-codes.yaml +0 -0
  42. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/20-in-preferences.yaml +0 -0
  43. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/30-availability-rules.yaml +0 -0
  44. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/40-posting-classes.yaml +0 -0
  45. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/50-warehouse.yaml +0 -0
  46. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/51-warehouse-locations.yaml +0 -0
  47. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/52-warehouse-defaults.yaml +0 -0
  48. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/53-tax-categories.yaml +0 -0
  49. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/54-item-classes.yaml +0 -0
  50. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/56-so-preferences.yaml +0 -0
  51. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/57-po-preferences.yaml +0 -0
  52. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/58-order-types.yaml +0 -0
  53. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/60-ar-preferences.yaml +0 -0
  54. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/61-ap-preferences.yaml +0 -0
  55. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/62-ca-preferences.yaml +0 -0
  56. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/63-cash-account.yaml +0 -0
  57. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/64-payment-methods.yaml +0 -0
  58. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/65-statement-cycles.yaml +0 -0
  59. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/70-vendor-classes.yaml +0 -0
  60. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/71-customer-classes.yaml +0 -0
  61. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/75-vendors.yaml +0 -0
  62. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/76-customers.yaml +0 -0
  63. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/80-stock-items-parts.yaml +0 -0
  64. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/82-stock-items-kits.yaml +0 -0
  65. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/85-kit-specifications.yaml +0 -0
  66. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/90-roles.yaml +0 -0
  67. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/91-users.yaml +0 -0
  68. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/92-role-users.yaml +0 -0
  69. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/10-financial-year.yaml +0 -0
  70. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/20-master-calendar.yaml +0 -0
  71. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/30-open-periods.yaml +0 -0
  72. {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/views/10-trial-balance.yaml +0 -0
  73. {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/10-seed-capital.yaml +0 -0
  74. {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/20-buy.yaml +0 -0
  75. {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/30-build.yaml +0 -0
  76. {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/40-sell.yaml +0 -0
  77. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/env +0 -0
  78. {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/gitignore +0 -0
  79. {acumatica_cli-0.34.0/src/acumatica_cli/templates/overlays/default-24.200.001/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/overlays/default-24.200.001/acu-scenario}/30-build.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: acumatica-cli
3
- Version: 0.34.0
3
+ Version: 0.36.0
4
4
  Summary: Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data
5
5
  Author: Konstantin Borovik
6
6
  Author-email: Konstantin Borovik <kb@lab5.ca>
@@ -38,18 +38,18 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
38
38
 
39
39
  | You can | Command | Effect |
40
40
  | ------- | ------- | ------ |
41
- | Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
41
+ | Seed a tenant from YAML | `apply` | Idempotent PUT of `acu-config/` into the live tenant |
42
42
  | Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
43
- | Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
44
- | Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
43
+ | Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `acu-config/{bootstrap,baseline,setup,master}/` |
44
+ | Run transaction scripts | `run` | Forward documents from `acu-scenario/` (capital, buy, build, sell) |
45
45
  | Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
46
46
  | Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
47
47
  | Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
48
48
  | Prove a cold rebuild | `tenant create` then `apply` then `run` then `diff` | Compose on a fresh tenant. No wrap command. |
49
49
  | Snapshot a site offline | `survey inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
50
- | Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
50
+ | Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `--config` writes `findings/` only |
51
51
  | Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
52
- | Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
52
+ | Scaffold a data repo | `config init` | Full `acu-config/`, `acu-scenario/`, `.env` tree |
53
53
  | Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
54
54
 
55
55
  Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
@@ -72,13 +72,13 @@ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
72
72
  acu config check # read-only preflight
73
73
  acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
74
74
  # or hosted: acu --tenant DEV bootstrap
75
- acu --tenant DEV apply config/ # seed config/{bootstrap,baseline,setup,master}/
76
- acu --tenant DEV run scenario/ # once capital → buy → build → sell
77
- acu --tenant DEV diff config/ # prove zero drift (exit 2 on drift)
78
- acu --tenant DEV state # capture state/ trial-balance
75
+ acu --tenant DEV apply acu-config # seed acu-config/{bootstrap,baseline,setup,master}/
76
+ acu --tenant DEV run acu-scenario # once capital → buy → build → sell
77
+ acu --tenant DEV diff acu-config # prove zero drift (exit 2 on drift)
78
+ acu --tenant DEV state acu-config/views # capture state/ trial-balance
79
79
  ```
80
80
 
81
- Bare `apply` / `diff` (no path args) also prefer `config/` when those trees exist.
81
+ apply / diff / run / state require an explicit data path.
82
82
 
83
83
  **Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
84
84
  The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
@@ -88,8 +88,8 @@ acu config init --host customer.acumatica.com my-erp
88
88
  cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
89
89
  acu config check # REST preflight; ssh probe is skipped
90
90
  acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
91
- acu --tenant DEV apply config/
92
- acu --tenant DEV diff config/
91
+ acu --tenant DEV apply acu-config
92
+ acu --tenant DEV diff acu-config
93
93
  # offline UI fallback when REST publish is blocked:
94
94
  acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
95
95
  ```
@@ -110,43 +110,41 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
110
110
  │ └── recycle [--yes] restart site app pool (tenant map + free API slots)
111
111
  │
112
112
  ├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
113
- ├── apply [--dry-run] [FILES...] push YAML via REST (idempotent PUT upserts)
114
- ├── diff [FILES...] drift check vs the live tenant (exit 2 on drift)
115
- ├── run [--dry-run] [FILES...] execute transaction scenario YAML (exit 1 on any miss)
116
- ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] [FILES...]
113
+ ├── apply [--dry-run] <FILES...> push YAML via REST (idempotent PUT upserts)
114
+ ├── diff <FILES...> drift check vs the live tenant (exit 2 on drift)
115
+ ├── run [--dry-run] <FILES...> execute transaction scenario YAML (exit 1 on any miss)
116
+ ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] <FILES...>
117
117
  │ capture derived state into state/ (not seed)
118
118
  ├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
119
119
  │ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
120
- │ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
120
+ │ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
121
121
  │ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
122
122
  │ │ offline snapshot artifact → inventory/ (not seed)
123
123
  │ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
124
- │ inventory/ + optional config/ → findings/ only
124
+ │ inventory/ + optional --config DIR → findings/ only
125
125
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
126
126
  │
127
127
  └── config configuration ops
128
- ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
128
+ ├── init [--host HOST] [DIR] scaffold full data repo (acu-config/, acu-scenario/, .env)
129
129
  ├── show print the resolved config as a complete .env
130
130
  └── check preflight: discovery, secrets, REST, endpoints, SSH
131
131
  ```
132
132
 
133
- When you omit FILES:
133
+ `apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
134
134
 
135
- - `apply` / `diff` prefer `config/<name>/` if any seed child exists under `config/`.
136
- Otherwise they walk root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
137
- A path like `config/` expands those nested seed dirs in the same order.
138
- - `run` defaults to `scenario/`.
139
- - `state` defaults to `config/views/`; writes go to `state/` (`--out`).
135
+ A dir with SEED_DIRS children (`bootstrap|baseline|setup|master`) expands those subdirs in that order. Typed path is used as given (`acu apply acu-config`, or `acu apply config/` if that dir exists).
136
+
137
+ `--out` defaults: `state` → `state/`; `survey extract` → `acu-config/` (SEED_DIRS into that root); `survey inventory` → `inventory/`; `survey reconcile` → `findings/`; `schema` → `schemas/`.
140
138
 
141
139
  Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
142
- `config/views` and `state` keep Period pinned.
140
+ `acu-config/views` and `state` keep Period pinned.
143
141
 
144
- `survey extract` always writes under `config/{bootstrap,baseline,setup,master}/` (catalog-driven; never root SEED_DIRS).
142
+ `survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
145
143
 
146
144
  `survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
147
145
  `survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
148
146
 
149
- `survey reconcile` compares `inventory/` to optional `config/` and writes `findings/` only.
147
+ `survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
150
148
  It never writes seed.
151
149
 
152
150
  Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
@@ -166,19 +164,52 @@ Do not confuse them with each other or with `state`:
166
164
 
167
165
  | Command | Plane | Input | Writes | Role |
168
166
  | ------- | ----- | ----- | ------ | ---- |
169
- | `survey extract` | REST (live) | tenant via contract API | `config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
167
+ | `survey extract` | REST (live) | tenant via contract API | `acu-config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
170
168
  | `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
171
- | `survey reconcile` | Offline | `inventory/` + optional `config/` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
172
- | `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
173
- | `apply` | REST (live) | seed YAML under `config/` | tenant | **Sole** tenant writer (keyed PUT) |
169
+ | `survey reconcile` | Offline | `inventory/` + optional `--config DIR` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
170
+ | `state` | REST (live) | `acu-config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
171
+ | `apply` | REST (live) | seed YAML under `acu-config/` | tenant | **Sole** tenant writer (keyed PUT) |
174
172
 
175
173
  `inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
176
174
  Binary `.adb` snapshots are rejected (XML only).
177
175
 
176
+ ### Machine-readable output (`--output json`)
177
+
178
+ `acu --output json <diff|apply|run|state> ...` prints one JSON document on stdout; progress and result lines move to stderr.
179
+ Exit codes do not change (`diff` still exits 2 on drift), and other commands ignore the flag.
180
+
181
+ `diff`:
182
+
183
+ ```json
184
+ {
185
+ "command": "diff", "tenant": "DEV", "base_url": "https://...", "drift": 1,
186
+ "files": [{
187
+ "file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
188
+ "records": 2,
189
+ "drifts": [{
190
+ "file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
191
+ "keys": {"UOM": "KG"}, "field": "Description", "kind": "changed",
192
+ "source": "Kilogram", "live": "kg",
193
+ "text": "UnitsOfMeasure [KG].Description: source='Kilogram' live='kg'"
194
+ }]
195
+ }]
196
+ }
197
+ ```
198
+
199
+ - `kind`: `changed`, `missing`, `extra` (detail row), `not_returned` or `not_applied` (setup action).
200
+ - `field`: path below the record (e.g. `Details[A].Qty`); `""` when the record itself is missing.
201
+ - `source` / `live`: set only for `changed`.
202
+
203
+ - `apply`: `{command, tenant, mode (all|plan|changed|dry_run), ok, failed, counts, errors, stopped, not_applied, files: [{file, entity, ok, errors}]}`; `counts` keys `create`, `update`, `unchanged`, `invoke`, `put`.
204
+ - `run`: `{command, tenant, counts: {passed, failed, skipped, not_run}, scenarios: [{file, outcome, misses, error?}], not_run}`; `misses` = failed expectation lines.
205
+ - `state`: `{command, tenant, mode (write|diff|assert), exit, changed, views: [{view, file, rows, status (wrote|changed|unchanged), differences}]}`.
206
+
178
207
  ## The data repo
179
208
 
180
209
  Your configuration lives in its own git repo.
181
- `acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
210
+ `acu config init` scaffolds a **single full seed** under `acu-config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `acu-scenario/`, observer `acu-config/views/`, and README.
211
+
212
+ It does not write a customization tree.
182
213
 
183
214
  The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
184
215
  `config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
@@ -187,38 +218,36 @@ There is no `--flavor`.
187
218
 
188
219
  | Path | What it holds |
189
220
  | ---- | ------------- |
190
- | `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
191
- | `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
192
- | `config/setup/` | one-time actions: financial year, master calendar, open periods |
193
- | `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
194
- | `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
195
- | `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
221
+ | `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
222
+ | `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
223
+ | `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
224
+ | `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
225
+ | `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
226
+ | `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
196
227
  | `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
197
228
  | `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
198
229
  | `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
199
230
  | `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
200
231
 
201
- Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
202
-
203
232
  Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
204
233
  Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
205
234
 
206
235
  Seed YAML is state: `apply` upserts it, `diff` proves it.
207
- `acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
236
+ `acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
208
237
 
209
238
  Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
210
239
 
211
- Features synthesize to `config/bootstrap/features.yaml`.
240
+ Features synthesize to `acu-config/bootstrap/features.yaml`.
212
241
  Existing files skip unless `--force`; empty live sets skip.
213
242
 
214
243
  Row failures continue (exit 1 only if any row failed).
215
244
  Drift stays with `diff`.
216
245
 
217
246
  ```sh
218
- acu --tenant DEV survey extract --out . --force # refresh config/** from live tenant
219
- git diff config/ # review extract delta before commit
220
- acu --tenant DEV apply config/ # replay extracted seed
221
- acu --tenant DEV diff config/ # expect exit 0
247
+ acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
248
+ git diff acu-config/ # review extract delta before commit
249
+ acu --tenant DEV apply acu-config # replay extracted seed
250
+ acu --tenant DEV diff acu-config # expect exit 0
222
251
  ```
223
252
  ### Seed `endpoint:` symbols
224
253
 
@@ -286,7 +315,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
286
315
 
287
316
  | Piece | Role |
288
317
  | ----- | ---- |
289
- | Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
318
+ | Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
290
319
  | `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
291
320
  | Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
292
321
  | OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
@@ -294,21 +323,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
294
323
  **Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
295
324
  No `--overlay` flag.
296
325
 
297
- **Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
298
- `acu run` replaces same-basename scenario files from the pin overlay.
326
+ Pass overlay trees as extra explicit paths when you need them.
299
327
 
300
328
  Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
301
- Explicit path args disable auto-compose.
302
329
 
303
330
  ```sh
304
- # ACU_API_VERSION=24.200.001 → uses overlays/default-24.200.001/
305
- acu apply
306
- acu run
307
- acu diff
308
-
309
- # explicit path args (no auto) — later path wins same keys
310
- acu apply config/ overlays/default-24.200.001/
311
- acu diff config/ overlays/default-24.200.001/
331
+ # ACU_API_VERSION=24.200.001 — this overlay is scenario-only
332
+ acu apply acu-config
333
+ acu diff acu-config
334
+ acu run acu-scenario overlays/default-24.200.001/acu-scenario/
312
335
  ```
313
336
 
314
337
  Add a future half by creating `overlays/default-<new-half>/` with the
@@ -391,7 +414,7 @@ Per-bug contract probes fold onto those tenants.
391
414
  Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
392
415
 
393
416
  Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
394
- The packaged full `config init` seed (under `config/`) is the only scaffold.
417
+ The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
395
418
 
396
419
  ```sh
397
420
  gmake e2e # whole tier, three files
@@ -402,7 +425,7 @@ gmake e2e FILE=test_extract_roundtrip # extract inverse
402
425
 
403
426
  ### CLI test-seed soak
404
427
 
405
- This checkout carries a CLI test seed at repo-root `config/` and `scenario/` (no `config/qms/`).
428
+ This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
406
429
  Soak the live CLI tenant from here with `--tenant ACUCLI`.
407
430
 
408
431
  Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
@@ -411,10 +434,10 @@ Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
411
434
  That path is not the soak.
412
435
 
413
436
  ```sh
414
- uv run acu --tenant ACUCLI apply
415
- uv run acu --tenant ACUCLI run
416
- uv run acu --tenant ACUCLI diff
417
- uv run acu --tenant ACUCLI state
437
+ uv run acu --tenant ACUCLI apply acu-config
438
+ uv run acu --tenant ACUCLI run acu-scenario
439
+ uv run acu --tenant ACUCLI diff acu-config
440
+ uv run acu --tenant ACUCLI state acu-config/views
418
441
  ```
419
442
 
420
443
  ## License
@@ -20,18 +20,18 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
20
20
 
21
21
  | You can | Command | Effect |
22
22
  | ------- | ------- | ------ |
23
- | Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
23
+ | Seed a tenant from YAML | `apply` | Idempotent PUT of `acu-config/` into the live tenant |
24
24
  | Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
25
- | Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
26
- | Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
25
+ | Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `acu-config/{bootstrap,baseline,setup,master}/` |
26
+ | Run transaction scripts | `run` | Forward documents from `acu-scenario/` (capital, buy, build, sell) |
27
27
  | Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
28
28
  | Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
29
29
  | Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
30
30
  | Prove a cold rebuild | `tenant create` then `apply` then `run` then `diff` | Compose on a fresh tenant. No wrap command. |
31
31
  | Snapshot a site offline | `survey inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
32
- | Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `config/` writes `findings/` only |
32
+ | Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `--config` writes `findings/` only |
33
33
  | Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
34
- | Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
34
+ | Scaffold a data repo | `config init` | Full `acu-config/`, `acu-scenario/`, `.env` tree |
35
35
  | Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
36
36
 
37
37
  Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
@@ -54,13 +54,13 @@ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
54
54
  acu config check # read-only preflight
55
55
  acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
56
56
  # or hosted: acu --tenant DEV bootstrap
57
- acu --tenant DEV apply config/ # seed config/{bootstrap,baseline,setup,master}/
58
- acu --tenant DEV run scenario/ # once capital → buy → build → sell
59
- acu --tenant DEV diff config/ # prove zero drift (exit 2 on drift)
60
- acu --tenant DEV state # capture state/ trial-balance
57
+ acu --tenant DEV apply acu-config # seed acu-config/{bootstrap,baseline,setup,master}/
58
+ acu --tenant DEV run acu-scenario # once capital → buy → build → sell
59
+ acu --tenant DEV diff acu-config # prove zero drift (exit 2 on drift)
60
+ acu --tenant DEV state acu-config/views # capture state/ trial-balance
61
61
  ```
62
62
 
63
- Bare `apply` / `diff` (no path args) also prefer `config/` when those trees exist.
63
+ apply / diff / run / state require an explicit data path.
64
64
 
65
65
  **Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
66
66
  The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
@@ -70,8 +70,8 @@ acu config init --host customer.acumatica.com my-erp
70
70
  cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
71
71
  acu config check # REST preflight; ssh probe is skipped
72
72
  acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
73
- acu --tenant DEV apply config/
74
- acu --tenant DEV diff config/
73
+ acu --tenant DEV apply acu-config
74
+ acu --tenant DEV diff acu-config
75
75
  # offline UI fallback when REST publish is blocked:
76
76
  acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
77
77
  ```
@@ -92,43 +92,41 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
92
92
  │ └── recycle [--yes] restart site app pool (tenant map + free API slots)
93
93
  │
94
94
  ├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
95
- ├── apply [--dry-run] [FILES...] push YAML via REST (idempotent PUT upserts)
96
- ├── diff [FILES...] drift check vs the live tenant (exit 2 on drift)
97
- ├── run [--dry-run] [FILES...] execute transaction scenario YAML (exit 1 on any miss)
98
- ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] [FILES...]
95
+ ├── apply [--dry-run] <FILES...> push YAML via REST (idempotent PUT upserts)
96
+ ├── diff <FILES...> drift check vs the live tenant (exit 2 on drift)
97
+ ├── run [--dry-run] <FILES...> execute transaction scenario YAML (exit 1 on any miss)
98
+ ├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] <FILES...>
99
99
  │ capture derived state into state/ (not seed)
100
100
  ├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
101
101
  │ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
102
- │ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
102
+ │ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
103
103
  │ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
104
104
  │ │ offline snapshot artifact → inventory/ (not seed)
105
105
  │ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
106
- │ inventory/ + optional config/ → findings/ only
106
+ │ inventory/ + optional --config DIR → findings/ only
107
107
  ├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
108
108
  │
109
109
  └── config configuration ops
110
- ├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
110
+ ├── init [--host HOST] [DIR] scaffold full data repo (acu-config/, acu-scenario/, .env)
111
111
  ├── show print the resolved config as a complete .env
112
112
  └── check preflight: discovery, secrets, REST, endpoints, SSH
113
113
  ```
114
114
 
115
- When you omit FILES:
115
+ `apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
116
116
 
117
- - `apply` / `diff` prefer `config/<name>/` if any seed child exists under `config/`.
118
- Otherwise they walk root `bootstrap/`, `baseline/`, `setup/`, then `master/` when present.
119
- A path like `config/` expands those nested seed dirs in the same order.
120
- - `run` defaults to `scenario/`.
121
- - `state` defaults to `config/views/`; writes go to `state/` (`--out`).
117
+ A dir with SEED_DIRS children (`bootstrap|baseline|setup|master`) expands those subdirs in that order. Typed path is used as given (`acu apply acu-config`, or `acu apply config/` if that dir exists).
118
+
119
+ `--out` defaults: `state` → `state/`; `survey extract` → `acu-config/` (SEED_DIRS into that root); `survey inventory` → `inventory/`; `survey reconcile` → `findings/`; `schema` → `schemas/`.
122
120
 
123
121
  Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
124
- `config/views` and `state` keep Period pinned.
122
+ `acu-config/views` and `state` keep Period pinned.
125
123
 
126
- `survey extract` always writes under `config/{bootstrap,baseline,setup,master}/` (catalog-driven; never root SEED_DIRS).
124
+ `survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
127
125
 
128
126
  `survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
129
127
  `survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
130
128
 
131
- `survey reconcile` compares `inventory/` to optional `config/` and writes `findings/` only.
129
+ `survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
132
130
  It never writes seed.
133
131
 
134
132
  Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
@@ -148,19 +146,52 @@ Do not confuse them with each other or with `state`:
148
146
 
149
147
  | Command | Plane | Input | Writes | Role |
150
148
  | ------- | ----- | ----- | ------ | ---- |
151
- | `survey extract` | REST (live) | tenant via contract API | `config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
149
+ | `survey extract` | REST (live) | tenant via contract API | `acu-config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
152
150
  | `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
153
- | `survey reconcile` | Offline | `inventory/` + optional `config/` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
154
- | `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
155
- | `apply` | REST (live) | seed YAML under `config/` | tenant | **Sole** tenant writer (keyed PUT) |
151
+ | `survey reconcile` | Offline | `inventory/` + optional `--config DIR` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
152
+ | `state` | REST (live) | `acu-config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
153
+ | `apply` | REST (live) | seed YAML under `acu-config/` | tenant | **Sole** tenant writer (keyed PUT) |
156
154
 
157
155
  `inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
158
156
  Binary `.adb` snapshots are rejected (XML only).
159
157
 
158
+ ### Machine-readable output (`--output json`)
159
+
160
+ `acu --output json <diff|apply|run|state> ...` prints one JSON document on stdout; progress and result lines move to stderr.
161
+ Exit codes do not change (`diff` still exits 2 on drift), and other commands ignore the flag.
162
+
163
+ `diff`:
164
+
165
+ ```json
166
+ {
167
+ "command": "diff", "tenant": "DEV", "base_url": "https://...", "drift": 1,
168
+ "files": [{
169
+ "file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
170
+ "records": 2,
171
+ "drifts": [{
172
+ "file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
173
+ "keys": {"UOM": "KG"}, "field": "Description", "kind": "changed",
174
+ "source": "Kilogram", "live": "kg",
175
+ "text": "UnitsOfMeasure [KG].Description: source='Kilogram' live='kg'"
176
+ }]
177
+ }]
178
+ }
179
+ ```
180
+
181
+ - `kind`: `changed`, `missing`, `extra` (detail row), `not_returned` or `not_applied` (setup action).
182
+ - `field`: path below the record (e.g. `Details[A].Qty`); `""` when the record itself is missing.
183
+ - `source` / `live`: set only for `changed`.
184
+
185
+ - `apply`: `{command, tenant, mode (all|plan|changed|dry_run), ok, failed, counts, errors, stopped, not_applied, files: [{file, entity, ok, errors}]}`; `counts` keys `create`, `update`, `unchanged`, `invoke`, `put`.
186
+ - `run`: `{command, tenant, counts: {passed, failed, skipped, not_run}, scenarios: [{file, outcome, misses, error?}], not_run}`; `misses` = failed expectation lines.
187
+ - `state`: `{command, tenant, mode (write|diff|assert), exit, changed, views: [{view, file, rows, status (wrote|changed|unchanged), differences}]}`.
188
+
160
189
  ## The data repo
161
190
 
162
191
  Your configuration lives in its own git repo.
163
- `acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
192
+ `acu config init` scaffolds a **single full seed** under `acu-config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `acu-scenario/`, observer `acu-config/views/`, and README.
193
+
194
+ It does not write a customization tree.
164
195
 
165
196
  The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
166
197
  `config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
@@ -169,38 +200,36 @@ There is no `--flavor`.
169
200
 
170
201
  | Path | What it holds |
171
202
  | ---- | ------------- |
172
- | `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
173
- | `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
174
- | `config/setup/` | one-time actions: financial year, master calendar, open periods |
175
- | `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
176
- | `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
177
- | `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
203
+ | `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
204
+ | `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
205
+ | `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
206
+ | `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
207
+ | `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
208
+ | `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
178
209
  | `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
179
210
  | `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
180
211
  | `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
181
212
  | `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
182
213
 
183
- Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
184
-
185
214
  Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
186
215
  Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
187
216
 
188
217
  Seed YAML is state: `apply` upserts it, `diff` proves it.
189
- `acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
218
+ `acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
190
219
 
191
220
  Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
192
221
 
193
- Features synthesize to `config/bootstrap/features.yaml`.
222
+ Features synthesize to `acu-config/bootstrap/features.yaml`.
194
223
  Existing files skip unless `--force`; empty live sets skip.
195
224
 
196
225
  Row failures continue (exit 1 only if any row failed).
197
226
  Drift stays with `diff`.
198
227
 
199
228
  ```sh
200
- acu --tenant DEV survey extract --out . --force # refresh config/** from live tenant
201
- git diff config/ # review extract delta before commit
202
- acu --tenant DEV apply config/ # replay extracted seed
203
- acu --tenant DEV diff config/ # expect exit 0
229
+ acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
230
+ git diff acu-config/ # review extract delta before commit
231
+ acu --tenant DEV apply acu-config # replay extracted seed
232
+ acu --tenant DEV diff acu-config # expect exit 0
204
233
  ```
205
234
  ### Seed `endpoint:` symbols
206
235
 
@@ -268,7 +297,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
268
297
 
269
298
  | Piece | Role |
270
299
  | ----- | ---- |
271
- | Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
300
+ | Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
272
301
  | `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
273
302
  | Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
274
303
  | OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
@@ -276,21 +305,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
276
305
  **Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
277
306
  No `--overlay` flag.
278
307
 
279
- **Bare compose (pin auto):** when path args are omitted, `acu apply` / `acu diff` append overlay config seed dirs when present.
280
- `acu run` replaces same-basename scenario files from the pin overlay.
308
+ Pass overlay trees as extra explicit paths when you need them.
281
309
 
282
310
  Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
283
- Explicit path args disable auto-compose.
284
311
 
285
312
  ```sh
286
- # ACU_API_VERSION=24.200.001 → uses overlays/default-24.200.001/
287
- acu apply
288
- acu run
289
- acu diff
290
-
291
- # explicit path args (no auto) — later path wins same keys
292
- acu apply config/ overlays/default-24.200.001/
293
- acu diff config/ overlays/default-24.200.001/
313
+ # ACU_API_VERSION=24.200.001 — this overlay is scenario-only
314
+ acu apply acu-config
315
+ acu diff acu-config
316
+ acu run acu-scenario overlays/default-24.200.001/acu-scenario/
294
317
  ```
295
318
 
296
319
  Add a future half by creating `overlays/default-<new-half>/` with the
@@ -373,7 +396,7 @@ Per-bug contract probes fold onto those tenants.
373
396
  Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
374
397
 
375
398
  Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
376
- The packaged full `config init` seed (under `config/`) is the only scaffold.
399
+ The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
377
400
 
378
401
  ```sh
379
402
  gmake e2e # whole tier, three files
@@ -384,7 +407,7 @@ gmake e2e FILE=test_extract_roundtrip # extract inverse
384
407
 
385
408
  ### CLI test-seed soak
386
409
 
387
- This checkout carries a CLI test seed at repo-root `config/` and `scenario/` (no `config/qms/`).
410
+ This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
388
411
  Soak the live CLI tenant from here with `--tenant ACUCLI`.
389
412
 
390
413
  Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
@@ -393,10 +416,10 @@ Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
393
416
  That path is not the soak.
394
417
 
395
418
  ```sh
396
- uv run acu --tenant ACUCLI apply
397
- uv run acu --tenant ACUCLI run
398
- uv run acu --tenant ACUCLI diff
399
- uv run acu --tenant ACUCLI state
419
+ uv run acu --tenant ACUCLI apply acu-config
420
+ uv run acu --tenant ACUCLI run acu-scenario
421
+ uv run acu --tenant ACUCLI diff acu-config
422
+ uv run acu --tenant ACUCLI state acu-config/views
400
423
  ```
401
424
 
402
425
  ## License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acumatica-cli"
3
- version = "0.34.0"
3
+ version = "0.36.0"
4
4
  description = "Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data"
5
5
  license = "PolyForm-Noncommercial-1.0.0"
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "acumatica-cli"
3
- version = "0.34.0"
3
+ version = "0.36.0"
4
4
  description = "Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data"
5
5
  authors = [{ name = "Konstantin Borovik", email = "kb@lab5.ca" }]
6
6
  license = "PolyForm-Noncommercial-1.0.0"