@wpmoo/toolkit 0.9.28 → 0.9.30

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.
@@ -11,13 +11,11 @@ Ready:
11
11
  - Generated environments use local `./moo` for daily commands.
12
12
  - Direct commands cover create, status, doctor, source, repository, module,
13
13
  service, database, snapshot, restore, lint, and POT workflows.
14
- - Deprecated package aliases remain compatibility paths:
14
+ - Compatibility aliases remain available through the 1.x line:
15
15
  `npx @wpmoo/odoo` and `npx @wpmoo/odoo-dev`.
16
-
17
- Remaining decision:
18
-
19
- - Whether the optional unscoped `npx wpmoo` short alias should be promoted,
20
- kept best-effort, or removed from public examples before `1.0.0`.
16
+ - The optional unscoped `npx wpmoo` short alias remains best-effort and
17
+ warning-only. User-facing examples may mention it as optional, but
18
+ documentation, scripts, and automation should use `npx @wpmoo/toolkit`.
21
19
 
22
20
  ## Stable JSON Contracts
23
21
 
@@ -29,11 +27,10 @@ Ready:
29
27
  - `doctor --json --postgres` exposes a versioned `postgres` payload with
30
28
  `contractVersion` and diagnostics `schemaVersion`.
31
29
  - PostgreSQL diagnostics treat unavailable optional metrics as optional fields.
32
-
33
- Remaining decision:
34
-
35
- - Document a compatibility policy for future JSON schema changes, including
36
- whether minor additive fields are allowed without a major release.
30
+ - Post-1.0 JSON contracts allow additive optional fields in minor and patch
31
+ releases.
32
+ - Automation should ignore unknown JSON fields.
33
+ - Breaking JSON changes require a major release or a schemaVersion bump.
37
34
 
38
35
  ## Deprecated Alias Policy
39
36
 
@@ -44,11 +41,9 @@ Ready:
44
41
  releases.
45
42
  - The optional `wpmoo` short alias is warning-only and does not determine
46
43
  release validity.
47
-
48
- Remaining decision:
49
-
50
- - Set an explicit deprecation horizon for compatibility aliases after `1.0.0`,
51
- or commit to maintaining them indefinitely.
44
+ - Compatibility aliases remain available through the 1.x line.
45
+ - Removing a compatibility alias requires a future major release and prior
46
+ notice.
52
47
 
53
48
  ## Generated File Compatibility
54
49
 
@@ -61,11 +56,10 @@ Ready:
61
56
  - PostgreSQL 18 mount compatibility is documented and doctor can apply safe
62
57
  mount-target fixes.
63
58
  - Generated `./moo` delegates daily commands and keeps local guard behavior.
64
-
65
- Remaining decision:
66
-
67
- - Define a generated-file migration policy for environments created by older
68
- pre-1.0 releases.
59
+ - Generated environments created by pre-1.0 releases are supported through safe
60
+ reset and doctor-guided generated-file migration checks.
61
+ - Generated-file migration support must preserve product source repositories,
62
+ `.env` files, database dumps, and Docker volumes.
69
63
 
70
64
  ## Stage And Production Policy
71
65
 
@@ -79,11 +73,9 @@ Ready:
79
73
  - `restore-snapshot --dry-run`, `doctor`, and `doctor --postgres` remain safe
80
74
  preview/read-only paths.
81
75
  - Migration-risk lifecycle commands can require `WPMOO_ALLOW_MIGRATIONS=1`.
82
-
83
- Remaining decision:
84
-
85
- - Decide whether stage/prod approvals should gain a timestamped confirmation
86
- file or continue to rely on environment variables only.
76
+ - Environment-variable approvals remain supported through 1.x.
77
+ - `.wpmoo/approvals.jsonl` adds time-bounded local approvals as an additive
78
+ safety layer, not as a replacement for env flags in 1.x.
87
79
 
88
80
  ## Release Artifact Policy
89
81
 
@@ -97,33 +89,59 @@ Ready:
97
89
  the current version already exists.
98
90
  - `npm run smoke:published -- "$VERSION"` is the preferred published package
99
91
  smoke check.
100
-
101
- Remaining decision:
102
-
103
- - Decide whether release smoke should include a generated-environment acceptance
104
- run by default for `1.0.0` tags.
92
+ - Generated-environment acceptance smoke is mandatory for a 1.0.0 release
93
+ candidate.
105
94
 
106
95
  ## Current Audit
107
96
 
108
- Last updated: 2026-05-21.
97
+ Last updated: 2026-05-22.
109
98
 
110
99
  Completed checks:
111
100
 
112
- - Full local gate for Train 8 passed on 2026-05-21:
101
+ - Full local gate through Train 19 passed on 2026-05-22:
113
102
  `npm run typecheck`, `npm test`, `npm run build`, and `git diff --check`.
114
- - Coverage passed on 2026-05-21: 72 test files, 682 tests, 92.32%
115
- statements, 87.56% branches, 96.74% functions, and 92.32% lines.
116
- - Published CLI smoke passed against `@wpmoo/toolkit@0.9.27` with `npm exec`
117
- for `wpmoo --version`, `wpmoo --help`, and `wpmoo doctor --help`.
103
+ - Coverage passed on 2026-05-22: 75 test files, 722 tests, 92.00%
104
+ statements, 87.59% branches, 96.30% functions, and 92.00% lines.
105
+ - Local release packaging passed for the 1.0 release-candidate surface with
106
+ `npm --cache /private/tmp/wpmoo-npm-cache pack --dry-run`; the package
107
+ contained 70 files and the expected `dist`, `docs/assets`, `docs/*.md`,
108
+ `README.md`, `LICENSE`, and `package.json` entries.
109
+ - Local dist CLI smoke passed for `node dist/cli.js --version`, `--help`,
110
+ `create --help`, `doctor --help`, and `status --help`.
111
+ - The generated-environment acceptance flow remains covered by
112
+ `test/smoke-published-script.test.ts`, including create, source list/sync,
113
+ safe reset preview, `doctor --fix`, snapshot, and restore dry-run steps.
118
114
  - Placeholder review found no `TODO`, `FIXME`, `TBD`, or `coming soon`
119
115
  markers in `README.md`, `docs`, or `src`.
120
116
  - Local markdown link review passed across `README.md` and `docs/*.md`.
121
-
122
- Final gap list:
123
-
124
- - Define JSON compatibility rules for post-1.0 additive fields.
125
- - Decide the long-term compatibility alias policy.
126
- - Decide generated-environment migration support for older pre-1.0 outputs.
127
- - Decide whether stage/prod approvals need timestamped confirmation files.
128
- - Decide whether generated-environment published smoke should be mandatory for
129
- `1.0.0` tags.
117
+ - Published CLI smoke previously passed against `@wpmoo/toolkit@0.9.27` with
118
+ `npm exec` for `wpmoo --version`, `wpmoo --help`, and
119
+ `wpmoo doctor --help`.
120
+
121
+ Release-candidate notes:
122
+
123
+ - Local `npm exec --package file:...` smoke against the generated tarball did
124
+ not complete in this restricted environment because package installation and
125
+ dependency resolution timed out before the CLI could run. This is not treated
126
+ as a product regression, but it prevents treating the current line as final
127
+ `1.0.0` evidence before a registry-backed smoke completes.
128
+ - The next patch release should be published as `0.9.30`. Do not tag `1.0.0`
129
+ until `WPMOO_SMOKE_ENVIRONMENT=1 npm run smoke:published -- "$VERSION"`
130
+ passes against a registry-resolved package.
131
+ - After a registry-backed generated-environment smoke passes, the remaining
132
+ 1.0 decision is procedural: bump to `1.0.0`, rerun the full gate, rerun
133
+ `npm run release:check`, tag, and verify the required scoped artifacts.
134
+
135
+ Final policy decisions:
136
+
137
+ - JSON compatibility permits additive optional fields in minor and patch
138
+ releases; breaking changes require a major release or schemaVersion bump.
139
+ - Compatibility aliases remain available through the 1.x line; removal requires
140
+ a future major release and prior notice.
141
+ - Pre-1.0 generated environments are supported through safe reset and
142
+ doctor-guided generated-file migration checks that preserve source code and
143
+ local runtime data.
144
+ - Environment-variable approvals remain supported through 1.x;
145
+ `.wpmoo/approvals.jsonl` is additive and local-only.
146
+ - Generated-environment acceptance smoke is mandatory for a `1.0.0` release
147
+ candidate.
@@ -3,7 +3,11 @@
3
3
  Use `npx @wpmoo/toolkit ...` for package/operator commands. Use `./moo ...`
4
4
  inside a generated environment for daily local commands. The deprecated
5
5
  compatibility aliases `npx @wpmoo/odoo` and `npx @wpmoo/odoo-dev` redirect to
6
- the toolkit package; new automation should use `@wpmoo/toolkit`.
6
+ the toolkit package; new automation should use `@wpmoo/toolkit`. Deprecated
7
+ compatibility aliases remain available through the 1.x line. Removing a
8
+ compatibility alias requires a future major release and prior notice. The
9
+ unscoped `npx wpmoo` short alias is optional and best-effort; scripts should use
10
+ `npx @wpmoo/toolkit`.
7
11
 
8
12
  ## Package Commands
9
13
 
@@ -38,7 +42,7 @@ Run these from the generated environment root:
38
42
  | `./moo test <module[,module]> --db <db>` | Modules -> Run tests | Yes in prod | Runs Odoo tests for modules. |
39
43
  | `./moo lint` | Modules -> Run environment lint | No | Runs configured environment lint checks. |
40
44
  | `./moo pot <module[,module]> [db] [output]` | Modules -> Generate POT | No | Generates translation template files. |
41
- | `./moo snapshot [db] [name]` | Database -> Create snapshot | No | Creates a database and filestore snapshot. |
45
+ | `./moo snapshot [--list] [db] [name]` | Database -> Create snapshot | No | Creates a database and filestore snapshot, or lists known snapshots with `--list`. |
42
46
  | `./moo restore-snapshot --dry-run <name> [db]` | Database -> Restore snapshot | Preview only | Prints a restore preview without changing data. |
43
47
  | `./moo restore-snapshot <name> [db]` | Database -> Restore snapshot | Yes | Restores database and filestore from a snapshot. |
44
48
  | `./moo resetdb [db] [module[,module]]` | Database -> Reset database | Yes | Destructive database reset. |
@@ -65,6 +69,10 @@ Current JSON contract notes:
65
69
  - `doctor --json --postgres` adds `postgres.contractVersion` and a PostgreSQL
66
70
  diagnostics object with its own `schemaVersion`.
67
71
  - PostgreSQL fields are optional when a metric is unavailable.
72
+ - Automation should ignore unknown JSON fields.
73
+ - Minor and patch releases may add optional fields without a breaking release.
74
+ - Removing, renaming, or changing the meaning of a documented field requires a
75
+ major release or a `schemaVersion` bump.
68
76
 
69
77
  ## Environment Variables
70
78
 
@@ -80,6 +88,24 @@ Current JSON contract notes:
80
88
 
81
89
  Process environment values take precedence over `.env` values for safety flags.
82
90
 
91
+ ## Approval Ledger
92
+
93
+ For time-bounded local approvals, add JSONL entries to `.wpmoo/approvals.jsonl`.
94
+ Generated `.gitignore` ignores this file, and it should not be committed.
95
+ Existing `WPMOO_ALLOW_*` flags remain supported; ledger entries are an additive
96
+ way to make short-lived intent explicit.
97
+
98
+ Each line is one JSON object:
99
+
100
+ ```json
101
+ {"scope":"stage-lifecycle","environment":"stage","command":"install","expiresAt":"2026-05-21T12:30:00.000Z","reason":"release rehearsal"}
102
+ ```
103
+
104
+ Supported `scope` values are `stage-lifecycle`, `prod-lifecycle`,
105
+ `destructive`, `no-recent-snapshot`, and `migration-risk`. `environment` must be
106
+ `stage` or `prod`. `command` is optional; omit it only for a deliberately broad
107
+ approval. Expired, malformed, or mismatched entries are ignored.
108
+
83
109
  ## Exit Behavior
84
110
 
85
111
  - Successful commands exit `0`.
@@ -107,4 +133,3 @@ Prefer read-only and dry-run commands first:
107
133
  ./moo doctor --postgres
108
134
  ./moo restore-snapshot --dry-run before-change devel
109
135
  ```
110
-
@@ -59,6 +59,11 @@ the process environment explicitly sets `WPMOO_ALLOW_PROD_LIFECYCLE=1`.
59
59
  Staging keeps these commands available for release rehearsal while still
60
60
  enforcing the destructive database guard above.
61
61
 
62
+ Generated environments also honor time-bounded local approvals from
63
+ `.wpmoo/approvals.jsonl`. Generated `.gitignore` ignores this ledger and
64
+ can approve the same scopes as the environment flags for a specific stage/prod
65
+ command until `expiresAt`.
66
+
62
67
  For PostgreSQL 18 environments (including `POSTGRES_IMAGE=postgres:18`), ensure db
63
68
  volume and tmpfs mount targets use `/var/lib/postgresql` directly:
64
69
 
@@ -80,12 +85,18 @@ database count, sessions currently running queries where `pg_stat_activity.state
80
85
  is `active`, long transactions / idle-in-transaction sessions, table health
81
86
  signals, unused index advisor signals, WAL and capacity visibility, and
82
87
  slow-query logging readiness (`log_min_duration_statement` and
83
- `pg_stat_statements` visibility). If the database is unavailable, doctor reports
84
- a warning instead of failing the whole environment check.
88
+ `pg_stat_statements` visibility). It also surfaces read-only PostgreSQL
89
+ configuration visibility for `shared_buffers`, `work_mem`,
90
+ `maintenance_work_mem`, `effective_cache_size`, and `shared_preload_libraries`.
91
+ If the database is unavailable, doctor reports a warning instead of failing the
92
+ whole environment check.
85
93
 
86
94
  `doctor --json --postgres` keeps output stable by exposing a versioned PostgreSQL
87
95
  diagnostics contract. The contract is intentionally permissive: fields are optional
88
96
  and omitted or marked unavailable when a running database does not expose them.
97
+ The broader `doctor --json` payload also includes optional `sections` entries
98
+ that group checks, warnings, and errors by generated files, compose, source
99
+ repositories, PostgreSQL, and host tools while preserving the legacy flat arrays.
89
100
 
90
101
  ## Safe reset policy
91
102
 
@@ -114,6 +125,13 @@ odoo/custom/manifests/
114
125
  Run `npx @wpmoo/toolkit reset --dry-run` before writing changes when you need to
115
126
  review the generated file refresh plan.
116
127
 
128
+ Pre-1.0 environments that still use `odoo/custom/src/<repo>` source folders are
129
+ treated as legacy private sources. `doctor` reports the migration path when
130
+ metadata is missing, and safe reset can register those folders in
131
+ `.wpmoo/odoo.json` plus `odoo/custom/manifests/sources.yaml` without deleting the
132
+ existing source folder. Module listing also reads the legacy folder while users
133
+ move it to `odoo/custom/src/private/<repo>` at their own pace.
134
+
117
135
  ## Snapshot policy
118
136
 
119
137
  Use restore preview before a destructive restore:
@@ -122,6 +140,9 @@ Use restore preview before a destructive restore:
122
140
  ./moo restore-snapshot --dry-run <snapshot-name> [db]
123
141
  ```
124
142
 
143
+ Use `./moo snapshot --list` to inspect known snapshot names, created times,
144
+ database hints, dump paths, and filestore presence before selecting one.
145
+
125
146
  `WPMOO_SNAPSHOT_RETENTION_COUNT` may be set to a positive integer to prune old
126
147
  snapshot manifests and their matching dump/filestore files after a new snapshot
127
148
  is written.
package/docs/handoff.md CHANGED
@@ -33,6 +33,10 @@ The optional `wpmoo` short alias is warning-only. If npm returns `E404` or
33
33
  otherwise rejects that alias, the release remains valid when the required
34
34
  scoped packages publish and verify correctly.
35
35
 
36
+ Smoke checks should be deterministic by always pinning the version you are
37
+ verifying, and by using one pinned package entrypoint for each artifact you
38
+ validate.
39
+
36
40
  Verify a tagged release with:
37
41
 
38
42
  ```bash
@@ -57,7 +61,23 @@ Optional short alias rule:
57
61
  Suggested smoke check:
58
62
 
59
63
  ```bash
60
- npm run smoke:published -- "$VERSION"
64
+ WPMOO_PUBLISHED_PACKAGE_SPEC="@wpmoo/toolkit@$VERSION" \
65
+ npm run smoke:published -- "$VERSION"
66
+ ```
67
+
68
+ For full release reproducibility, keep the default package cache behavior and avoid
69
+ pre-existing global `NPM_CONFIG_CACHE` state unless you intentionally reuse it.
70
+
71
+ The smoke script checks `--version`, top-level `--help`, and critical command
72
+ help output before optional generated-environment acceptance smoke.
73
+
74
+ For a 1.0.0 tag, run generated-environment acceptance smoke with
75
+ WPMOO_SMOKE_ENVIRONMENT=1. Treat the release as final only after that smoke
76
+ passes:
77
+
78
+ ```bash
79
+ WPMOO_SMOKE_ENVIRONMENT=1 WPMOO_PUBLISHED_PACKAGE_SPEC="@wpmoo/toolkit@$VERSION" \
80
+ npm run smoke:published -- "$VERSION"
61
81
  ```
62
82
 
63
83
  Current command standard:
@@ -125,6 +125,12 @@ Take a snapshot before risky changes:
125
125
  ./moo snapshot devel before-moo-test-update
126
126
  ```
127
127
 
128
+ List available snapshots before choosing one:
129
+
130
+ ```bash
131
+ ./moo snapshot --list
132
+ ```
133
+
128
134
  Preview a restore:
129
135
 
130
136
  ```bash
@@ -187,4 +193,3 @@ WPMOO_ENV=prod WPMOO_ALLOW_DESTRUCTIVE=1 ./moo restore-snapshot before-change de
187
193
 
188
194
  Do not set production flags globally in a shell profile. Prefer one-command
189
195
  environment variable prefixes so intent is visible in shell history.
190
-
@@ -151,6 +151,33 @@ Use the supported package path in automation:
151
151
  npx @wpmoo/toolkit --version
152
152
  ```
153
153
 
154
+ ## Published Smoke Is Not Reproducible
155
+
156
+ Symptoms:
157
+
158
+ - Smoke succeeds once and fails later, or output differs between runs.
159
+ - The smoke step fails on one environment but not another with the same tag.
160
+
161
+ Use an explicit package spec so each smoke run uses the same published package
162
+ artifact:
163
+
164
+ ```bash
165
+ VERSION="$(node -p "require('./package.json').version")"
166
+ WPMOO_PUBLISHED_PACKAGE_SPEC="@wpmoo/toolkit@$VERSION" \
167
+ npm run smoke:published -- "$VERSION"
168
+ ```
169
+
170
+ That script runs in temporary directories and uses a temporary npm cache when
171
+ `NPM_CONFIG_CACHE` is not already set. Set a fixed cache path only when you need
172
+ to reproduce with a shared cache.
173
+
174
+ For `1.0.0`, include generated-environment acceptance smoke:
175
+
176
+ ```bash
177
+ WPMOO_SMOKE_ENVIRONMENT=1 WPMOO_PUBLISHED_PACKAGE_SPEC="@wpmoo/toolkit@$VERSION" \
178
+ npm run smoke:published -- "$VERSION"
179
+ ```
180
+
154
181
  ## PostgreSQL Diagnostics Are Unavailable
155
182
 
156
183
  Symptoms:
@@ -182,6 +209,8 @@ Expected result when available:
182
209
 
183
210
  - The JSON payload includes `postgres.contractVersion`.
184
211
  - The diagnostics object includes `schemaVersion`.
212
+ - The optional `sections` array groups PostgreSQL warnings under the
213
+ `postgresql` section while preserving the flat `warnings` array.
185
214
  - Missing or malformed metric rows are reported as unavailable diagnostics
186
215
  instead of being treated as success.
187
216
 
@@ -222,4 +251,3 @@ WPMOO_ENV=stage WPMOO_ALLOW_DESTRUCTIVE=1 WPMOO_ALLOW_NO_RECENT_SNAPSHOT=1 ./moo
222
251
  Use the guard flag only when the command is intentional, reviewed, and has an
223
252
  appropriate rollback path. Migration-risk lifecycle commands may also require
224
253
  `WPMOO_ALLOW_MIGRATIONS=1`.
225
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wpmoo/toolkit",
3
- "version": "0.9.28",
3
+ "version": "0.9.30",
4
4
  "description": "WPMoo Toolkit for development, staging, and production lifecycle workflows.",
5
5
  "type": "module",
6
6
  "repository": {