@carllee1983/dbcli 9.1.0 → 9.1.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "9.1.0",
3
+ "version": "9.1.2",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcli-agent",
3
- "version": "9.1.0",
3
+ "version": "9.1.2",
4
4
  "description": "Database CLI skill and command reference for AI agents",
5
5
  "author": {
6
6
  "name": "Carl Lee",
@@ -2,7 +2,7 @@
2
2
  "name": "dbcli-agent",
3
3
  "displayName": "dbcli Agent",
4
4
  "description": "Database CLI skill and command reference for AI agents.",
5
- "version": "9.1.0",
5
+ "version": "9.1.2",
6
6
  "author": {
7
7
  "name": "Carl Lee",
8
8
  "url": "https://github.com/CarlLee1983"
package/CHANGELOG.md CHANGED
@@ -5,6 +5,100 @@ All notable changes to dbcli are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [9.1.2] - 2026-10-01
9
+
10
+ 一個開發依賴的安全公告、工作規格協定從 ForgeFlow 換成 Warrant,以及三個讓測試與建置
11
+ 不再依賴執行順序或在磁碟上留下東西的修正。
12
+
13
+ 版本為 **9.1.2**。沒有任何指令、旗標、engine 或輸出改變。npm 套件唯一的差別是不再
14
+ 附帶 `.agents/skills/story-development/SKILL.md`——那是 dbcli 自己開發流程用的
15
+ skill,不是給使用者的。
16
+
17
+ ### Changed
18
+
19
+ - **工作規格改用 Warrant,ForgeFlow 的機制整套移除。** Story 從一個裝著
20
+ `story.md`/`acceptance.md`/`task.md` 的目錄,變成一個只有 Goal、Out of Scope、
21
+ Acceptance Criteria 三節的 `specs/stories/<slug>.md`;核准由人 commit 或在當次
22
+ session 明確指派,完成由 `make verify` 證明。ForgeFlow 留下的每一個決定都是在維護
23
+ 協定本身而不是 dbcli:adoption marker、範本、上游 contract job、`Story:` trailer
24
+ 對帳與 handoff 結構要彼此一致,代價是 `make verify` 裡的一道門、CI 的第二次
25
+ checkout、三支 checker 加上它們的函式庫與測試。這些都刪掉而不是停用,連同
26
+ `story-development` skill——它隨 `.agents/` 一起打包,所以已安裝的套件裡會少掉
27
+ 它。ForgePilot 仍是控制面,`DBCLI-*` 舊目錄原封保留為歷史紀錄。決定記在
28
+ ADR-0040,取代 ADR-0025、0027、0029、0031、0032 與 0036。
29
+
30
+ - **`assets/ui-template.html` 改為建置產物,不再進版控。** 每次 `bun run build` 都會
31
+ 重新產生並覆寫它,`prepublishOnly` 也在每次發佈前重建,所以 commit 裡那份從來不是
32
+ 使用者拿到的那份,只會跟建置結果漂移——每跑一次 `make verify` 就把 worktree 弄髒。
33
+ 現在它和 `dist/` 一樣列在 `.gitignore`,由 `build:determinism` 檢查兩次建置產出
34
+ 相同位元組,而每個會渲染 HTML 的測試自己建置所需的東西,不再靠前面的測試檔先建好。
35
+ 發佈出去的 template 仍由 `prepublishOnly` 建置,內容不變。決定記在 ADR-0041。
36
+
37
+ ### Fixed
38
+
39
+ - **Skill Author Integration Kit 的測試不再依賴執行順序。** 它以套件名
40
+ (`@carllee1983/dbcli/core`)import,解析到的是未進版控的 `dist/core.mjs`;靜態
41
+ import 只在更早的測試檔已建好 `dist/` 時才載入得了,CI 先跑它就在載入模組時失敗。
42
+ 改為在 `beforeAll` 建置後動態 import。
43
+
44
+ - **測試套件不再在 OS 暫存目錄留下東西。** 一次完整測試會在 `TMPDIR` 留下約 130 個
45
+ 目錄與檔案:每個測試都呼叫的 seed helper、`beforeAll`/`beforeEach` 建了卻沒有對應
46
+ 刪除的目錄、只還原 `HOME` 的 `finally`,以及直接寫進 `tmpdir()` 的設定檔。每個會
47
+ 外洩的檔案現在都以 repo 既有的寫法清掉自己建的東西;從空的 `TMPDIR` 開始跑,只剩
48
+ 第三方的 node-jiti 快取。
49
+
50
+ ### Security
51
+
52
+ - **`brace-expansion` 的 override 提高到 `^5.0.12`。** `bun run audit` 在
53
+ `brace-expansion@5.0.9` 回報三個漏洞(兩個 high、一個 moderate):
54
+ GHSA-qhr7-859c-m2p7、GHSA-6j4f-fj2g-mc7p、GHSA-q2hr-2g5m-vwhr。它經由 eslint 與
55
+ typescript-eslint 的 minimatch 引入,只存在於開發依賴,不在發佈的套件裡;提高既有的
56
+ override 就全部清掉。
57
+
58
+ ## [9.1.1] - 2026-09-15
59
+
60
+ 一個使用者回報的查詢缺陷(#197),一條會把人導向無效權限階的拒絕訊息,以及兩個
61
+ 會對同一個 commit 給出兩種答案、或只會叫「東西變了」的測試門檻。
62
+
63
+ 版本為 **9.1.1**。沒有新增指令、旗標或 engine;沒有任何一處拒絕先前被接受的輸入。
64
+ 唯一改變輸出的是拒絕訊息裡的 `required:` 欄位與它的句子——那個值先前是錯的,照它
65
+ 去要權限會被再拒一次,所以修正它不是相容性變更,是讓它開始為真。
66
+
67
+ ### Fixed
68
+
69
+ - **snippet 裡重複使用同一個具名參數,在 MySQL / MariaDB / SQLite 上不再炸。**
70
+ `rewriteToBind()` 對每一次 `:name` 出現輸出一個 placeholder,但 bind values 是由
71
+ 去重後的名稱清單映射出來的。PostgreSQL 重用 `$1`,一個值對一個索引本來就對;`?`
72
+ 沒有索引可以重用,所以 placeholder 數量跟著出現次數走、values 數量跟著相異名稱數
73
+ 走,兩者在有重複參數時必然對不上,MariaDB 以 `ER_WRONG_ARGUMENTS` 拒絕整條
74
+ statement。
75
+
76
+ 實務影響是「參數為 0 就查全部、否則查單一」這類條件在 snippet 裡寫不出來,只能
77
+ 繞道 CTE 讓參數只出現一次。`--dry-run` 看得到 SQL 與 bind values 不匹配,但不會
78
+ 報錯,所以問題要到真的執行才炸。非 PostgreSQL 引擎現在每一次出現送一個值,
79
+ PostgreSQL 的去重行為不變。(#197)
80
+
81
+ - **拒絕訊息指向的權限階,現在是真的會通過的那一階。** 無法分類的語句(`REPLACE
82
+ INTO`、`PRAGMA`、`VACUUM`、`REINDEX` 等)在 `query-only` 下被拒時宣稱需要
83
+ `read-write`,但沒有任何一階授予未知語句,取得 read-write 之後會再被拒一次。訊息
84
+ 與 `required:` 欄位現在都說 `admin`,en 與 zh-TW 同步。判決完全沒變:本來拒絕的仍
85
+ 然拒絕,本來允許的仍然允許。(DBCLI-037)
86
+
87
+ ### Changed
88
+
89
+ - **capability catalog 的輸出改由契約守住,不再由 sha256 守住。** 三份渲染
90
+ (JSON/text/Markdown)的凍結雜湊換成結構性斷言:文件在釘住的 schema 版本下
91
+ parse 得過、三份渲染列出同一組 capability、每個 capability 指的 command 是 CLI 真的
92
+ 帶得動的。catalog 是從 engine 矩陣推導出來的(ADR-0022),所以每次矩陣變動都會
93
+ 移動那三個雜湊,而修法永遠是把現在的值抄回去——連續三次之後,它報告的是 diff
94
+ 本來就說了的事。決定與被否決的選項記在 ADR-0039。使用者可見的輸出沒有變。
95
+ (DBCLI-038)
96
+
97
+ - **驗證 artifact 的秘密洩漏檢查改成逐欄檢查。** 原本在整份文件裡搜尋連線 port 的
98
+ 四位數字,而 artifact 帶一個隨機後綴的 id,後綴湊出那四位數字時測試會紅——什麼都
99
+ 沒洩漏,重跑就過。改為解析後逐欄走訪並指名帶著 port 的欄位;判準仍是包含而非
100
+ 相等,藏在連線字串裡的 port 照樣抓得到。(DBCLI-039)
101
+
8
102
  ## [9.1.0] - 2026-09-11
9
103
 
10
104
  ForgeFlow Story DBCLI-014 到 DBCLI-036 在 `v9.0.0` 之後交付。其中只有最後三張
package/README.md CHANGED
@@ -1722,28 +1722,20 @@ below: `package.json` and `src/` never mention them, `.forgepilot/` is
1722
1722
  gitignored local state, and a clone without any of them runs `make verify`
1723
1723
  normally.
1724
1724
 
1725
- ### How work is specified and reviewed: ForgeFlow
1726
-
1727
- Each unit of work is a Story under `specs/stories/`, made of a `story.md` (the
1728
- intent boundary) and an `acceptance.md` (the criteria). That shape is not a
1729
- local convention — it is upstream ForgeFlowV2's contract. The adopted version
1730
- and revision are pinned in `specs/.forgeflow-adoption`, and the CI
1731
- `forgeflow-contract` job clones **that exact revision** and runs upstream's own
1732
- checkers against this repository (`bun run forgeflow:contract`, which needs
1733
- `FORGEFLOW_ROOT`). The contract is executed by upstream's code rather than
1734
- reimplemented here, because two implementations of one contract diverge on a
1735
- schedule nobody controls (ADR-0027).
1736
-
1737
- A Story declaring itself security sensitive must enumerate its trust-boundary
1738
- fields and a security fixture matrix, and **every cell must be an exact value**
1739
- rather than prose. That rule catches more than wording: clearing the last of it
1740
- turned up three fixture rows that asserted nothing at all, and one row
1741
- describing a mechanism that does not exist.
1742
-
1743
- The exemption list in `scripts/lib/forgeflow-contract.ts` is a ratchet that may
1744
- shrink and never grow. It is currently empty, so any finding at all fails the
1745
- gate; adding an entry back requires lowering — never raising — the two counts
1746
- beside it, which a test enforces.
1725
+ ### How work is specified: Warrant
1726
+
1727
+ Each unit of work is a Story: one file, `specs/stories/<slug>.md`, with exactly
1728
+ three sections — Goal, Out of Scope, and Acceptance Criteria. A Story is
1729
+ approved only when a human commits it to the default branch or explicitly
1730
+ assigns it in the current session; an agent never approves its own. The
1731
+ contract agents follow is the `## Warrant` section of `AGENTS.md`, and
1732
+ `specs/stories/README.md` describes the format. The `DBCLI-*` directories under
1733
+ `specs/stories/` are legacy records from an earlier protocol, not pending work.
1734
+
1735
+ Warrant defines what a Story must contain and what counts as evidence: every
1736
+ acceptance criterion needs a reproducible observation, and the requirements,
1737
+ criteria, and scope stay as the human approved them. ForgePilot and
1738
+ `make verify` decide when it is done.
1747
1739
 
1748
1740
  ### When work is done: ForgePilot and `make verify`
1749
1741
 
@@ -1761,35 +1753,16 @@ no completion command — only a human can approve.
1761
1753
 
1762
1754
  A decision that is hard to reverse, surprising without context, or the result of
1763
1755
  a real trade-off gets a record in `docs/adr/`, named `ADR-<digits>-<slug>.md`
1764
- with its status as a `* Status:` bullet rather than front matter. That shape
1765
- exists so a Story's `Decision:` field resolves to it mechanically (ADR-0029).
1766
- Open questions live there as `status: proposed`; undecided is a state that has
1767
- to be storable.
1756
+ with its status as a `* Status:` bullet rather than front matter. A record that
1757
+ is replaced stays in `docs/adr/` with `* Status: superseded` and a
1758
+ `* Superseded by:` bullet naming its successor. Open questions live there as
1759
+ `status: proposed`; undecided is a state that has to be storable.
1768
1760
 
1769
1761
  Prefer closing a record with a falsification condition — one sentence saying
1770
1762
  when the decision would no longer hold — naming the files it depends on in
1771
1763
  backticks. Tooling reads the boundary list from those backticks, so the marker
1772
1764
  is load-bearing rather than decorative.
1773
1765
 
1774
- ### The principle behind all of it
1775
-
1776
- Every gate here is a variation on one lesson: **a declaration nothing compares
1777
- to anything is not a control.** Delivery claims in the handoff are reconciled
1778
- against commit trailers; the adopted ForgeFlow version is reconciled against
1779
- every place that restates it; the ForgeFlow contract itself is run against a
1780
- pinned upstream revision.
1781
-
1782
- The lesson has a limit, and finding it cost a decision. A Story's `## Authority`
1783
- was briefly reconciled against the fact of its delivery, on the reasoning that
1784
- reaching `main` requires commits on a pushed branch (ADR-0030). It does — but
1785
- `completed_stories` records that a Story was delivered, not **who** performed
1786
- each operation, and the normal flow here is an agent that is granted `modify` and
1787
- a local `commit` handing its branch to a human who pushes and merges. The gate
1788
- refused that flow by name, so the rule was removed (ADR-0031). Whether an
1789
- Authority declaration is true is a question this repository cannot observe and
1790
- Human Review can; a gate that guesses at it is worse than an unchecked
1791
- declaration, because its verdict looks like evidence.
1792
-
1793
1766
  ---
1794
1767
 
1795
1768
  ## License