@adhd/backlog 1.0.5 โ 1.0.6
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 +53 -0
- package/README.md +194 -39
- package/api.d.ts +87 -0
- package/api.ir.json +1 -1
- package/citation.d.ts +176 -0
- package/envelope.d.ts +35 -1
- package/index.d.ts +23 -3
- package/index.js +106 -58
- package/index.mjs +11627 -7068
- package/ir-artifact.d.ts +7 -3
- package/lifecycle.d.ts +49 -0
- package/package.json +5 -5
- package/query/canonical.d.ts +16 -0
- package/query/card.d.ts +116 -4
- package/query/get.d.ts +8 -1
- package/query/index.d.ts +1 -0
- package/query/query.d.ts +20 -13
- package/query/redirect.d.ts +30 -0
- package/query/resolve.d.ts +48 -0
- package/query/similar-clusters.d.ts +8 -0
- package/query/similarity-signals.d.ts +47 -0
- package/query/spec-staleness.d.ts +21 -0
- package/query/types.d.ts +249 -34
- package/query/verdict-core.d.ts +21 -0
- package/query/verdict.d.ts +22 -0
- package/query/views/catalog.d.ts +47 -0
- package/query/views/registry.d.ts +27 -7
- package/query/views/report.d.ts +49 -0
- package/query/views/semantic.d.ts +28 -5
- package/query/views/stats.d.ts +38 -2
- package/readiness.d.ts +29 -0
- package/retry-policy.d.ts +44 -0
- package/serve.d.ts +1 -1
- package/server.d.ts +71 -3
- package/service-config.d.ts +109 -0
- package/service-errors.d.ts +51 -0
- package/skill/SKILL.md +688 -81
- package/store/catalog-invariant-guard.d.ts +4 -4
- package/vocabulary.d.ts +48 -0
- package/write/anchor-check.d.ts +139 -0
- package/write/attestation.d.ts +64 -0
- package/write/catalog-merge.d.ts +15 -8
- package/write/catalog.d.ts +63 -0
- package/write/citation-path.d.ts +31 -0
- package/write/citation.d.ts +157 -0
- package/write/create-issue.d.ts +143 -29
- package/write/errors.d.ts +159 -0
- package/write/gate.d.ts +67 -0
- package/write/merge-project.d.ts +54 -0
- package/write/obligation.d.ts +133 -0
- package/write/relate.d.ts +1 -1
- package/write/revision.d.ts +27 -0
- package/write/similarity-scan.d.ts +84 -0
- package/write/spec-revision.d.ts +131 -0
- package/write/spec-revision.reconcile.d.ts +48 -0
- package/write/transition.d.ts +13 -2
- package/write/tx.d.ts +21 -1
- package/write/update.d.ts +23 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,56 @@
|
|
|
1
|
+
## 1.0.6 (2026-09-29)
|
|
2
|
+
|
|
3
|
+
### ๐ Features
|
|
4
|
+
|
|
5
|
+
- **backlog:** first-class citation verbs + one citation contract ([e46a0490](https://github.com/PseudoSky/adhd/commit/e46a0490))
|
|
6
|
+
|
|
7
|
+
### ๐ฉน Fixes
|
|
8
|
+
|
|
9
|
+
- **workspace:** restore the publish gate's heavy lane and canonicalise the gate ([45532731](https://github.com/PseudoSky/adhd/commit/45532731))
|
|
10
|
+
- **backlog:** drop banned prior-version/current-version tokens from the cross-repo attestation spec ([acf53458](https://github.com/PseudoSky/adhd/commit/acf53458))
|
|
11
|
+
- **backlog:** read verdict applies the write gate's close-predictor skip ([13e7c870](https://github.com/PseudoSky/adhd/commit/13e7c870))
|
|
12
|
+
- **backlog:** a terminal-scoped obligation gates the close, not the claim (demo 3.3) ([5db10040](https://github.com/PseudoSky/adhd/commit/5db10040))
|
|
13
|
+
- **backlog:** resolve a cross-repo anchor against the sibling project root that owns it (demo 2.4) ([068e554c](https://github.com/PseudoSky/adhd/commit/068e554c))
|
|
14
|
+
|
|
15
|
+
### โค๏ธ Thank You
|
|
16
|
+
|
|
17
|
+
- pseudosky
|
|
18
|
+
|
|
19
|
+
## 1.1.0 (2026-09-28)
|
|
20
|
+
|
|
21
|
+
### ๐ Features
|
|
22
|
+
|
|
23
|
+
- **backlog:** deterministic dependent-weight tiebreak in view:"order" (C2 AC4) ([15dc77ba](https://github.com/PseudoSky/adhd/commit/15dc77ba))
|
|
24
|
+
- **backlog:** C6 verdict โ derived actionability with reasons; claim refuses live blockers ([c0c0ea5c](https://github.com/PseudoSky/adhd/commit/c0c0ea5c))
|
|
25
|
+
- **backlog:** C5 closure gate โ terminal transitions require satisfied obligations ([a49ec889](https://github.com/PseudoSky/adhd/commit/a49ec889))
|
|
26
|
+
- **backlog:** C10 โ a spec is a revision of its ticket (store-citizen documents) ([02a969ba](https://github.com/PseudoSky/adhd/commit/02a969ba))
|
|
27
|
+
- **backlog:** C4 obligation โ obligate/unobligate + closed predicate core ([72ddafbe](https://github.com/PseudoSky/adhd/commit/72ddafbe))
|
|
28
|
+
- **backlog:** C8 โ closed primitives, readable catalogs, self-describing surface ([5e8cb041](https://github.com/PseudoSky/adhd/commit/5e8cb041))
|
|
29
|
+
- **backlog:** C3 attestation โ attest/recheck, anchors, citation roots ([f675393b](https://github.com/PseudoSky/adhd/commit/f675393b))
|
|
30
|
+
- **backlog:** C9 cross-project similarity detection and reviewed linking ([f9e1eb96](https://github.com/PseudoSky/adhd/commit/f9e1eb96))
|
|
31
|
+
- **backlog:** D-A trustworthy service layer โ readiness, config-drift gate, retry+breaker ([aa894690](https://github.com/PseudoSky/adhd/commit/aa894690))
|
|
32
|
+
- **backlog:** foundation โ attestation/obligation node kinds + attests/has_obligation/satisfies edges (69632883) ([cc7eae49](https://github.com/PseudoSky/adhd/commit/cc7eae49))
|
|
33
|
+
- **backlog:** C1 reference โ prefix resolution, redirect, merge/rm-project ([2780b433](https://github.com/PseudoSky/adhd/commit/2780b433))
|
|
34
|
+
- **backlog:** C7 honest envelopes, score provenance, bounded sub-collections, report ([8fa60ffd](https://github.com/PseudoSky/adhd/commit/8fa60ffd))
|
|
35
|
+
- **backlog:** C2 kind-scope โ related exposes all rel types, order spans member kinds ([f02e8d23](https://github.com/PseudoSky/adhd/commit/f02e8d23))
|
|
36
|
+
|
|
37
|
+
### ๐ฉน Fixes
|
|
38
|
+
|
|
39
|
+
- **backlog:** collapse the kind case-fragments in the repair CLI, pin the transition-path refusal ([16b42095](https://github.com/PseudoSky/adhd/commit/16b42095))
|
|
40
|
+
- **backlog:** C10 spec discovery sees declared-kind SPECs, not only raw kind (603737c2) ([e4a6b51d](https://github.com/PseudoSky/adhd/commit/e4a6b51d))
|
|
41
|
+
- **backlog:** C10 reconcile discovers live kind:SPEC items, not only raw node kind ([9c87e1d4](https://github.com/PseudoSky/adhd/commit/9c87e1d4))
|
|
42
|
+
- **backlog:** C9 wire the cross-project structural second signal (A-side) ([c01ef514](https://github.com/PseudoSky/adhd/commit/c01ef514))
|
|
43
|
+
- **backlog:** D-A apply the resolved service.* config (port/transport/host/resilience) ([4405e717](https://github.com/PseudoSky/adhd/commit/4405e717))
|
|
44
|
+
- **backlog:** rename create partOf input to dedupeExcludeUid (c5460239; 081facec) ([7584a847](https://github.com/PseudoSky/adhd/commit/7584a847))
|
|
45
|
+
- **backlog:** C1 lookup โ match issue name, not body, so the registry is not shadowed ([46b3165d](https://github.com/PseudoSky/adhd/commit/46b3165d))
|
|
46
|
+
- **backlog:** C7 โ reconcile _score_kind doc/code vocabulary ([3c111d80](https://github.com/PseudoSky/adhd/commit/3c111d80))
|
|
47
|
+
- **backlog:** create dedupe excludes a declared parent + its part_of ancestors (c5460239) ([dfb5aca9](https://github.com/PseudoSky/adhd/commit/dfb5aca9))
|
|
48
|
+
- **backlog:** create dedupe gate fails closed, not open, on a degraded scan (BUG 4e8fce2a; cc2b5b87) ([04dd0283](https://github.com/PseudoSky/adhd/commit/04dd0283))
|
|
49
|
+
|
|
50
|
+
### โค๏ธ Thank You
|
|
51
|
+
|
|
52
|
+
- pseudosky
|
|
53
|
+
|
|
1
54
|
## 1.0.5 (2026-09-27)
|
|
2
55
|
|
|
3
56
|
### ๐ฉน Fixes
|
package/README.md
CHANGED
|
@@ -60,11 +60,20 @@ adhd-backlog create --input '{
|
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
```json
|
|
63
|
-
{ "ok": true, "data": { "created": true, "uid": "b3b2da0e-โฆ", "item": { "uid": "b3b2da0e-โฆ", "title": "Query pagination drops the last page under offset paging", "kind": "issue", "status": "open", "priority": "HIGH", "project": "49ec673b-โฆ", "component": "65c4e373-โฆ", "createdAt": "2026-09-24T00:14:38.802Z", "author": "agent:worker-1", "gitContext": "feat/backlog-hard-replacement @ 4bf902fc" } } }
|
|
63
|
+
{ "ok": true, "data": { "created": true, "uid": "b3b2da0e-โฆ", "item": { "uid": "b3b2da0e-โฆ", "title": "Query pagination drops the last page under offset paging", "kind": "issue", "status": "open", "priority": "HIGH", "project": "49ec673b-โฆ", "component": "65c4e373-โฆ", "createdAt": "2026-09-24T00:14:38.802Z", "author": "agent:worker-1", "gitContext": "feat/backlog-hard-replacement @ 4bf902fc" }, "placementResolved": "default-root" } }
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
> `project` and `component` in the result are `uid`s, not names. `gitContext`
|
|
67
67
|
> is described under [Citations & git context](#citations--git-context).
|
|
68
|
+
> `placementResolved` is `"default-root"` when the omitted `component` fell
|
|
69
|
+
> back to the project's reserved `(root)` component, or `"explicit"` when a
|
|
70
|
+
> supplied one resolved โ a `default-root` item is invisible to
|
|
71
|
+
> component-scoped scans. A create result may additionally carry
|
|
72
|
+
> `duplicateScanDegraded: true` plus `duplicateScanDegradedReason`
|
|
73
|
+
> (`"no-search-backend"` / `"no-embed-query"` / `"no-vector-scores"`) when the
|
|
74
|
+
> pre-write dedupe scan could not run a calibrated comparison; both are absent
|
|
75
|
+
> on a healthy scan and never imply the write failed. Full field notes are in
|
|
76
|
+
> [`skill/SKILL.md` ยง3](skill/SKILL.md).
|
|
68
77
|
|
|
69
78
|
Query for it:
|
|
70
79
|
|
|
@@ -187,11 +196,94 @@ resolve to the wrong record.
|
|
|
187
196
|
{ "ok": false, "error": { "code": "conflict", "message": "Issue \"63c2f57e-โฆ\" was superseded by a body edit and is no longer the live issue; it now lives under \"e3b32183-โฆ\"", "details": { "retryable": false } } }
|
|
188
197
|
```
|
|
189
198
|
|
|
199
|
+
### 8. Obligation-gated transitions and the actionability verdict
|
|
200
|
+
|
|
201
|
+
Declare a typed requirement on an issue with `obligate`; the store then refuses
|
|
202
|
+
any transition that would violate it until the requirement is met. A
|
|
203
|
+
`block`-severity `evidence` obligation, for example, keeps a `closed`
|
|
204
|
+
transition refused until a matching verified attestation exists.
|
|
205
|
+
|
|
206
|
+
An obligation is scoped by `applies_to.to` to the **transition** it guards โ a
|
|
207
|
+
close-scoped obligation gates the close, **not** claimability. So `get` reports
|
|
208
|
+
the item actionable (the same answer `claim` gives), and the close is what gets
|
|
209
|
+
refused:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
adhd-backlog get --input '{"uid":"1d9b77e5-โฆ","fields":["verdict","obligations"]}'
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{ "ok": true, "data": { "uid": "1d9b77e5-โฆ", "obligations": [{ "uid": "fbcee200-โฆ", "applies_to": { "to": "closed" }, "requirement": { "op": "evidence", "kind": "published-artifact", "min": 1 }, "on_fail": "block" }], "verdict": { "actionable": true, "evaluated_at": "โฆ", "revision": 0, "conditions": [] } } }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Only an obligation scoped to a **non-terminal** transition (e.g.
|
|
220
|
+
`applies_to:{to:"in_progress"}`) is due at claim time, and only then does it
|
|
221
|
+
appear as a rung-2 block condition in the verdict.
|
|
222
|
+
|
|
223
|
+
Attempt the close and the gate refuses with a typed `precondition_failed`,
|
|
224
|
+
writing nothing:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{ "ok": false, "error": { "code": "precondition_failed", "message": "Transition refused: EvidenceUnverified (requires \"published-artifact\") โ no verified attestation of kind \"published-artifact\" satisfies this obligation", "details": { "retryable": false } } }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`actionable` is tri-state (`true` / `false` / `"unknown"`) โ `"unknown"` is
|
|
231
|
+
never a green light. The full declare โ read โ refuse โ attest โ close
|
|
232
|
+
workflow, the closed predicate grammar, and the permitted-override path are in
|
|
233
|
+
[`skill/SKILL.md` ยง4](skill/SKILL.md).
|
|
234
|
+
|
|
235
|
+
### 9. Compare-and-swap spec revisions
|
|
236
|
+
|
|
237
|
+
A ticket's work product is a sequence of immutable spec revisions.
|
|
238
|
+
`spec-append` appends a fragment and advances the pointer in place, and its
|
|
239
|
+
required `base_revision` makes the append a compare-and-swap: a stale base is
|
|
240
|
+
refused with `precondition_failed` and nothing is written. `spec-check` tells a
|
|
241
|
+
reader whether the token it holds is still current โ an absent token is
|
|
242
|
+
`stale`, never `fresh` โ and `attest` records a comment keyed to an exact
|
|
243
|
+
revision (never to the ticket body) via a `SPEC` subject + a `revision:` anchor:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
adhd-backlog spec-check --input '{"uid":"c79b52b0-โฆ"}'
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{ "ok": true, "data": { "current_revision": "58b5dfd8-โฆ", "current_token": "sha256:d0bcba4aโฆ", "state": "stale", "method": "none", "reason": "no-token-supplied" } }
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
See [`skill/SKILL.md` ยง5](skill/SKILL.md) for the append/check worked example.
|
|
254
|
+
|
|
255
|
+
### 10. Live catalogs and dependency-ordered plans
|
|
256
|
+
|
|
257
|
+
`query --input '{"view":"catalogs"}'` returns every vocabulary the store
|
|
258
|
+
enforces (kinds, statuses, priorities, relations, fields, error codes, location
|
|
259
|
+
types, and the mounted verbs), each term naming the in-code source it was
|
|
260
|
+
generated from. Note that **`kind` is open/free-form, not an enumerable
|
|
261
|
+
allowlist**: `create` accepts any `kind` string and the `kind` catalog is a
|
|
262
|
+
usage census (`source: "store"`), so it is **empty on a fresh store** and then
|
|
263
|
+
lists what has actually been filed (`"issue"` is the default; `"plan"` is the
|
|
264
|
+
conventional parent kind). `filter.kind` is validated against that live census,
|
|
265
|
+
so filtering by a never-used kind is a `validation` error naming the values
|
|
266
|
+
that do exist. This mirrors `status`, which is likewise an open catalog.
|
|
267
|
+
|
|
268
|
+
`query --input '{"view":"order","filter":{"plan":"<uid>"}}'`
|
|
269
|
+
returns a plan's members topologically ordered by their `blocks` edges. Note
|
|
270
|
+
the trap: the `catalog` selector is honoured only with `view:"catalogs"` โ
|
|
271
|
+
`{"catalog":"status"}` without it silently returns the ordinary `list` view
|
|
272
|
+
(never catalog `terms`). See
|
|
273
|
+
[`skill/SKILL.md` ยง6](skill/SKILL.md).
|
|
274
|
+
|
|
190
275
|
## Command surface
|
|
191
276
|
|
|
192
277
|
Every verb but `embedding-status` takes a single `--input` flag carrying one JSON
|
|
193
|
-
object;
|
|
194
|
-
`
|
|
278
|
+
object; `embedding-status` takes **no** options at all. **There are no per-field
|
|
279
|
+
flags** โ a per-field option (`get --uid โฆ`, `query --view list`, `create
|
|
280
|
+
--title โฆ`, `batch action --operation โฆ`) fails with `invalid_argument` (exit 2)
|
|
281
|
+
and `Unknown option: --<field>. Available: --input`. (`--help` prints a
|
|
282
|
+
"per-field flags are also accepted" footer line; it is generated boilerplate
|
|
283
|
+
that does not hold for these commands โ `--input` is the only option they
|
|
284
|
+
accept. The special commands `serve`, `install-skill`, and `search` are the
|
|
285
|
+
exception: they take argv flags and no `--input`.) Thirty operations (the
|
|
286
|
+
29 verbs plus `batch`):
|
|
195
287
|
|
|
196
288
|
| Verb | CLI | MCP tool |
|
|
197
289
|
| ----------------- | ------------------------------- | -------------------------- |
|
|
@@ -200,11 +292,20 @@ object; there are no per-field flags. Nineteen operations (the 18 verbs plus
|
|
|
200
292
|
| `priorityMatrix` | `adhd-backlog priority-matrix` | `backlog_priority_matrix` |
|
|
201
293
|
| `partOfRollup` | `adhd-backlog part-of-rollup` | `backlog_part_of_rollup` |
|
|
202
294
|
| `openCurve` | `adhd-backlog open-curve` | `backlog_open_curve` |
|
|
295
|
+
| `report` | `adhd-backlog report` | `backlog_report` |
|
|
203
296
|
| `embeddingStatus` | `adhd-backlog embedding-status` | `backlog_embedding_status` |
|
|
204
297
|
| `lookup` | `adhd-backlog lookup` | `backlog_lookup` |
|
|
205
298
|
| `create` | `adhd-backlog create` | `backlog_create` |
|
|
206
299
|
| `update` | `adhd-backlog update` | `backlog_update` |
|
|
300
|
+
| `addCitation` | `adhd-backlog add-citation` | `backlog_add_citation` |
|
|
301
|
+
| `removeCitation` | `adhd-backlog remove-citation` | `backlog_remove_citation` |
|
|
207
302
|
| `transition` | `adhd-backlog transition` | `backlog_transition` |
|
|
303
|
+
| `attest` | `adhd-backlog attest` | `backlog_attest` |
|
|
304
|
+
| `recheck` | `adhd-backlog recheck` | `backlog_recheck` |
|
|
305
|
+
| `obligate` | `adhd-backlog obligate` | `backlog_obligate` |
|
|
306
|
+
| `unobligate` | `adhd-backlog unobligate` | `backlog_unobligate` |
|
|
307
|
+
| `specAppend` | `adhd-backlog spec-append` | `backlog_spec_append` |
|
|
308
|
+
| `specCheck` | `adhd-backlog spec-check` | `backlog_spec_check` |
|
|
208
309
|
| `claim` | `adhd-backlog claim` | `backlog_claim` |
|
|
209
310
|
| `relate` | `adhd-backlog relate` | `backlog_relate` |
|
|
210
311
|
| `move` | `adhd-backlog move` | `backlog_move` |
|
|
@@ -213,15 +314,24 @@ object; there are no per-field flags. Nineteen operations (the 18 verbs plus
|
|
|
213
314
|
| `upsertComponent` | `adhd-backlog upsert-component` | `backlog_upsert_component` |
|
|
214
315
|
| `upsertLocation` | `adhd-backlog upsert-location` | `backlog_upsert_location` |
|
|
215
316
|
| `rmLocation` | `adhd-backlog rm-location` | `backlog_rm_location` |
|
|
317
|
+
| `mergeProject` | `adhd-backlog merge-project` | `backlog_merge_project` |
|
|
318
|
+
| `rmProject` | `adhd-backlog rm-project` | `backlog_rm_project` |
|
|
216
319
|
| `batch` | `adhd-backlog batch action` | `batch_action` |
|
|
217
320
|
|
|
218
321
|
`--help` prints these as `backlog <verb>`; the CLI also accepts the bare
|
|
219
322
|
`adhd-backlog <verb>` form shown above, and accepts the explicit namespace
|
|
220
|
-
prefix at any position. `get`/`query`/`lookup`/`embedding-status`
|
|
221
|
-
`create`/`update`/`
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
323
|
+
prefix at any position. `get`/`query`/`lookup`/`embedding-status` and the four
|
|
324
|
+
stats/rollup ops are reads. `create`/`update`/`add-citation`/`remove-citation`/
|
|
325
|
+
`transition`/`claim`/`relate`/`move`/`delete` mutate one issue;
|
|
326
|
+
`attest`/`recheck` record anchored evidence,
|
|
327
|
+
and `obligate`/`unobligate` declare or retire a typed requirement that gates a
|
|
328
|
+
transition ([SKILL.md ยง4](skill/SKILL.md)); `specAppend`/`specCheck` advance
|
|
329
|
+
and verify a ticket's spec revisions, and a revision is annotated through
|
|
330
|
+
`attest` with a `SPEC` subject + a `revision:` anchor ([SKILL.md
|
|
331
|
+
ยง5](skill/SKILL.md)). The
|
|
332
|
+
`upsert*`/`rmLocation` verbs manage the **registry** (projects, components,
|
|
333
|
+
locations), and `mergeProject`/`rmProject` collapse or retire project rows.
|
|
334
|
+
`batch action` fans any one of them out over many items.
|
|
225
335
|
|
|
226
336
|
## Transports
|
|
227
337
|
|
|
@@ -239,14 +349,45 @@ simultaneously true everywhere:
|
|
|
239
349
|
Every verb call returns one of two shapes, on every transport:
|
|
240
350
|
|
|
241
351
|
```ts
|
|
242
|
-
{ ok: true, data: T, warnings?: string[],
|
|
352
|
+
{ ok: true, data: T, warnings?: string[],
|
|
353
|
+
meta?: { total, returned, limit?, offset?, truncated?, total_relation?, has_more?, next_cursor? } }
|
|
243
354
|
{ ok: false, error: { code, message, details? }, warnings?: string[] }
|
|
244
355
|
```
|
|
245
356
|
|
|
246
|
-
`meta` is present on list
|
|
247
|
-
match count
|
|
248
|
-
|
|
249
|
-
|
|
357
|
+
`meta` is present on the four **item-list** reads (`query`'s `list`/`ready`/
|
|
358
|
+
`stale`/`similar` views). `total` is the match count; on `list` it is the exact
|
|
359
|
+
count _before_ `limit`/`offset`, while on `ready`/`stale`/`similar` a true
|
|
360
|
+
pre-limit total is unknowable at bounded cost, so `meta` reports
|
|
361
|
+
`has_more` (derived by fetching one row beyond the page) and labels `total`
|
|
362
|
+
with `total_relation: 'gte'` โ a lower bound, never a fabricated exact number
|
|
363
|
+
(`'eq'` means exact). `graph`/`order`/`overlap` are a graph, a topological
|
|
364
|
+
order, and an axis grouping โ they deliberately carry **no** `meta`, because
|
|
365
|
+
none of them is a filtered row set with an honest "how many matched" count.
|
|
366
|
+
|
|
367
|
+
> **`view:"ready"` is not an actionability filter.** It selects the `open`
|
|
368
|
+
> issues that are unclaimed and whose every live incoming `blocks` blocker is
|
|
369
|
+
> terminal โ a pure claim/`blocks` predicate that never evaluates obligations
|
|
370
|
+
> or evidence. An item with an unsatisfied `block`-severity obligation
|
|
371
|
+
> (`fields:["verdict"]` reports `actionable:false`) still appears in `ready`.
|
|
372
|
+
> To find actionable work, read `fields:["verdict"]`; do not use `ready`.
|
|
373
|
+
> Full definition: [`skill/SKILL.md` ยง3](skill/SKILL.md).
|
|
374
|
+
|
|
375
|
+
A derived `_score` always carries its provenance: `_score_kind` is `'rrf'`
|
|
376
|
+
(the fused text+vec rank `view:'similar'` and semantic list reads use),
|
|
377
|
+
`'bm25'` (a grep-only FTS score), `'cosine'`, `'rank'`, or `'priority'`. A
|
|
378
|
+
rank-derived `_score` is **ordinal** โ never read it as a similarity or a
|
|
379
|
+
confidence.
|
|
380
|
+
|
|
381
|
+
Sub-collections can be bounded: `get { fields:["auditTrail"], lastN:5 }`
|
|
382
|
+
returns at most the newest 5 audit rows (oldest-first order preserved);
|
|
383
|
+
`part-of-rollup { uid, countOnly:true }` returns the counts and omits
|
|
384
|
+
`childrenOpenUids` entirely, while `part-of-rollup { uid, limit, after }` pages
|
|
385
|
+
the open-descendant uid list (`nextCursor`/`hasMore`).
|
|
386
|
+
|
|
387
|
+
The `report` verb is a grouped rollup whose every number is computed from the
|
|
388
|
+
store in that call: `byKind`, `byPriority` (composed from `priority-matrix`),
|
|
389
|
+
`byStatus`, and `avgAgeDays` of open in-scope items, with `statusScope` naming
|
|
390
|
+
exactly what was counted (`'open'` when the filter omits `status`).
|
|
250
391
|
|
|
251
392
|
### Error codes
|
|
252
393
|
|
|
@@ -269,11 +410,20 @@ code alone.
|
|
|
269
410
|
|
|
270
411
|
### Citations & git context
|
|
271
412
|
|
|
272
|
-
A citation is `{ file, lines?, context?, symbol? }`.
|
|
273
|
-
`create`, or on the `transition` that moves an issue into a
|
|
274
|
-
when the project's policy requires it.
|
|
275
|
-
|
|
276
|
-
|
|
413
|
+
A citation is `{ file, lines?, context?, symbol?, blastRadius?, revision? }`.
|
|
414
|
+
Pass `citations` on `create`, or on the `transition` that moves an issue into a
|
|
415
|
+
terminal status when the project's policy requires it. Add one to an existing
|
|
416
|
+
issue with `add-citation` and retire one with `remove-citation` (addressed by
|
|
417
|
+
the citation's **own uid**, never by re-specifying `(file, lines)`). `update`
|
|
418
|
+
carries `citations` as a **diff-emitter** โ it adds what's new and removes what's
|
|
419
|
+
gone against the live set, in the same transaction, and never mints a new issue
|
|
420
|
+
uid (only a `body` edit supersedes). `file` must name a file, not a directory: a
|
|
421
|
+
directory target is rejected as a non-retryable `validation` error.
|
|
422
|
+
|
|
423
|
+
Pin a citation to a git revision with `revision` (a branch, tag, or sha) to cite
|
|
424
|
+
a file that exists **only on an unmerged branch** โ the target is read from
|
|
425
|
+
`git show <revision>:<path>` rather than the working tree, so the sha is a real
|
|
426
|
+
content hash even though the file is not checked out.
|
|
277
427
|
|
|
278
428
|
The item-level **`gitContext`** is separate from a citation's own `context`:
|
|
279
429
|
it records the repo disclosure contract's `<active git context>` โ the first
|
|
@@ -284,15 +434,17 @@ the item's `Citations:` block. Omit it and nothing is stored.
|
|
|
284
434
|
|
|
285
435
|
### Which build these docs describe
|
|
286
436
|
|
|
287
|
-
These docs describe `entrypoint/backlog/dist/index.js` built from revision
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
and
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
437
|
+
These docs describe `entrypoint/backlog/dist/index.js` built from the revision
|
|
438
|
+
captured here, which mounts 29 verbs โ including the citation
|
|
439
|
+
(`add-citation`/`remove-citation`), obligation
|
|
440
|
+
(`obligate`/`unobligate`), spec-pointer (`spec-append`/`spec-check`),
|
|
441
|
+
and catalog (`query --input '{"view":"catalogs"}'`) surfaces. A **globally
|
|
442
|
+
installed** `adhd-backlog` may be an older build (it is whatever was last
|
|
443
|
+
published/installed); on such a build `gitContext` may be rejected with
|
|
444
|
+
`invalid_argument`, and the stats/rollup ops (`priority-matrix` /
|
|
445
|
+
`part-of-rollup` / `open-curve` / `report`) and the obligation/spec verbs may be
|
|
446
|
+
absent. Run `adhd-backlog --help` and compare it against
|
|
447
|
+
[ยง1 of SKILL.md](skill/SKILL.md) if a documented field or verb is refused.
|
|
296
448
|
|
|
297
449
|
## Build & startup
|
|
298
450
|
|
|
@@ -322,29 +474,32 @@ the extract-stage IR cache, which persists the result for the next run.
|
|
|
322
474
|
and store-free (it never opens the graph store and never writes under
|
|
323
475
|
`~/.adhd`).
|
|
324
476
|
|
|
325
|
-
| Setting | Env var
|
|
326
|
-
| ---------------- |
|
|
327
|
-
| IR cache enabled | `APIGEN_IR_CACHE_ENABLED`
|
|
328
|
-
| IR cache file | `APIGEN_IR_CACHE_FILE`
|
|
477
|
+
| Setting | Env var | Default | Notes |
|
|
478
|
+
| ---------------- | ------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
479
|
+
| IR cache enabled | `APIGEN_IR_CACHE_ENABLED` | `1` | Governs ONLY the **runtime fallback** cache. It does **not** bypass the baked `api.ir.json` artifact โ that artifact is the startup path, not a cache |
|
|
480
|
+
| IR cache file | `APIGEN_IR_CACHE_FILE` | a machine-global path under `~/.adhd` | Where a fallback extraction's result is cached |
|
|
329
481
|
|
|
330
482
|
## Library API
|
|
331
483
|
|
|
332
484
|
Beyond the CLI/MCP/HTTP surface, the package exports its query layer
|
|
333
|
-
(`src/query/index.ts`), including
|
|
485
|
+
(`src/query/index.ts`), including four rollup/stats read ops that are **not**
|
|
334
486
|
members of `query.view`:
|
|
335
487
|
|
|
336
488
|
- `priorityMatrix(handle, { filter? })` โ a status-aware per-priority count
|
|
337
489
|
breakdown (defaults to open work; `filter.status` may be `'open'`, `'closed'`,
|
|
338
490
|
`'all'`, or a status name).
|
|
339
|
-
- `partOfRollup(handle, { uid })` โ transitive
|
|
340
|
-
issue, counted once each regardless of chain
|
|
491
|
+
- `partOfRollup(handle, { uid, countOnly?, limit?, after? })` โ transitive
|
|
492
|
+
`part_of` descendants of an issue, counted once each regardless of chain
|
|
493
|
+
depth; `countOnly` omits the uid list, `limit`/`after` page it.
|
|
341
494
|
- `openCurve(handle, { filter?, at })` โ per-sampled-instant counts of issues
|
|
342
495
|
that existed and how many were open, reconstructed from the audit trail.
|
|
496
|
+
- `report(handle, { filter? })` โ a grouped rollup (`byKind`/`byPriority`/
|
|
497
|
+
`byStatus`/`avgAgeDays`) composed from live reads in the same call.
|
|
343
498
|
|
|
344
|
-
Reach them by importing `@adhd/backlog` in-process. The same
|
|
345
|
-
mounted as operations โ `priority-matrix` / `part-of-rollup` / `open-curve`
|
|
346
|
-
the CLI (`backlog_priority_matrix` / `backlog_part_of_rollup` /
|
|
347
|
-
`backlog_open_curve` on MCP); see the command surface above.
|
|
499
|
+
Reach them by importing `@adhd/backlog` in-process. The same four are also
|
|
500
|
+
mounted as operations โ `priority-matrix` / `part-of-rollup` / `open-curve` /
|
|
501
|
+
`report` on the CLI (`backlog_priority_matrix` / `backlog_part_of_rollup` /
|
|
502
|
+
`backlog_open_curve` / `backlog_report` on MCP); see the command surface above.
|
|
348
503
|
|
|
349
504
|
## Configuration
|
|
350
505
|
|
|
@@ -361,7 +516,7 @@ into a narrower scope.
|
|
|
361
516
|
| Write busy timeout | `ADHD_BACKLOG_DATABASE_BUSY_TIMEOUT_MS` | `5000` | How long a write waits on a contended lock before giving up |
|
|
362
517
|
| Log level | `ADHD_BACKLOG_LOG_LEVEL` | `info` | `trace`\|`debug`\|`info`\|`warn`\|`error`\|`fatal`\|`silent` |
|
|
363
518
|
| Scope | `ADHD_BACKLOG_SCOPE` (falls back to `ADHD_ENV_SCOPE`) | `global` | Which store root to resolve against |
|
|
364
|
-
| Namespace | `--namespace <value>` CLI flag (no env var) | `production` | Which path segment under the scope root to resolve against (`<root>/backlog/<namespace>/โฆ`) โ one of `production`\|`test`\|`sandbox`. `--namespace sandbox` ALSO mints a fresh throwaway root and writes a real `config.yaml` there with `embedding.enabled: false`, so a sandboxed invocation is isolated along two independent axes plus a deliberate config, never an accident of an empty directory |
|
|
519
|
+
| Namespace | `--namespace <value>` CLI flag (no env var) | `production` | Which path segment under the scope root to resolve against (`<root>/backlog/<namespace>/โฆ`) โ one of `production`\|`test`\|`sandbox`. `--namespace sandbox` ALSO mints a fresh throwaway root and writes a real `config.yaml` there with `embedding.enabled: false`, so a sandboxed invocation is isolated along two independent axes plus a deliberate config, never an accident of an empty directory. It also **ignores a foreign `ADHD_ROOT`**: if the variable names a path this tool did not mint as a sandbox it warns `โฆ is not a sandbox this tool created โ ignoring it โฆ` and mints a fresh store instead, so a stray `ADHD_ROOT` can never redirect a sandboxed run into an unrecognized location. `adhd-backlog sandbox-path` reports the resolved store without opening it; its `adhdRoot` key is present only when a root was explicitly resolved (`ADHD_ROOT` set, or `--namespace sandbox`) and is omitted for the default `production`/`test` namespaces |
|
|
365
520
|
| Semantic search | `ADHD_BACKLOG_EMBEDDING_ENABLED` | `false` | See below |
|
|
366
521
|
| Embedding provider | `ADHD_BACKLOG_EMBEDDING_PROVIDER` | `fastembed` | Only consulted when embedding is enabled |
|
|
367
522
|
| Embedding model | `ADHD_BACKLOG_EMBEDDING_MODEL` | `bge-base-en-v1.5` (768-dim) | Only consulted when embedding is enabled |
|
package/api.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IMergeProjectInput, IMergeProjectOutcome, IRmProjectInput } from './write/merge-project.js';
|
|
1
2
|
import { IUpsertProjectInput, IUpsertProjectOutcome, IUpsertComponentInput, IUpsertComponentOutcome, IUpsertLocationInput, IUpsertLocationOutcome, IRmLocationInput, IRmLocationOutcome } from './write/catalog.js';
|
|
2
3
|
import { IDeleteIssueInput, IDeleteIssueOutcome } from './write/delete.js';
|
|
3
4
|
import { IMoveIssueInput, IMoveIssueOutcome } from './write/move.js';
|
|
@@ -7,6 +8,12 @@ import { ITransitionInput, ITransitionOutcome } from './write/transition.js';
|
|
|
7
8
|
import { IUpdateIssueInput, IUpdateIssueOutcome } from './write/update.js';
|
|
8
9
|
import { ICreateIssueInput, ICreateIssueResult } from './write/create-issue.js';
|
|
9
10
|
import { IIssueGetInput, IIssueGetResult, IIssueQueryInput, IIssueQueryResult, ILookupResult } from './query/types.js';
|
|
11
|
+
import { ISpecCheckInput, ISpecCheckOutcome } from './query/spec-staleness.js';
|
|
12
|
+
import { ISpecAppendInput, ISpecAppendOutcome } from './write/spec-revision.js';
|
|
13
|
+
import { IObligateInput, IObligateOutcome, IUnobligateInput, IUnobligateOutcome } from './write/obligation.js';
|
|
14
|
+
import { IAttestInput, IAttestOutcome, IRecheckInput, IRecheckOutcome } from './write/attestation.js';
|
|
15
|
+
import { IAddCitationInput, IAddCitationOutcome, IRemoveCitationInput, IRemoveCitationOutcome } from './write/citation.js';
|
|
16
|
+
import { IReportInput, IReportResult } from './query/views/report.js';
|
|
10
17
|
import { IPriorityMatrixInput, IPriorityMatrixResult, IPartOfRollupInput, IPartOfRollupResult, IOpenCurveInput, IOpenCurveResult } from './query/views/stats.js';
|
|
11
18
|
import { EmbeddingLiveConfig } from './write/embedding-config.js';
|
|
12
19
|
import { IOutcomeEnvelope } from './envelope.js';
|
|
@@ -93,6 +100,17 @@ export declare function partOfRollup(ctx: BacklogCtx, input: IPartOfRollupInput)
|
|
|
93
100
|
* `queryHandle` gates.
|
|
94
101
|
*/
|
|
95
102
|
export declare function openCurve(ctx: BacklogCtx, input: IOpenCurveInput): Promise<IOutcomeEnvelope<IOpenCurveResult>>;
|
|
103
|
+
/**
|
|
104
|
+
* SPEC.md ยง5 / DESIGN ยง5 AC7's grouped rollup โ counts by kind, by priority
|
|
105
|
+
* (composed from `priorityMatrix`), and by status, plus the average age of
|
|
106
|
+
* open in-scope items, every number computed from the store in THIS call.
|
|
107
|
+
*
|
|
108
|
+
* A read op, NOT a `query.view` member: it returns a named-scope aggregate
|
|
109
|
+
* (`statusScope` names what was counted) keyed by no list cursor. Uses only
|
|
110
|
+
* `handle.graph` โ see {@link priorityMatrix}'s note on the `queryHandle`
|
|
111
|
+
* gates.
|
|
112
|
+
*/
|
|
113
|
+
export declare function report(ctx: BacklogCtx, input: IReportInput): Promise<IOutcomeEnvelope<IReportResult>>;
|
|
96
114
|
/** The `embedding_status` read op's payload (see {@link embeddingStatus}). */
|
|
97
115
|
export interface IEmbeddingStatusResult {
|
|
98
116
|
/** The on-disk `embedding.enabled` (observed from the config layers). */
|
|
@@ -136,6 +154,7 @@ export declare function embeddingStatus(ctx: BacklogCtx): Promise<IOutcomeEnvelo
|
|
|
136
154
|
*/
|
|
137
155
|
export declare function lookup(ctx: BacklogCtx, input: {
|
|
138
156
|
q: string;
|
|
157
|
+
kind?: string;
|
|
139
158
|
}): Promise<IOutcomeEnvelope<ILookupResult>>;
|
|
140
159
|
/** File a new issue, minting its `uid` and linking it to a project component. */
|
|
141
160
|
export declare function create(ctx: BacklogCtx, input: ICreateIssueInput): Promise<IOutcomeEnvelope<ICreateIssueResult>>;
|
|
@@ -147,8 +166,60 @@ export declare function create(ctx: BacklogCtx, input: ICreateIssueInput): Promi
|
|
|
147
166
|
* use `transition`.
|
|
148
167
|
*/
|
|
149
168
|
export declare function update(ctx: BacklogCtx, input: IUpdateIssueInput): Promise<IOutcomeEnvelope<IUpdateIssueOutcome>>;
|
|
169
|
+
/**
|
|
170
|
+
* Add one first-class citation to an existing issue.
|
|
171
|
+
*
|
|
172
|
+
* Mints a `citation` node + its `has_citation` edge + an audit row, atomically.
|
|
173
|
+
* The citation may pin a git `revision` to cite evidence that exists only on an
|
|
174
|
+
* unmerged branch. `update` carries citations as a diff; this is the single-add
|
|
175
|
+
* form.
|
|
176
|
+
*/
|
|
177
|
+
export declare function addCitation(ctx: BacklogCtx, input: IAddCitationInput): Promise<IOutcomeEnvelope<IAddCitationOutcome>>;
|
|
178
|
+
/**
|
|
179
|
+
* Soft-remove one citation by the citation's OWN `uid` (never a
|
|
180
|
+
* `(target,line)` re-specification). Bi-temporally invalidates the citation
|
|
181
|
+
* node and its `has_citation` edge; the issue's uid is untouched.
|
|
182
|
+
*/
|
|
183
|
+
export declare function removeCitation(ctx: BacklogCtx, input: IRemoveCitationInput): Promise<IOutcomeEnvelope<IRemoveCitationOutcome>>;
|
|
150
184
|
/** Move an issue to a new status, recording the transition in its audit trail. */
|
|
151
185
|
export declare function transition(ctx: BacklogCtx, input: ITransitionInput): Promise<IOutcomeEnvelope<ITransitionOutcome>>;
|
|
186
|
+
/**
|
|
187
|
+
* Create a first-class attestation โ a separate record keyed to an issue by
|
|
188
|
+
* `{id, revision}`, never written into the issue. The subject's `uid` and
|
|
189
|
+
* revision are unchanged.
|
|
190
|
+
*/
|
|
191
|
+
export declare function attest(ctx: BacklogCtx, input: IAttestInput): Promise<IOutcomeEnvelope<IAttestOutcome>>;
|
|
192
|
+
/**
|
|
193
|
+
* Re-run an attestation's anchor ladder and APPEND the new check to its
|
|
194
|
+
* append-only `checks[]` history (never overwriting earlier checks).
|
|
195
|
+
*/
|
|
196
|
+
export declare function recheck(ctx: BacklogCtx, input: IRecheckInput): Promise<IOutcomeEnvelope<IRecheckOutcome>>;
|
|
197
|
+
/**
|
|
198
|
+
* Declare a typed requirement on an issue.
|
|
199
|
+
*
|
|
200
|
+
* The requirement is drawn from a closed predicate core
|
|
201
|
+
* (`evidence`/`blockers_terminal`/`relation`/`all_of`/`any_of`/`not`);
|
|
202
|
+
* `applies_to.to` is required. Nothing is evaluated here โ the C5 gate reads
|
|
203
|
+
* it at a transition and the C6 verdict predicts it on read.
|
|
204
|
+
*/
|
|
205
|
+
export declare function obligate(ctx: BacklogCtx, input: IObligateInput): Promise<IOutcomeEnvelope<IObligateOutcome>>;
|
|
206
|
+
/** Retire an obligation (bi-temporal; never a hard delete). */
|
|
207
|
+
export declare function unobligate(ctx: BacklogCtx, input: IUnobligateInput): Promise<IOutcomeEnvelope<IUnobligateOutcome>>;
|
|
208
|
+
/**
|
|
209
|
+
* Append a spec REVISION to a ticket (C10, DESIGN ยง12). A work product is a
|
|
210
|
+
* revision of its ticket: this mints a NEW immutable `SPEC` node holding the
|
|
211
|
+
* fragment and advances the ticket's `meta.spec_revision` pointer IN PLACE โ
|
|
212
|
+
* the ticket's uid is preserved and no prior revision is rewritten. The
|
|
213
|
+
* required `base_revision` is a CAS token: a stale value is refused with
|
|
214
|
+
* `precondition_failed` and nothing is written.
|
|
215
|
+
*/
|
|
216
|
+
export declare function specAppend(ctx: BacklogCtx, input: ISpecAppendInput): Promise<IOutcomeEnvelope<ISpecAppendOutcome>>;
|
|
217
|
+
/**
|
|
218
|
+
* Check whether a spec-revision `token` is still current for a ticket (C10).
|
|
219
|
+
* An ABSENT token is `stale` (`method:'none'`, `reason:'no-token-supplied'`),
|
|
220
|
+
* never `fresh`.
|
|
221
|
+
*/
|
|
222
|
+
export declare function specCheck(ctx: BacklogCtx, input: ISpecCheckInput): Promise<IOutcomeEnvelope<ISpecCheckOutcome>>;
|
|
152
223
|
/** Take, renew or release an exclusive working lease on an issue. */
|
|
153
224
|
export declare function claim(ctx: BacklogCtx, input: IClaimInput): Promise<IOutcomeEnvelope<IClaimOutcome>>;
|
|
154
225
|
/** Create or remove a typed relationship between two issues. */
|
|
@@ -180,6 +251,22 @@ export declare function upsertComponent(ctx: BacklogCtx, input: IUpsertComponent
|
|
|
180
251
|
export declare function upsertLocation(ctx: BacklogCtx, input: IUpsertLocationInput): Promise<IOutcomeEnvelope<IUpsertLocationOutcome>>;
|
|
181
252
|
/** Soft-remove a location by `uid`. */
|
|
182
253
|
export declare function rmLocation(ctx: BacklogCtx, input: IRmLocationInput): Promise<IOutcomeEnvelope<IRmLocationOutcome>>;
|
|
254
|
+
/**
|
|
255
|
+
* Merge duplicate project `fromUid` into the canonical survivor `toUid` (C1).
|
|
256
|
+
*
|
|
257
|
+
* One `BEGIN IMMEDIATE` transaction re-points every component the duplicate
|
|
258
|
+
* owned onto the survivor, soft-retires the duplicate with a one-hop
|
|
259
|
+
* `meta.redirectTo`, and audits. Idempotent on a repeat `(from,to)` call.
|
|
260
|
+
*/
|
|
261
|
+
export declare function mergeProject(ctx: BacklogCtx, input: IMergeProjectInput): Promise<IOutcomeEnvelope<IMergeProjectOutcome>>;
|
|
262
|
+
/**
|
|
263
|
+
* Soft-retire a project by `uid` WITHOUT a survivor (C1): stamps `t_invalid`
|
|
264
|
+
* with a reason and audits; no `redirectTo` is written.
|
|
265
|
+
*/
|
|
266
|
+
export declare function rmProject(ctx: BacklogCtx, input: IRmProjectInput): Promise<IOutcomeEnvelope<{
|
|
267
|
+
uid: string;
|
|
268
|
+
retired: true;
|
|
269
|
+
}>>;
|
|
183
270
|
/**
|
|
184
271
|
* SPEC ยง6.7 names this verb `delete` on every mount (`backlog_delete`,
|
|
185
272
|
* `backlog delete`, `DELETE /issue`). `export async function delete` is a
|