@adhd/backlog 1.0.3 → 1.0.4
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.
- package/CHANGELOG.md +10 -0
- package/api.ir.json +1 -1
- package/index.js +41 -41
- package/index.mjs +1107 -1080
- package/package.json +1 -1
- package/write/catalog.d.ts +23 -11
- package/write/errors.d.ts +37 -1
package/package.json
CHANGED
package/write/catalog.d.ts
CHANGED
|
@@ -73,21 +73,32 @@ export interface IMintOrResolveInput {
|
|
|
73
73
|
* that reads as non-terminal — the drift `catalog-repair.ts` exists to clean
|
|
74
74
|
* up is not regenerated on the next mint.
|
|
75
75
|
*
|
|
76
|
-
* Membership is
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
76
|
+
* Membership is decided on the FOLDED name ({@link catalogNameFold}) — the
|
|
77
|
+
* same Unicode fold the duplicate guard and the case-fragment repair use, never
|
|
78
|
+
* SQL `lower()`/`NOCASE`, which fold only ASCII `A`–`Z`. The spellings below
|
|
79
|
+
* are the canonical catalog rows, but the PREDICATE folds, so `Closed`,
|
|
80
|
+
* `fixed`, `resolved` and `done` all count as reserved. This matters because a
|
|
81
|
+
* first-ever lowercase `fixed`/`resolved`/`done` has no uppercase row to
|
|
82
|
+
* collide against; under an exact-case predicate it would seed
|
|
83
|
+
* `terminal:false` — a closed status the read layer returns as open (backlog
|
|
84
|
+
* b4525bc3 / d7ec2c50). There is exactly ONE such table in the codebase
|
|
85
|
+
* (`catalog-repair.ts` re-exports this set rather than declaring its own).
|
|
83
86
|
*/
|
|
84
87
|
export declare const RESERVED_TERMINAL_STATUS_NAMES: ReadonlySet<string>;
|
|
85
|
-
/** Whether `name` is
|
|
88
|
+
/** Whether `name` is one of {@link RESERVED_TERMINAL_STATUS_NAMES} under the case fold — so any spelling of the reserved terminal vocabulary (`closed`/`Closed`/`CLOSED`, `fixed`/`FIXED`) counts. */
|
|
86
89
|
export declare function isReservedTerminalStatusName(name: string): boolean;
|
|
87
90
|
/**
|
|
88
91
|
* The flat-catalog find-then-create (§1, §4c, §6.1): `kind`/`status`/
|
|
89
92
|
* `priority`/`agent` are mintable on an unresolved NAME; a uid-shaped `ref`
|
|
90
93
|
* that does not resolve instead throws — minting NEVER applies to a uid.
|
|
94
|
+
*
|
|
95
|
+
* A NAME that case-folds to an EXISTING LIVE row of the same kind but is
|
|
96
|
+
* spelled differently (`IN_PROGRESS` when `in_progress` is live) is REFUSED
|
|
97
|
+
* with {@link CaseVariantNameError} — never fold-resolved onto the existing
|
|
98
|
+
* row, never minted as a twin. Identity is exact-case (`WHERE name = ?`), so a
|
|
99
|
+
* variant is neither the same row nor a genuinely new name; it is ambiguous,
|
|
100
|
+
* and the ambiguity is stopped here rather than allowed to grow a duplicate
|
|
101
|
+
* the catalog-invariant guard would then abort every read over.
|
|
91
102
|
*/
|
|
92
103
|
export declare function mintOrResolveCatalogTx(tx: AdapterTransaction, input: IMintOrResolveInput): Promise<IResolvedCatalogRow>;
|
|
93
104
|
/**
|
|
@@ -108,9 +119,10 @@ export declare function mintOrResolveCatalogTx(tx: AdapterTransaction, input: IM
|
|
|
108
119
|
* exact `(kind,name)` lookup inside {@link mintOrResolveCatalogTx} finds the
|
|
109
120
|
* seeded row on every subsequent call, so reseeding never duplicates — the
|
|
110
121
|
* store converges to one live `status` row per name. A case-variant name
|
|
111
|
-
* (`Closed` vs a seeded `closed`) is
|
|
112
|
-
*
|
|
113
|
-
*
|
|
122
|
+
* (`Closed` vs a seeded `closed`) is REFUSED by {@link mintOrResolveCatalogTx}
|
|
123
|
+
* with {@link CaseVariantNameError} rather than folded onto the existing row or
|
|
124
|
+
* minted as a twin — the same exact-case stop every other flat catalog takes
|
|
125
|
+
* (see that function's doc comment).
|
|
114
126
|
*
|
|
115
127
|
* A uid-shaped `ref` that does not resolve still throws
|
|
116
128
|
* `CatalogNotFoundError` — minting never applies to a uid (§6.1).
|
package/write/errors.d.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* All named classes here are `E_VALIDATION`- or `E_CONSTRAINT`-class
|
|
19
19
|
* members of the same union (SPEC.md §4c, "Two failure-signaling shapes,
|
|
20
20
|
* reconciled into one contract") — `IssueNotFoundError`, `InvalidArgumentError`,
|
|
21
|
-
* `CatalogNotFoundError`, `ClaimHeldError`, `SingleValuedRelationConflictError`,
|
|
21
|
+
* `CatalogNotFoundError`, `CaseVariantNameError`, `ClaimHeldError`, `SingleValuedRelationConflictError`,
|
|
22
22
|
* `NoteRequiredError`, `CitationRequiredError`, `CitationUnverifiableError` are
|
|
23
23
|
* `E_VALIDATION` (never retryable — thrown before any driver call runs);
|
|
24
24
|
* `StaleSupersedeError` is the one deliberate `E_CONSTRAINT` this spec's own
|
|
@@ -162,6 +162,42 @@ export declare class CatalogNotFoundError extends BacklogWriteError {
|
|
|
162
162
|
readonly retryable = false;
|
|
163
163
|
constructor(catalogKind: string, ref: string);
|
|
164
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* A flat-catalog write named a token that differs from an EXISTING LIVE row of
|
|
167
|
+
* the SAME kind only by letter case (`IN_PROGRESS` vs `in_progress`, `high` vs
|
|
168
|
+
* `HIGH`). Catalog identity is EXACT-case (`DATA_MODEL.md:70-78`; the
|
|
169
|
+
* `(kind, name)` resolve in `write/catalog.ts` is `WHERE name = ?`), so the
|
|
170
|
+
* write path REFUSES the variant rather than fold-resolving it onto the
|
|
171
|
+
* existing row or minting a twin. Accepting it would grow a second live row
|
|
172
|
+
* that case-folds to the first — the case-fragment defect the uniqueness guard
|
|
173
|
+
* (`store/catalog-invariant-guard.ts`) exists to catch, which is exactly how
|
|
174
|
+
* the store wedged (BUG: a mixed-case write minted a twin, then the guard
|
|
175
|
+
* refused every read).
|
|
176
|
+
*
|
|
177
|
+
* The message names BOTH spellings and tells the caller which one to use: the
|
|
178
|
+
* one already live. The ambiguity is stopped here, at the single write call
|
|
179
|
+
* site, instead of aborting every read.
|
|
180
|
+
*
|
|
181
|
+
* `E_VALIDATION`, never retryable — this is a before-any-mint decision, so
|
|
182
|
+
* retrying the identical payload fails identically.
|
|
183
|
+
*/
|
|
184
|
+
export declare class CaseVariantNameError extends BacklogWriteError {
|
|
185
|
+
/** The flat-catalog kind (`status`, `priority`, `kind`, `agent`). */
|
|
186
|
+
readonly catalogKind: string;
|
|
187
|
+
/** The name of the row ALREADY LIVE for this kind — the spelling to use. */
|
|
188
|
+
readonly canonicalName: string;
|
|
189
|
+
/** The differing name the caller supplied — the spelling that was refused. */
|
|
190
|
+
readonly offendingName: string;
|
|
191
|
+
readonly code: "E_VALIDATION";
|
|
192
|
+
readonly retryable = false;
|
|
193
|
+
constructor(
|
|
194
|
+
/** The flat-catalog kind (`status`, `priority`, `kind`, `agent`). */
|
|
195
|
+
catalogKind: string,
|
|
196
|
+
/** The name of the row ALREADY LIVE for this kind — the spelling to use. */
|
|
197
|
+
canonicalName: string,
|
|
198
|
+
/** The differing name the caller supplied — the spelling that was refused. */
|
|
199
|
+
offendingName: string);
|
|
200
|
+
}
|
|
165
201
|
/** A caller-supplied argument is missing, blank, or fails a project-declared invariant. */
|
|
166
202
|
export declare class InvalidArgumentError extends BacklogWriteError {
|
|
167
203
|
readonly field: string;
|