pm-csv 2026.10.26 → 2026.10.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +64 -36
  2. package/README.md +95 -2
  3. package/dist/admission.d.ts +93 -0
  4. package/dist/admission.d.ts.map +1 -0
  5. package/dist/admission.js +362 -0
  6. package/dist/admission.js.map +1 -0
  7. package/dist/atomic-update.d.ts.map +1 -1
  8. package/dist/atomic-update.js +16 -14
  9. package/dist/atomic-update.js.map +1 -1
  10. package/dist/edit-refusal.d.ts +1 -1
  11. package/dist/edit-refusal.d.ts.map +1 -1
  12. package/dist/index.d.ts +46 -8
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +364 -117
  15. package/dist/index.js.map +1 -1
  16. package/dist/join-plans.d.ts +110 -0
  17. package/dist/join-plans.d.ts.map +1 -0
  18. package/dist/join-plans.js +557 -0
  19. package/dist/join-plans.js.map +1 -0
  20. package/dist/lineage.d.ts +3 -6
  21. package/dist/lineage.d.ts.map +1 -1
  22. package/dist/lineage.js +32 -11
  23. package/dist/lineage.js.map +1 -1
  24. package/dist/mutation-intent.d.ts +57 -0
  25. package/dist/mutation-intent.d.ts.map +1 -0
  26. package/dist/mutation-intent.js +145 -0
  27. package/dist/mutation-intent.js.map +1 -0
  28. package/dist/roundtrip.d.ts +2 -8
  29. package/dist/roundtrip.d.ts.map +1 -1
  30. package/dist/roundtrip.js +78 -24
  31. package/dist/roundtrip.js.map +1 -1
  32. package/dist/settings-snapshot.d.ts +37 -0
  33. package/dist/settings-snapshot.d.ts.map +1 -0
  34. package/dist/settings-snapshot.js +128 -0
  35. package/dist/settings-snapshot.js.map +1 -0
  36. package/dist/table-schema.d.ts +10 -7
  37. package/dist/table-schema.d.ts.map +1 -1
  38. package/dist/table-schema.js +36 -12
  39. package/dist/table-schema.js.map +1 -1
  40. package/docs/import-admission.md +199 -0
  41. package/docs/join-plans.md +201 -0
  42. package/docs/join-validation.md +240 -0
  43. package/docs/spreadsheet-roundtrip.md +17 -2
  44. package/manifest.json +1 -1
  45. package/package.json +10 -6
package/CHANGELOG.md CHANGED
@@ -1,10 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 2026.10.26 - 2026-10-26
3
+ ## 2026.10.28 - 2026-10-28
4
4
 
5
5
  ### Fixed
6
6
 
7
- - Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-195](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-195.toon))
7
+ - Prove packed CSV custom fields survive export and re-import ([pm-csv-packed-custom-fields](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-packed-custom-fields.toon))
8
+
9
+ ### Other
10
+
11
+ - Use the pm SDK for runtime CSV export fields ([pm-csv-sdk-adoption-1025](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-sdk-adoption-1025.toon))
12
+
13
+ ## 2026.10.26 - 2026-10-26
14
+
15
+ ### Closed
16
+
17
+ - Closed: Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-195](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-195.toon))
8
18
 
9
19
  ## 2026.10.25 - 2026-10-25
10
20
 
@@ -40,9 +50,7 @@
40
50
 
41
51
  ### Fixed
42
52
 
43
- - Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-173](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-173.toon))
44
53
  - Development README names TypeScript 5 while the manifest pins TypeScript 7 ([pm-csv-bqyu](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-bqyu.toon))
45
- - Harden the release merge wait against mergeStateStatus deadlock ([pm-csv-7izf](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-7izf.toon))
46
54
  - The changelog gate stamps an untagged version with the current date, so its verdict flips every midnight with no commit ([pm-csv-bv81](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-bv81.toon))
47
55
  - Keep toolchain acceptance aligned with built-in merge drivers and shipped history ([pm-csv-9y0w](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-9y0w.toon))
48
56
  - Make legacy CSV importer accept file input and native flags ([pm-csv-76cu](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-76cu.toon))
@@ -53,6 +61,11 @@
53
61
 
54
62
  - Certify pm-csv with pm CLI and SDK 2026.9.28 ([pm-csv-3044](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-3044.toon))
55
63
 
64
+ ### Closed
65
+
66
+ - Closed: Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-173](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-173.toon))
67
+ - Closed: Harden the release merge wait against mergeStateStatus deadlock ([pm-csv-7izf](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-7izf.toon))
68
+
56
69
  ## 2026.10.12 - 2026-10-12
57
70
 
58
71
  ### Added
@@ -73,13 +86,16 @@
73
86
 
74
87
  ### Fixed
75
88
 
76
- - Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-134](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-134.toon))
77
89
  - A publish that npm accepts late is reported as failed and the GitHub Release is skipped on bun mirror lag ([pm-csv-c2a8](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-c2a8.toon))
78
90
 
79
91
  ### Other
80
92
 
81
93
  - Certify pm CLI 2026.9.23 and adopt the guarded pm-ops merge-driver launcher ([pm-csv-nqi5](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-nqi5.toon))
82
94
 
95
+ ### Closed
96
+
97
+ - Closed: Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-134](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-134.toon))
98
+
83
99
  ## 2026.9.18 - 2026-09-18
84
100
 
85
101
  ### Other
@@ -136,10 +152,10 @@
136
152
 
137
153
  ## 2026.9.1 - 2026-09-01
138
154
 
139
- ### Fixed
155
+ ### Closed
140
156
 
141
- - Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-86](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-86.toon))
142
- - Pin pm-changelog 2026.8.30 before the next release ([pm-csv-vc26](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-vc26.toon))
157
+ - Closed: Daily Release workflow is failing ([pm-csv-github-2b408bfa2d7f-86](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-github-2b408bfa2d7f-86.toon))
158
+ - Closed: Pin pm-changelog 2026.8.30 before the next release ([pm-csv-vc26](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-vc26.toon))
143
159
 
144
160
  ## 2026.8.31 - 2026-08-31
145
161
 
@@ -153,9 +169,12 @@
153
169
  ### Fixed
154
170
 
155
171
  - A failed provenance publish silently falls back to an unattested one ([pm-csv-nb1m](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-nb1m.toon))
156
- - Fix joinContinuations whitespace, add action.yml to EXECUTABLE_PATHS, and skip value-flag args in isPublishCommand ([pm-csv-v9cs](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-v9cs.toon))
157
172
  - The publish-attestation gate misses a publish routed through an unquoted shell variable ([pm-csv-ab5t](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-ab5t.toon))
158
173
 
174
+ ### Closed
175
+
176
+ - Closed: Fix joinContinuations whitespace, add action.yml to EXECUTABLE_PATHS, and skip value-flag args in isPublishCommand ([pm-csv-v9cs](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-v9cs.toon))
177
+
159
178
  ## 2026.8.28 - 2026-08-28
160
179
 
161
180
  ### Added
@@ -164,7 +183,6 @@
164
183
 
165
184
  ### Fixed
166
185
 
167
- - Full git history retains personal identity and redacted host-path blobs ([pm-csv-uaq1](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-uaq1.toon))
168
186
  - Changelog scripts consume bounded tracker output and erase release history ([pm-csv-zmcb](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-zmcb.toon))
169
187
  - Adopt the canonical certified complete-list reader ([pm-csv-t4cc](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-t4cc.toon))
170
188
  - Resume reader comment falsely permits empty map on list-all failure ([pm-csv-u254](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-u254.toon))
@@ -175,15 +193,16 @@
175
193
  - Dry-run upserts misreport existing keys as creates ([pm-csv-njaq](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-njaq.toon))
176
194
  - Latest published manifest fails pm 2026.8.20 strict health ([pm-csv-0aal](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-0aal.toon))
177
195
 
178
- ### Security
179
-
180
- - The identity gate deadlocks the one remediation its own failure message prescribes ([pm-csv-om24](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-om24.toon))
181
-
182
196
  ### Other
183
197
 
184
198
  - Enable GitHub CodeQL code scanning ([pm-csv-pam9](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-pam9.toon))
185
199
  - Alert on daily release failure and require merge drivers in CI ([pm-csv-76gz](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-76gz.toon))
186
200
 
201
+ ### Closed
202
+
203
+ - Closed: Full git history retains personal identity and redacted host-path blobs ([pm-csv-uaq1](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-uaq1.toon))
204
+ - Closed: The identity gate deadlocks the one remediation its own failure message prescribes ([pm-csv-om24](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-om24.toon))
205
+
187
206
  ## 2026.8.16 - 2026-08-16
188
207
 
189
208
  ### Fixed
@@ -194,25 +213,31 @@
194
213
 
195
214
  ### Fixed
196
215
 
197
- - Converge changelog generation and verification on replace mode ([pm-csv-mal7](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-mal7.toon))
198
216
  - The release merge-wait read branch protection which the workflow token can never read ([pm-csv-7ifl](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-7ifl.toon))
199
217
 
200
218
  ### Other
201
219
 
202
220
  - Adopt the canonical docstring gate against a pm-ops release that skips installed extension artifacts ([pm-csv-hi55](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-hi55.toon))
203
221
 
222
+ ### Closed
223
+
224
+ - Closed: Converge changelog generation and verification on replace mode ([pm-csv-mal7](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-mal7.toon))
225
+
204
226
  ## 2026.8.9 - 2026-08-09
205
227
 
206
228
  ### Fixed
207
229
 
208
- - Release workflow publishes npm before advancing git main, so a protected-branch push rejection permanently desyncs npm from git ([pm-csv-exz4](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-exz4.toon))
209
- - The overrun guard asserted a recovery outcome it never checked and reported update failures with no item id ([pm-csv-158c](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-158c.toon))
210
230
  - pm shell-outs silently degrade to wrong answers when stdout exceeds the spawnSync buffer ([pm-csv-02hc](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-02hc.toon))
211
231
 
212
232
  ### Other
213
233
 
214
234
  - Reconcile main to 2026.8.9 so git matches the npm version already published ([pm-csv-usmi](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-usmi.toon))
215
235
 
236
+ ### Closed
237
+
238
+ - Closed: Release workflow publishes npm before advancing git main, so a protected-branch push rejection permanently desyncs npm from git ([pm-csv-exz4](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-exz4.toon))
239
+ - Closed: The overrun guard asserted a recovery outcome it never checked and reported update failures with no item id ([pm-csv-158c](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-158c.toon))
240
+
216
241
  ## 2026.8.7 - 2026-08-07
217
242
 
218
243
  ### Other
@@ -247,45 +272,45 @@
247
272
 
248
273
  ## 2026.7.27 - 2026-07-27
249
274
 
250
- ### Fixed
251
-
252
- - csv validate fails to register on pm-cli 2026.7.27 because it redeclares the host-owned --json global ([pm-csv-0orl](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-0orl.toon))
253
-
254
275
  ### Removed
255
276
 
256
277
  - Adopt pm-cli 2026.7.26 typed authoring contracts and remove the any-cast defineExtension shim ([pm-csv-28sk](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-28sk.toon))
257
278
 
258
- ## 2026.7.26 - 2026-07-26
279
+ ### Closed
259
280
 
260
- ### Fixed
281
+ - Closed: csv validate fails to register on pm-cli 2026.7.27 because it redeclares the host-owned --json global ([pm-csv-0orl](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-0orl.toon))
261
282
 
262
- - Documented install command fails: pm install github.com/unbraind/pm-csv cannot resolve an entry file ([pm-csv-agf5](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-agf5.toon))
283
+ ## 2026.7.26 - 2026-07-26
263
284
 
264
285
  ### Other
265
286
 
266
287
  - Enable governance duplicate-detection advisory mode and adopt pm-cli 2026.7.25 ([pm-csv-kjqq](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-kjqq.toon))
267
288
 
268
- ## 2026.7.25 - 2026-07-25
289
+ ### Closed
269
290
 
270
- ### Fixed
291
+ - Closed: Documented install command fails: pm install github.com/unbraind/pm-csv cannot resolve an entry file ([pm-csv-agf5](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-agf5.toon))
271
292
 
272
- - pm item reads are capped at Node's 1 MiB spawnSync default, so a mature tracker fails with no diagnosis ([pm-csv-m13h](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-m13h.toon))
293
+ ## 2026.7.25 - 2026-07-25
273
294
 
274
295
  ### Other
275
296
 
276
297
  - Adopt --respect-item-release in changelog scripts and close the shipped-but-stale export terminator tracker ([pm-csv-qnax](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-qnax.toon))
277
298
  - Redact local host paths (/home/<user\>) from tracker item history ([pm-csv-tl5j](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-tl5j.toon))
278
299
 
279
- ## 2026.7.23 - 2026-07-23
300
+ ### Closed
280
301
 
281
- ### Fixed
302
+ - Closed: pm item reads are capped at Node's 1 MiB spawnSync default, so a mature tracker fails with no diagnosis ([pm-csv-m13h](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-m13h.toon))
282
303
 
283
- - Recommend pm merge reconcile (2026.7.22) over raw history-repair in Multi-agent merge safety docs ([pm-csv-9c2s](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-9c2s.toon))
304
+ ## 2026.7.23 - 2026-07-23
284
305
 
285
306
  ### Other
286
307
 
287
308
  - Adopt pm field-aware merge driver for multi-agent branch-merge safety ([pm-csv-3lxi](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-3lxi.toon))
288
309
 
310
+ ### Closed
311
+
312
+ - Closed: Recommend pm merge reconcile (2026.7.22) over raw history-repair in Multi-agent merge safety docs ([pm-csv-9c2s](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-9c2s.toon))
313
+
289
314
  ## 2026.7.19-1 - 2026-07-19
290
315
 
291
316
  ### Added
@@ -298,14 +323,14 @@
298
323
 
299
324
  ## 2026.7.19 - 2026-07-19
300
325
 
301
- ### Fixed
302
-
303
- - Fix --no-header: host rejects bare --no- flag as negation of missing --header ([pm-csv-ik4l](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-ik4l.toon))
304
-
305
326
  ### Other
306
327
 
307
328
  - Harden release bun-verify so registry-mirror lag cannot block the GitHub release ([pm-csv-m7i9](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/chores/pm-csv-m7i9.toon))
308
329
 
330
+ ### Closed
331
+
332
+ - Closed: Fix --no-header: host rejects bare --no- flag as negation of missing --header ([pm-csv-ik4l](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-ik4l.toon))
333
+
309
334
  ## 2026.7.11 - 2026-07-11
310
335
 
311
336
  ### Added
@@ -407,14 +432,17 @@
407
432
 
408
433
  ### Fixed
409
434
 
410
- - csv export drops body (no --include-body) and uses nonexistent due_date/milestone create flags ([pm-csv-l4vy](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-l4vy.toon))
411
- - csv import/export return error object instead of throwing (exit 0 on failure) ([pm-csv-e9v4](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-e9v4.toon))
412
435
  - csv import --dry-run silently ignored (still writes) ([pm-csv-zw3a](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-zw3a.toon))
413
436
 
414
437
  ### Other
415
438
 
416
439
  - Production-readiness audit 2026-05-28 ([pm-csv-7jbc](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/tasks/pm-csv-7jbc.toon))
417
440
 
441
+ ### Closed
442
+
443
+ - Closed: csv export drops body (no --include-body) and uses nonexistent due_date/milestone create flags ([pm-csv-l4vy](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-l4vy.toon))
444
+ - Closed: csv import/export return error object instead of throwing (exit 0 on failure) ([pm-csv-e9v4](https://github.com/unbraind/pm-csv/blob/main/.agents/pm/issues/pm-csv-e9v4.toon))
445
+
418
446
  ## 2026.5.28 - 2026-05-28
419
447
 
420
448
  ### Added
package/README.md CHANGED
@@ -42,11 +42,32 @@ tracker without a Git repository. None of these commands requires Git.
42
42
  | `pm csv import <file>` | Import a required CSV file; `--dry-run` previews without writes. |
43
43
  | `pm csv-import import <file>` | Same required file, flags, implementation and results as `csv import`. |
44
44
  | `pm csv validate <file>` | Validate a CSV file without writes. |
45
+ | `pm csv admit <file>` | Stream bounded initial/full validation, counts, widths and mutation upper bounds without writes. |
45
46
  | `pm csv export` / `pm csv-export export` | Export tracker items as CSV. |
46
47
  | `pm csv schema describe <file>` | Propose a reusable versioned table schema with `--output schema.json`. |
47
48
  | `pm csv schema preview <file> --schema schema.json` | Refuse changed dialect, columns, domains or target contracts without writes. |
48
49
  | `pm csv schema import <file> --schema schema.json` | Negotiate before importing through the existing mutation core; `--dry-run` is read-only. |
49
50
 
51
+ ### Bounded import admission
52
+
53
+ ```sh
54
+ pm csv admit large.csv --initial-rows 1000 --json
55
+ pm csv admit large.csv --json
56
+ pm csv import reviewed.csv --atomic --admission --json
57
+ ```
58
+
59
+ Full admission reports exact row counts, column widths, mutation upper bounds
60
+ and explicit resource limits. Initial observations report prefix counts and never
61
+ authorize apply. A million-row regression runs below a fixed 128 MiB heap cap;
62
+ atomic application separately requires at most 1,000 rows and 8 MiB. The opt-in
63
+ import guard finishes full validation and binds the captured source bytes before
64
+ any mutation, so an invalid final row refuses the entire admitted import.
65
+
66
+ The typed SDK, limit/refusal tables and an example are in
67
+ [bounded import admission](docs/import-admission.md). All admission commands work
68
+ without git. SDK transaction coordination does not isolate ordinary SDK/CLI
69
+ writers; the remaining target read/write window is documented there.
70
+
50
71
  ### Versioned table schema negotiation
51
72
 
52
73
  Save a reviewed mapping once and reuse it without silently reinterpreting a
@@ -84,9 +105,24 @@ pm csv import legacy.csv --encoding latin1 # non-UTF-8 source
84
105
  pm csv import sprint12.csv --source 'jira-export-2026-06'
85
106
  pm csv import vendor.csv --strict # fail before writing on bad row data
86
107
  pm csv import items.csv --dry-run
87
- pm csv import tasks.csv --atomic # writer-locked, crash-recoverable import
108
+ pm csv import tasks.csv --atomic # SDK-coordinated, crash-recoverable import
88
109
  ```
89
110
 
111
+ **Column ownership on keyed updates:** an absent header means “do not touch”.
112
+ Empty cells also leave existing values alone. A nonempty cell sets a supported
113
+ field; `none` or `null` (case-insensitive) explicitly clears a supported nullable scope
114
+ field: `parent`, `assignee`, `sprint`, `release` or `blocked_by`. Tags are additive;
115
+ `blocked_by` adds a blocker without deleting other dependency edges. Custom fields
116
+ are export-only and remain unchanged on import. Thus a title-only `--key title`
117
+ reimport preserves status, assignment, planning fields, body, links and custom data.
118
+ New items explicitly suppress implicit focus parents and planning defaults.
119
+ Spreadsheet edit sessions have their own documented explicit-clear contract.
120
+ Replay compares command values through SDK field normalization: local parents such
121
+ as `abcd`, `#ABCD` and `pm-abcd` resolve using the tracker prefix; provider locators
122
+ retain their native spelling. Assignment/planning whitespace and clear aliases
123
+ follow native command semantics. Stored edit-session values instead use SDK document
124
+ canonicalization, preserving literal strings such as `none`.
125
+
90
126
  **Flags**
91
127
 
92
128
  | Flag | Type | Default | Description |
@@ -102,7 +138,8 @@ pm csv import tasks.csv --atomic # writer-locked, crash-recoverable import
102
138
  | `--priority <n>` | integer | — | Import **only** rows whose integer priority equals this value |
103
139
  | `--strict` | boolean | false | Abort before writing if validation finds missing titles, unknown statuses, invalid/out-of-range priorities, or duplicate mapped columns |
104
140
  | `--dry-run` | boolean | false | Preview what would be imported without writing any data |
105
- | `--atomic` | boolean | false | Use one writer-locked, crash-recoverable transaction. On failure, attempt best-effort create compensation; pre-existing updates restore captured prior values unless a conflict prevents safe compensation. Inspect and reconcile any marked orphan before retrying. Incompatible with `--stream` |
141
+ | `--admission` | boolean | false | Finish bounded full validation and enforce atomic row/byte budgets before application; requires `--atomic` |
142
+ | `--atomic` | boolean | false | Use one SDK-coordinated, crash-recoverable transaction. On failure, attempt best-effort create compensation; pre-existing updates restore captured prior values unless a conflict prevents safe compensation. Inspect and reconcile any marked orphan before retrying. Incompatible with `--stream` |
106
143
 
107
144
  #### Strict import gate
108
145
 
@@ -437,6 +474,15 @@ plus complete CSV export in fresh npm/npx and Bun/bunx projects on the pinned
437
474
  development host, and in npm/npx on the declared minimum host. It is mandatory
438
475
  inside `npm run release:check`.
439
476
 
477
+ Every scenario seeds custom string, number, boolean, ISO date string, list and
478
+ empty-string values through its installed host SDK. Automatic `--all-fields`
479
+ discovery and explicit custom-column selection must export each value exactly,
480
+ including quoted multiline text, zero, false and empty lists. The packed
481
+ package's CSV parser then decodes the export for SDK import into a fresh
482
+ non-git tracker; SDK reads compare every custom value with the source tracker.
483
+ This SDK adapter roundtrip does not certify custom-column support in the legacy
484
+ `pm csv import` command, whose supported columns are listed above.
485
+
440
486
  ```bash
441
487
  npm install
442
488
  npm run build # runs tsc → dist/
@@ -524,3 +570,50 @@ keys make unchanged retries idempotent. The compact TOON/JSON receipt reports
524
570
  counts; artifacts include SHA-256 checksums. See the [protocol and worked
525
571
  example](docs/row-lineage.md) for the typed SDK, mapping revisions, refusals,
526
572
  privacy policy and recovery behavior.
573
+
574
+ ## Cross-table reference joins
575
+
576
+ Resolve explicit external-key parent and dependency columns across selected tables
577
+ in one preview, then apply the reviewed source digests through SDK transactions.
578
+
579
+ ```sh
580
+ pm csv join preview joins.json --output reviewed.json --json
581
+ pm csv join apply reviewed.json --json
582
+ ```
583
+
584
+ Duplicate or unresolved keys include cell coordinates and block import. See the
585
+ [three-table example, typed SDK API, bounds and recovery contract](docs/join-plans.md).
586
+ These create-only plans work without git. Retain the reviewed artifact for crash
587
+ recovery. Ordinary failures compensate unchanged owned creates and retain native
588
+ delete history; interrupted cleanup revalidates every target before continuing.
589
+ After compensation, preview fresh identities. Configured type/field lookups never
590
+ accept inherited object properties, while prototype-looking external keys remain
591
+ literal data. Foreign records and peer edits are preserved.
592
+
593
+ Saved join and checkout IDs must use distinct canonical native spellings under
594
+ the reviewed SDK prefix. All IDs validate before target leases or writes;
595
+ `abcd` and `review-abcd` cannot identify two rows with prefix `review`, even in
596
+ a correctly rehashed artifact. Preview a fresh plan after `csv_join_invalid`.
597
+
598
+ Join journal identity covers the full reviewed plan, independent of current
599
+ foreign-row eligibility. Retry resumes pending compensation under its recorded
600
+ key and step list before new work. Historical subset journals remain recoverable;
601
+ convergent spreadsheet values cannot bypass their cleanup. Atomic CSV retry with
602
+ changed filters or mappings refuses when it would shrink or change an existing
603
+ journal's row domain: resume using the original options to finish recovery first.
604
+
605
+ Join planning captures one settings/schema snapshot. Create type and status
606
+ defaults are resolved from that snapshot before writes; every mutation batch
607
+ rechecks its digest inside SDK writer coordination. A settings change between
608
+ rows returns `csv_join_settings_changed` and compensates unchanged owned creates.
609
+ Recovery uses one separately guarded current-policy snapshot for cleanup. Peer
610
+ edits or further policy changes can require journal reconciliation. Inputs and
611
+ the tracker root are captured before asynchronous SDK reads, so caller edits or
612
+ working-directory changes cannot redirect an in-flight plan.
613
+
614
+ CSV mutations use explicit source-owned scope: missing or empty create parents
615
+ are unset through the SDK, so session focus cannot add links. Empty supported
616
+ scope cells preserve legacy keyed-import state; spreadsheet patches preserve
617
+ unselected fields. Join replay refuses unreviewed stored scope. Public join
618
+ failures consistently use `JoinRefusal`, with lower-level `sourceCode` and remedy
619
+ retained. See [scope and refusal contracts](docs/join-plans.md#explicit-scope-and-refusal-boundaries).
@@ -0,0 +1,93 @@
1
+ import { PmCliError } from "@unbrained/pm-cli/sdk";
2
+ import type { ExtensionApi } from "@unbrained/pm-cli/sdk/authoring";
3
+ import type { PmSettings } from "@unbrained/pm-cli/sdk";
4
+ import type { ImportRowFilter } from "./index.ts";
5
+ /** Hard allocation and materialization ceilings; callers can only lower them. Units are UTF-16 code units unless named bytes. */
6
+ export declare const ADMISSION_LIMITS: Readonly<Record<"maxFieldCodeUnits" | "maxRecordCodeUnits" | "maxColumns" | "maxAtomicBytes" | "maxAtomicRows" | "maxSourceBytes", number>>;
7
+ /** One strict SDK/CLI boundary; initial scans never authorize apply. */
8
+ export interface AdmissionOptions {
9
+ mode?: "initial" | "full";
10
+ initialRows?: number;
11
+ delimiter?: string;
12
+ encoding?: "utf-8" | "utf8" | "utf16le" | "latin1";
13
+ skipHeaders?: boolean;
14
+ fieldMap?: Record<string, string>;
15
+ autoMap?: boolean;
16
+ filter?: ImportRowFilter;
17
+ maxFieldCodeUnits?: number;
18
+ maxRecordCodeUnits?: number;
19
+ maxColumns?: number;
20
+ maxAtomicBytes?: number;
21
+ maxAtomicRows?: number;
22
+ maxSourceBytes?: number;
23
+ }
24
+ /** Compact source-free receipt. Mutation work is a row-operation upper bound, never an exact create/update count or heap prediction. */
25
+ export interface AdmissionReceipt {
26
+ version: 1;
27
+ mode: "initial" | "full";
28
+ ok: boolean;
29
+ complete: boolean;
30
+ admitted: boolean;
31
+ digest?: string;
32
+ rows: {
33
+ value: number;
34
+ kind: "exact" | "lower_bound";
35
+ };
36
+ invalidRows: number;
37
+ issues: {
38
+ row: number;
39
+ code: "row_width" | "row_invalid";
40
+ }[];
41
+ fieldWidths: number[];
42
+ mutationWork: {
43
+ value: number;
44
+ kind: "upper_bound";
45
+ };
46
+ sourceBytes: number;
47
+ limits: typeof ADMISSION_LIMITS;
48
+ remedy?: string;
49
+ }
50
+ /** Stable refusal families; no source cells, source paths or low-level IO text is exposed. */
51
+ export type AdmissionRefusalCode = "csv_admission_options" | "csv_admission_io" | "csv_admission_limit" | "csv_admission_invalid" | "csv_admission_incomplete" | "csv_admission_source_changed" | "csv_admission_settings_changed" | "csv_admission_target_changed" | "csv_admission_sdk";
52
+ /** Expected semantic failure with a concrete retry action. */
53
+ export declare class AdmissionRefusal extends PmCliError {
54
+ /** Stable category for an automated retry decision. */
55
+ readonly code: AdmissionRefusalCode;
56
+ /** Concrete repair action, excluding source content. */
57
+ readonly remedy: string;
58
+ constructor(code: AdmissionRefusalCode, remedy: string);
59
+ }
60
+ /** Keep admission and its native application in one settings-refusal family. */
61
+ export declare function admissionSettingsChanged(): AdmissionRefusal;
62
+ /** Preserve typed admission remedies when native transaction compensation aggregates failures. */
63
+ export declare function findAdmissionFailure(error: unknown, seen?: Set<unknown>): AdmissionRefusal | undefined;
64
+ /** Older hosts keep read-only admission; applying needs the native semantic preview capability. */
65
+ export declare function requireAdmissionCapability<T extends (...args: never[]) => unknown>(value: T | undefined): T;
66
+ /** Preserve a concrete host/storage remedy when an older SDK previews installed dependency links. */
67
+ export declare function admissionPreviewFailure(error: unknown): AdmissionRefusal;
68
+ /** Validate options once before IO, including finite integer domains and bounded own-key mappings. */
69
+ export declare function parseAdmissionOptions(value: AdmissionOptions): Required<AdmissionOptions>;
70
+ /** Normalize a selected status through the same native registry as row writes, preserving source-based type filtering. */
71
+ export declare function normalizeAdmissionFilter(filter: ImportRowFilter, settings: PmSettings): ImportRowFilter | undefined;
72
+ /** Refuse unusable resource reports before an atomic caller allocates a row plan. */
73
+ export declare function assertCSVAdmission(receipt: AdmissionReceipt): void;
74
+ /** Capture bounded bytes for the existing atomic parser, refusing source drift before materialization or writes. */
75
+ export declare function readAdmittedSource(file: string, digest: string, maxBytes?: number): Buffer;
76
+ /** Require current native state or the latest immutable success of exactly this row. */
77
+ export declare function admissionTargetRevision(pmRoot: string, id: string, expected?: string, appliedMarker?: string): Promise<string>;
78
+ /** Reconcile ordered writes to one native target; later rows prove the completed prefix, including reverse compensation. */
79
+ export declare function admissionTargetSequence(pmRoot: string, id: string, expected: string, markers: readonly string[]): Promise<{
80
+ revision: string;
81
+ completed: number;
82
+ }>;
83
+ /** Check every emitted count and width before returning success, also useful to consumers validating receipts. */
84
+ export declare function assertAdmissionNumbers(receipt: AdmissionReceipt): void;
85
+ /** Read-only admission against one SDK settings revision. Source size never determines retained row count. */
86
+ export declare function admitCSV(pmRoot: string, file: string, options?: AdmissionOptions, diagnostics?: AdmissionDiagnostics): Promise<AdmissionReceipt>;
87
+ /** Trusted observer for deterministic concurrency diagnostics, outside the untrusted options schema. */
88
+ export interface AdmissionDiagnostics {
89
+ onBoundary?: (phase: "opened" | "read" | "validated") => void | Promise<void>;
90
+ }
91
+ /** Register one host-rendered compact TOON/JSON command; no source values or artifacts are emitted. */
92
+ export declare function registerAdmissionCommand(api: ExtensionApi): void;
93
+ //# sourceMappingURL=admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.d.ts","sourceRoot":"","sources":["../admission.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACvN,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlD,iIAAiI;AACjI,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,mBAAmB,GAAG,oBAAoB,GAAG,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,EAAE,MAAM,CAAC,CACrF,CAAC;AACrF,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AACD,wIAAwI;AACxI,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAAA;KAAE,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAAA;KAAE,EAAE,CAAC;IAC7D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,8FAA8F;AAC9F,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG,kBAAkB,GAAG,qBAAqB,GACrG,uBAAuB,GAAG,0BAA0B,GAAG,8BAA8B,GAAG,gCAAgC,GAAG,8BAA8B,GAAG,mBAAmB,CAAC;AAClL,8DAA8D;AAC9D,qBAAa,gBAAiB,SAAQ,UAAU;IAC9C,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,YAAY,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAIrD;CACF;AACD,gFAAgF;AAChF,wBAAgB,wBAAwB,IAAI,gBAAgB,CAE3D;AACD,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,eAAqB,GAAG,gBAAgB,GAAG,SAAS,CAW5G;AACD,mGAAmG;AACnG,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,CAAC,CAG3G;AACD,qGAAqG;AACrG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAOxE;AACD,sGAAsG;AACtG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAgCzF;AACD,0HAA0H;AAC1H,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS,CAMnH;AACD,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAIlE;AACD,oHAAoH;AACpH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAkC,GAAG,MAAM,CAoBnH;AAeD,wFAAwF;AACxF,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKpI;AACD,4HAA4H;AAC5H,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxK;AAKD,kHAAkH;AAClH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAUtE;AA0FD,8GAA8G;AAC9G,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,EAAE,WAAW,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG9J;AACD,wGAAwG;AACxG,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E;AACD,uGAAuG;AACvG,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CA2BhE"}