kibi-cursor 2.10.0 → 2.11.0
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/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +91 -0
- package/README.md +21 -3
- package/agent-plugin/plugin.json +1 -1
- package/agent-plugin/skills/kibi-commit-review/SKILL.md +6 -2
- package/agent-plugin/skills/kibi-decisions/SKILL.md +7 -2
- package/agent-plugin/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/agent-plugin/skills/kibi-usage/SKILL.md +14 -3
- package/agent-plugin/skills/kibi-usage/resources/prolog-proofs.md +207 -0
- package/agent-plugin/skills/kibi-usage/resources/proof.md +44 -3
- package/bin/hook-runner.mjs +3233 -0
- package/bin/launch-kibi-mcp.mjs +2 -1
- package/dist/.cursor-plugin/plugin.json +1 -1
- package/dist/bin/hook-runner.mjs +3233 -0
- package/dist/bin/launch-kibi-mcp.mjs +2 -1
- package/dist/hook-runner.js +245 -200
- package/dist/hooks/hooks.json +6 -6
- package/dist/skills/.canon-hash.json +6 -5
- package/dist/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/skills/kibi-usage/SKILL.md +14 -3
- package/dist/skills/kibi-usage/resources/prolog-proofs.md +207 -0
- package/dist/skills/kibi-usage/resources/proof.md +44 -3
- package/hooks/hooks.json +6 -6
- package/package.json +5 -3
- package/skills/.canon-hash.json +6 -5
- package/skills/kibi-commit-review/SKILL.md +6 -2
- package/skills/kibi-decisions/SKILL.md +7 -2
- package/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/skills/kibi-usage/SKILL.md +14 -3
- package/skills/kibi-usage/resources/prolog-proofs.md +207 -0
- package/skills/kibi-usage/resources/proof.md +44 -3
|
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
|
|
|
51
51
|
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
52
52
|
each answer into `answer`, render again, and record the rules only once every
|
|
53
53
|
question is answered. An answer is the person's words: quote it in
|
|
54
|
-
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
`origin.ref`; a view itself is never an approval. Record the answers on the
|
|
55
|
+
branch of the change they approve and push them to its pull request, never to
|
|
56
|
+
a separate one.
|
|
55
57
|
|
|
56
58
|
## Summary contents
|
|
57
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.40.1
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -20,6 +20,7 @@ resources:
|
|
|
20
20
|
- resources/fact-lanes.md
|
|
21
21
|
- resources/workflows.md
|
|
22
22
|
- resources/proof.md
|
|
23
|
+
- resources/prolog-proofs.md
|
|
23
24
|
- resources/ui-requirements.md
|
|
24
25
|
- resources/logic-ir.md
|
|
25
26
|
- resources/kb-improvement.md
|
|
@@ -94,8 +95,10 @@ it is a pointer to the knowledge, never proof. Each line answers one question:
|
|
|
94
95
|
requirement first. Read the lead requirement with `kb_query({id})` before
|
|
95
96
|
changing behavior; add `includeBody: true` to see its authored prose, and
|
|
96
97
|
fix a stale sentence there with `kb_upsert` `document.body`.
|
|
97
|
-
- `REQ-… must keep true:
|
|
98
|
-
|
|
98
|
+
- `REQ-… must keep true: <claim>` (edit only): what the lead requirement
|
|
99
|
+
requires, as the claims its facts model (with the operator and members,
|
|
100
|
+
such as "The greet function must not call console.log") or, without
|
|
101
|
+
them, its own statement. An edit that breaks one of them is a requirement
|
|
99
102
|
change: ask before changing the rule (see Decision firmness), and never
|
|
100
103
|
code around the fact.
|
|
101
104
|
- `Decision: ADR-…` (edit only): the decision behind the lead requirement.
|
|
@@ -372,6 +375,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
372
375
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
373
376
|
exists in `rationale`, or link the ADR that explains it.
|
|
374
377
|
|
|
378
|
+
A signoff belongs to the change it approves. Ask for it before you open or
|
|
379
|
+
merge the pull request, and when the person answers, record their answer
|
|
380
|
+
(`approved_by` or a `*_waiver_approved_by` field set to them, their words in
|
|
381
|
+
`origin.ref` or `approval_ref`) on the same branch and push it to the same pull
|
|
382
|
+
request. Writing down an answer the person gave is not approving it yourself.
|
|
383
|
+
Never open a separate pull request only to carry a signoff, firmness or waiver
|
|
384
|
+
approval.
|
|
385
|
+
|
|
375
386
|
## Decision firmness
|
|
376
387
|
|
|
377
388
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# SWI-Prolog Code Proofs
|
|
2
|
+
|
|
3
|
+
Kibi reads code models from SWI-Prolog files (`.pl`, `.plt`) with the
|
|
4
|
+
SWI-Prolog it runs on (KIBI_SWIPL, the bundled runtime, then `swipl` on
|
|
5
|
+
PATH). It loads the file a symbol names (a module, or a plain file into
|
|
6
|
+
`user`) and reads a predicate named by its indicator, the symbol's title
|
|
7
|
+
(`operator/2`, `lists:append/3`, `greeting//1`) or `export`.
|
|
8
|
+
|
|
9
|
+
- A domain (`exhaustive`, `domains`, `value_source` with `measure: count`)
|
|
10
|
+
is the distinct solutions of one argument. A one-argument predicate needs
|
|
11
|
+
nothing more; for more arguments set `arg` (1-based) to the one that names
|
|
12
|
+
each member: `domain_source: {symbol_id: SYM-operator, arg: 1}` lists every
|
|
13
|
+
`Name` of `operator(Name, Description)`. A solution that leaves that
|
|
14
|
+
argument unbound refuses the read.
|
|
15
|
+
- A value (`value_source`) is the single number a constant holds:
|
|
16
|
+
`hard_limit_seconds(10).` Zero or several solutions refuse the read.
|
|
17
|
+
- A `rule` predicate is called once per row of its argument domains; success
|
|
18
|
+
is true, failure false, an exception an error row (which rejects).
|
|
19
|
+
- A `state_machine` transition table is a `Name/2` (from, to) or `Name/3`
|
|
20
|
+
(from, event, to) fact table: every solution is an edge. With `domains:
|
|
21
|
+
{state, event}` a `Name/3` next-state predicate is called on every state
|
|
22
|
+
and event. `initial_source` names an `initial/1`-style fact.
|
|
23
|
+
- A `regex` reads an atom or string constant as a `type: string` pattern;
|
|
24
|
+
Kibi decides string facts on it. Patterns for `library(pcre)` are not read.
|
|
25
|
+
|
|
26
|
+
Loading a module runs its directives, the same trust a JavaScript import
|
|
27
|
+
gives. The proof file must name the predicate and load its file
|
|
28
|
+
(`use_module`, `ensure_loaded`, `consult`, a `:- [..]` load list, or
|
|
29
|
+
`library(X)` for a pack's `prolog/X.pl`), or be the plunit `.plt` file
|
|
30
|
+
beside it; otherwise Kibi treats the domain as hand-listed. `arg` on a
|
|
31
|
+
TypeScript, JavaScript or Python export is refused, and so is `field` on a
|
|
32
|
+
Prolog predicate.
|
|
33
|
+
|
|
34
|
+
## Writing the certificate
|
|
35
|
+
|
|
36
|
+
A Prolog test writes the `kibi.code-certificate.v1` JSON into the directory
|
|
37
|
+
`kibi prove` sets in `KIBI_PROOF_CERTIFICATES`. Copy this module into the
|
|
38
|
+
project's test directory (for example `test/kibi_certificate.pl`) and call it
|
|
39
|
+
from the proof. Read members from the code with `findall/3` over the domain
|
|
40
|
+
predicate; never list them by hand.
|
|
41
|
+
|
|
42
|
+
```prolog
|
|
43
|
+
:- module(kibi_certificate,
|
|
44
|
+
[ kibi_exhaustive_certificate/5, % +TestId, +SymbolId, +Members, :Check, -Certificate
|
|
45
|
+
kibi_rule_certificate/4, % +TestId, +Domains, +Predicates, -Certificate
|
|
46
|
+
kibi_machine_certificate/5, % +TestId, +SymbolId, +Edges, +Initial, -Certificate
|
|
47
|
+
kibi_pattern_certificate/4, % +TestId, +SymbolId, +Text, -Certificate
|
|
48
|
+
kibi_write_certificate/1 % +Certificate
|
|
49
|
+
]).
|
|
50
|
+
:- use_module(library(http/json)).
|
|
51
|
+
:- use_module(library(apply)).
|
|
52
|
+
:- use_module(library(lists)).
|
|
53
|
+
|
|
54
|
+
:- meta_predicate
|
|
55
|
+
kibi_exhaustive_certificate(+, +, +, 1, -).
|
|
56
|
+
|
|
57
|
+
% Members as Kibi reads them: atoms and strings as text, numbers as written,
|
|
58
|
+
% other terms quoted.
|
|
59
|
+
kibi_text(Value, Text) :- string(Value), !, Text = Value.
|
|
60
|
+
kibi_text(Value, Text) :- atom(Value), !, atom_string(Value, Text).
|
|
61
|
+
kibi_text(Value, Text) :- number(Value), !, number_string(Value, Text).
|
|
62
|
+
kibi_text(Value, Text) :- format(string(Text), "~q", [Value]).
|
|
63
|
+
|
|
64
|
+
%! kibi_exhaustive_certificate(+TestId, +SymbolId, +Members, :Check, -Certificate)
|
|
65
|
+
%
|
|
66
|
+
% Run Check on every member of the domain and record each outcome. Read
|
|
67
|
+
% Members from the code (findall over the domain predicate), never list
|
|
68
|
+
% them by hand: Kibi re-reads the predicate and rejects a different set.
|
|
69
|
+
kibi_exhaustive_certificate(TestId, SymbolId, Members, Check, Certificate) :-
|
|
70
|
+
maplist(kibi_text, Members, Texts),
|
|
71
|
+
maplist(exhaustive_result(Check), Members, Texts, Results),
|
|
72
|
+
Certificate = _{version: "kibi.code-certificate.v1", kind: "exhaustive",
|
|
73
|
+
test_id: TestId,
|
|
74
|
+
domain: _{symbol_id: SymbolId, members: Texts},
|
|
75
|
+
results: Results}.
|
|
76
|
+
|
|
77
|
+
exhaustive_result(Check, Member, Text, Result) :-
|
|
78
|
+
catch(( call(Check, Member)
|
|
79
|
+
-> Result = _{member: Text, outcome: "passed"}
|
|
80
|
+
; Result = _{member: Text, outcome: "failed", message: "the check failed"}
|
|
81
|
+
),
|
|
82
|
+
Error,
|
|
83
|
+
( message_to_text(Error, Message),
|
|
84
|
+
Result = _{member: Text, outcome: "failed", message: Message} )).
|
|
85
|
+
|
|
86
|
+
%! kibi_rule_certificate(+TestId, +Domains, +Predicates, -Certificate)
|
|
87
|
+
%
|
|
88
|
+
% Domains is a list of domain(Type, SymbolId, Members); Predicates a list
|
|
89
|
+
% of predicate(Name, SymbolId, ArgTypes, Goal), where Goal is called with
|
|
90
|
+
% one argument per type appended and decides the row by success or
|
|
91
|
+
% failure.
|
|
92
|
+
kibi_rule_certificate(TestId, Domains, Predicates, Certificate) :-
|
|
93
|
+
findall(Type-_{symbol_id: SymbolId, members: Texts},
|
|
94
|
+
( member(domain(Type, SymbolId, Members), Domains), maplist(kibi_text, Members, Texts) ),
|
|
95
|
+
DomainPairs),
|
|
96
|
+
dict_pairs(DomainDict, _, DomainPairs),
|
|
97
|
+
findall(Name-_{symbol_id: SymbolId, arg_types: ArgTypes, rows: Rows},
|
|
98
|
+
( member(predicate(Name, SymbolId, ArgTypes, Goal), Predicates),
|
|
99
|
+
maplist(domain_members(Domains), ArgTypes, Lists),
|
|
100
|
+
findall(Row, (maplist(member, Tuple, Lists), rule_row(Goal, Tuple, Row)), Rows)
|
|
101
|
+
),
|
|
102
|
+
PredicatePairs),
|
|
103
|
+
dict_pairs(PredicateDict, _, PredicatePairs),
|
|
104
|
+
Certificate = _{version: "kibi.code-certificate.v1", kind: "rule",
|
|
105
|
+
test_id: TestId, domains: DomainDict, predicates: PredicateDict}.
|
|
106
|
+
|
|
107
|
+
domain_members(Domains, Type, Members) :-
|
|
108
|
+
memberchk(domain(Type, _, Members), Domains).
|
|
109
|
+
|
|
110
|
+
rule_row(Goal, Tuple, Row) :-
|
|
111
|
+
maplist(kibi_text, Tuple, Args),
|
|
112
|
+
Call =.. [call, Goal|Tuple],
|
|
113
|
+
catch(( once(Call) -> Row = _{args: Args, value: true} ; Row = _{args: Args, value: false} ),
|
|
114
|
+
Error,
|
|
115
|
+
( message_to_text(Error, Message), Row = _{args: Args, error: Message} )).
|
|
116
|
+
|
|
117
|
+
%! kibi_machine_certificate(+TestId, +SymbolId, +Edges, +Initial, -Certificate)
|
|
118
|
+
%
|
|
119
|
+
% Edges is the list of From-To pairs of the transition table (findall over
|
|
120
|
+
% it); Initial is the list of initial states, or [] when the contract names
|
|
121
|
+
% no initial_source.
|
|
122
|
+
kibi_machine_certificate(TestId, SymbolId, Edges, Initial, Certificate) :-
|
|
123
|
+
findall([F, T], (member(From-To, Edges), kibi_text(From, F), kibi_text(To, T)), Pairs0),
|
|
124
|
+
sort(Pairs0, Pairs),
|
|
125
|
+
findall(S, (member([A, B], Pairs), member(S, [A, B])), Ends),
|
|
126
|
+
sort(Ends, States),
|
|
127
|
+
Machine0 = _{symbol_id: SymbolId, states: States, transitions: Pairs},
|
|
128
|
+
( Initial == []
|
|
129
|
+
-> Machine = Machine0
|
|
130
|
+
; maplist(kibi_text, Initial, InitialTexts0),
|
|
131
|
+
sort(InitialTexts0, InitialTexts),
|
|
132
|
+
Machine = Machine0.put(initial, InitialTexts)
|
|
133
|
+
),
|
|
134
|
+
Certificate = _{version: "kibi.code-certificate.v1", kind: "state_machine",
|
|
135
|
+
test_id: TestId, machine: Machine}.
|
|
136
|
+
|
|
137
|
+
%! kibi_pattern_certificate(+TestId, +SymbolId, +Text, -Certificate)
|
|
138
|
+
%
|
|
139
|
+
% The string or atom constant a string claim is about.
|
|
140
|
+
kibi_pattern_certificate(TestId, SymbolId, Value, Certificate) :-
|
|
141
|
+
kibi_text(Value, Text),
|
|
142
|
+
Certificate = _{version: "kibi.code-certificate.v1", kind: "regex", test_id: TestId,
|
|
143
|
+
pattern: _{symbol_id: SymbolId, type: "string", value: Text}}.
|
|
144
|
+
|
|
145
|
+
%! kibi_write_certificate(+Certificate)
|
|
146
|
+
%
|
|
147
|
+
% Leave the certificate where kibi prove reads it (the directory in
|
|
148
|
+
% KIBI_PROOF_CERTIFICATES). Does nothing outside a kibi prove run.
|
|
149
|
+
kibi_write_certificate(Certificate) :-
|
|
150
|
+
( getenv('KIBI_PROOF_CERTIFICATES', Directory), Directory \== ''
|
|
151
|
+
-> make_directory_path(Directory),
|
|
152
|
+
format(atom(Name), "~w.json", [Certificate.test_id]),
|
|
153
|
+
directory_file_path(Directory, Name, File),
|
|
154
|
+
setup_call_cleanup(open(File, write, Out, [encoding(utf8)]),
|
|
155
|
+
json_write_dict(Out, Certificate, [width(0)]),
|
|
156
|
+
close(Out))
|
|
157
|
+
; true
|
|
158
|
+
).
|
|
159
|
+
|
|
160
|
+
message_to_text(Error, Text) :-
|
|
161
|
+
catch(message_to_codes(Error, Text), _, fail), !.
|
|
162
|
+
message_to_text(Error, Text) :- format(string(Text), "~q", [Error]).
|
|
163
|
+
|
|
164
|
+
message_to_codes(Error, Text) :-
|
|
165
|
+
'$messages':translate_message(Error, Lines, []),
|
|
166
|
+
with_output_to(string(Raw), print_message_lines(current_output, '', Lines)),
|
|
167
|
+
split_string(Raw, "", "\n ", [Text]).
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A proof that the operators are exactly the claimed set:
|
|
171
|
+
|
|
172
|
+
```prolog
|
|
173
|
+
:- use_module('../prolog/operators').
|
|
174
|
+
:- use_module(kibi_certificate).
|
|
175
|
+
:- initialization(main, main).
|
|
176
|
+
|
|
177
|
+
main :-
|
|
178
|
+
findall(Name, operator(Name, _), Names0),
|
|
179
|
+
list_to_set(Names0, Names),
|
|
180
|
+
kibi_exhaustive_certificate('TEST-operator-set', 'SYM-operator', Names,
|
|
181
|
+
[Name]>>operator(Name, _), Certificate),
|
|
182
|
+
kibi_write_certificate(Certificate).
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Its contract: `kind: exhaustive`, `domain_source: {symbol_id: SYM-operator,
|
|
186
|
+
arg: 1}`, `proves: [CLAIM-...]`. A rule proof passes
|
|
187
|
+
`[domain(status, 'SYM-status', Statuses)]` and
|
|
188
|
+
`[predicate(detected, 'SYM-detected', [status], detected)]`; its contract
|
|
189
|
+
names `predicate_source: {detected: {symbol_id: SYM-detected}}` and
|
|
190
|
+
`domains: {status: {symbol_id: SYM-status}}`.
|
|
191
|
+
|
|
192
|
+
## Source proofs over Prolog code
|
|
193
|
+
|
|
194
|
+
A `source` proof needs no certificate: Kibi reads the Prolog files itself,
|
|
195
|
+
term by term, and never runs them. Use the `references` reader on `.pl` and
|
|
196
|
+
`.plt` files for what modules load (`extract: imports`, members as written:
|
|
197
|
+
`library(lists)`, `helpers`), call (`calls`, `Name/Arity` or
|
|
198
|
+
`Module:Name/Arity`), read from the environment (`env`, `getenv/2`), pass as
|
|
199
|
+
a first argument (`string_args` with `callee`) and throw (`thrown`: the error
|
|
200
|
+
of `error(type_error(...), _)` is `type_error`). Use the `prolog` reader for
|
|
201
|
+
facts: `{reader: prolog, file: pack.pl, functor: requires/1}` lists a pack's
|
|
202
|
+
requirements, and `arg` picks the argument of a fact with several. A goal or
|
|
203
|
+
closure held in a variable (`call(Goal)`, `maplist(G, L)`), a goal with a
|
|
204
|
+
variable module, a clause asserted from a variable and `:- if(...)` fail the
|
|
205
|
+
read with their place: name the predicate instead. The claim cannot be
|
|
206
|
+
decided for a file the read refuses; never drop a file the claim is about
|
|
207
|
+
from `files`.
|
|
@@ -262,11 +262,15 @@ left:
|
|
|
262
262
|
each list item, such as the `run` of each workflow step), `glob` (`pattern`, `capture`),
|
|
263
263
|
`openapi` (`file`, `select: operations|unsecured_operations|...`),
|
|
264
264
|
`references` (`files`, `extract: env|imports|calls|string_args|thrown|
|
|
265
|
-
property
|
|
265
|
+
property`; TypeScript, JavaScript, Python and SWI-Prolog files, and Go,
|
|
266
|
+
Java, C# and Rust files through `kibi-plugin-treesitter`), `schema` (`format: drizzle|prisma|sql`, `select:
|
|
266
267
|
tables|columns|required_columns|nullable_columns|foreign_keys`), `routes`
|
|
267
268
|
(Hono or Express app export, `path_prefix`, `names_from`, `select:
|
|
268
269
|
routes|middleware`) or `validator` (zod, valibot or pydantic, `select:
|
|
269
|
-
fields|required_fields|optional_fields`)
|
|
270
|
+
fields|required_fields|optional_fields`) or `prolog` (`file`, `functor:
|
|
271
|
+
requires/1`, `arg`: one argument of each fact, such as a pack's
|
|
272
|
+
requirements in `pack.pl`). Prolog files are read term by term and never
|
|
273
|
+
run; see `resources/prolog-proofs.md`. A member Kibi cannot read
|
|
270
274
|
statically (a computed env name, a dynamic import, an env object handed
|
|
271
275
|
to a variable) fails the read with its location, and so does an empty
|
|
272
276
|
read (a glob matching no file, migrations with no `CREATE TABLE`), so a
|
|
@@ -288,6 +292,40 @@ left:
|
|
|
288
292
|
The builders need kibi-cli 2.33.0 or newer in the project. The env
|
|
289
293
|
extractor reads `process.env`, `import.meta.env`, `Bun.env`,
|
|
290
294
|
`Deno.env.get`, `os.environ` and `os.getenv`, through casts.
|
|
295
|
+
- `references` over Go, Java, C# or Rust needs `kibi-plugin-treesitter` and
|
|
296
|
+
the language's grammar pack (`kibi-lang-go`, `kibi-lang-java`,
|
|
297
|
+
`kibi-lang-csharp`, `kibi-lang-rust`) in `devDependencies`, with the
|
|
298
|
+
plugin activated for proofs:
|
|
299
|
+
`"kibi.reference-extractor.v1": { "mode": "augment" }` in its
|
|
300
|
+
`kibi.plugins` entry (next to `"kibi.symbol-extractor.v2"`). A project
|
|
301
|
+
with no `package.json` creates one that only holds this list. Without it
|
|
302
|
+
the read is refused with what to install, so ask the operator before
|
|
303
|
+
installing; `kibi doctor` names what the project needs. Members are
|
|
304
|
+
written as the code names them (`os.Getenv`, `System.out.println`,
|
|
305
|
+
`Console.WriteLine`, `std::env::var`, Go import paths, `java.util.*`,
|
|
306
|
+
`std::io::Write`); a method on an expression Kibi cannot name is
|
|
307
|
+
`*.name`. Reflection, a name computed at run time, the whole
|
|
308
|
+
environment, C# `dynamic` and `#if`, Rust `#[cfg(...)]` items other than
|
|
309
|
+
`#[cfg(test)]`, and any macro for Rust `calls` and `thrown` fail the
|
|
310
|
+
read with their place: the claim cannot be decided for that file, so
|
|
311
|
+
model a claim the code can show (Rust `calls` over a file with
|
|
312
|
+
`println!` is always refused). Never drop a file the claim is about
|
|
313
|
+
from `files`: the read decides a claim only for the files it covers,
|
|
314
|
+
and a proof is rejected when a symbol the test covers or that
|
|
315
|
+
implements the claim's requirement lies outside them.
|
|
316
|
+
- Reference members match by name segments (`.`, `/`, `::`). `excludes`
|
|
317
|
+
fails on anything that is or may be an excluded item: `java.sql`
|
|
318
|
+
excludes `java.sql.Connection`, `github.com/labstack/echo/v4` excludes
|
|
319
|
+
`.../echo/v4/middleware`, a trailing `*` is a prefix (`java.sql.*`), a
|
|
320
|
+
wildcard import or a shorter name (`File.delete`) may be the item, and
|
|
321
|
+
`*.delete` (a call on a receiver Kibi cannot name) may be
|
|
322
|
+
`java.io.File.delete`, so the claim is refused naming it. `includes` and
|
|
323
|
+
`subset_of` count only members that certainly are an item (the item, a
|
|
324
|
+
member under `X.*`, or `a.b.m` for `*.m`); `eq` compares spellings.
|
|
325
|
+
- For a claim about what the code reads from the environment use
|
|
326
|
+
`extract: env`: `string_args` on a getter (`os.Getenv`, `env::var`,
|
|
327
|
+
`System.getenv`, `getenv/2`, ...) sees only that getter, so Kibi refuses
|
|
328
|
+
it for `eq`, `subset_of` and `excludes`.
|
|
291
329
|
|
|
292
330
|
`arithmetic` and `smt` from `constraint_source` alone prove that the
|
|
293
331
|
knowledge base's facts entail the claim, not that code follows the facts:
|
|
@@ -318,7 +356,10 @@ read for a test that wants to assert on it), fail the test when it records a fai
|
|
|
318
356
|
(`failedMembers`, `failedCalls`), and call `writeCodeCertificate`; it writes to the
|
|
319
357
|
directory `kibi prove` sets in `KIBI_PROOF_CERTIFICATES` and does nothing
|
|
320
358
|
elsewhere. A Python test writes the same `kibi.code-certificate.v1` JSON
|
|
321
|
-
to that directory itself.
|
|
359
|
+
to that directory itself. Kibi also reads SWI-Prolog domains, constants,
|
|
360
|
+
rule predicates, transition tables and string constants (`arg` picks a
|
|
361
|
+
predicate's argument); `resources/prolog-proofs.md` has the rules and a
|
|
362
|
+
certificate module to copy. Wire the KB: the proof file symbol is
|
|
322
363
|
`executable_for` the test and named in `required_proofs`; the domain symbol
|
|
323
364
|
(and every symbol a rule, machine or pattern contract names) `implements`
|
|
324
365
|
the requirement and is `covered_by` the test; the test
|
package/hooks/hooks.json
CHANGED
|
@@ -3,32 +3,32 @@
|
|
|
3
3
|
"hooks": {
|
|
4
4
|
"sessionStart": [
|
|
5
5
|
{
|
|
6
|
-
"command": "node
|
|
6
|
+
"command": "node bin/hook-runner.mjs"
|
|
7
7
|
}
|
|
8
8
|
],
|
|
9
9
|
"beforeSubmitPrompt": [
|
|
10
10
|
{
|
|
11
|
-
"command": "node
|
|
11
|
+
"command": "node bin/hook-runner.mjs"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
14
|
"preToolUse": [
|
|
15
15
|
{
|
|
16
|
-
"command": "node
|
|
16
|
+
"command": "node bin/hook-runner.mjs"
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
19
|
"postToolUse": [
|
|
20
20
|
{
|
|
21
|
-
"command": "node
|
|
21
|
+
"command": "node bin/hook-runner.mjs"
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"beforeReadFile": [
|
|
25
25
|
{
|
|
26
|
-
"command": "node
|
|
26
|
+
"command": "node bin/hook-runner.mjs"
|
|
27
27
|
}
|
|
28
28
|
],
|
|
29
29
|
"stop": [
|
|
30
30
|
{
|
|
31
|
-
"command": "node
|
|
31
|
+
"command": "node bin/hook-runner.mjs",
|
|
32
32
|
"loop_limit": 1
|
|
33
33
|
}
|
|
34
34
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "Kibi Cursor plugin - thin adapter for Cursor MCP integration and editor hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
-
"build": "tsc -p tsconfig.json && bun run scripts/copy-plugin-assets.ts && bun run scripts/build-agent-plugin.ts && bun run ../../scripts/sync-agent-skills.ts --write --target cursor",
|
|
44
|
+
"build": "tsc -p tsconfig.json && bun run build:hook-bundle && bun run scripts/copy-plugin-assets.ts && bun run scripts/build-agent-plugin.ts && bun run ../../scripts/sync-agent-skills.ts --write --target cursor",
|
|
45
|
+
"build:hook-bundle": "bun run scripts/build-hook-bundle.ts",
|
|
46
|
+
"check:hook-bundle": "bun run --cwd ../agent-core build && bun run scripts/build-hook-bundle.ts --check",
|
|
45
47
|
"dev": "tsc -p tsconfig.json --watch",
|
|
46
48
|
"clean": "rm -rf dist",
|
|
47
49
|
"prepack": "npm run build"
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
}
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"kibi-agent-core": "^0.
|
|
64
|
+
"kibi-agent-core": "^0.11.1"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@types/node": "latest",
|
package/skills/.canon-hash.json
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
"kibi-bootstrap/resources/branch-lifecycle.md": "c854264ce888439140883a3fc636db5e522f020dd27b30a5c1ecc4105b64ed13",
|
|
5
5
|
"kibi-bootstrap/resources/operation-access.md": "b5a6a59e72d800c376e7fad79132897623c32a0ce152a1e8d73f9628b444db51",
|
|
6
6
|
"kibi-bootstrap/resources/source-authoring.md": "bf296e62f69474e01797d6cb9469bf624551dca834dd188abb6e705bd96fa586",
|
|
7
|
-
"kibi-commit-review/SKILL.md": "
|
|
7
|
+
"kibi-commit-review/SKILL.md": "bec768ad3e4cd4e782e9e13360b69bcd40a0964b305909818115d7f9e8d282d9",
|
|
8
8
|
"kibi-commit-review/resources/staged-gate.md": "37f750f327bb9202c1f30989763f4f1205b906cf672318ca50887d7984bc3e08",
|
|
9
|
-
"kibi-decisions/SKILL.md": "
|
|
9
|
+
"kibi-decisions/SKILL.md": "d91f784410251095e9d881bce751728cc4596858a518fb24f5e5d38c940bab50",
|
|
10
10
|
"kibi-decisions/resources/decision-records.md": "b201e619c48daf6ebe5989991a96f6c0573adb6c37abf814b9d34b7a1cd423c6",
|
|
11
|
-
"kibi-decisions/resources/signoff-views.md": "
|
|
11
|
+
"kibi-decisions/resources/signoff-views.md": "84eb2b7123e54047205b84af6fbf60c910ebcaaf98023e5812f3de9b65a4871c",
|
|
12
12
|
"kibi-freshness/SKILL.md": "b5c4f24bebdb5b4e0d04c2fa1176fc33ace35334b0c0b6ca943d6f445dc9b69e",
|
|
13
13
|
"kibi-freshness/resources/branch-lifecycle.md": "ebc01b19fe3dca8df5fc0175978963f6f1204f71f7c805cb2a5fb1b277ac78e4",
|
|
14
14
|
"kibi-freshness/resources/operation-access.md": "4e1db9294ee540cd29b8b3a2532a81e7894d5b4228b39e99ba48b37212f489f3",
|
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
"kibi-traceability/resources/operation-access.md": "39f7972ab7f4ae7479e78f7072bb50e8e6c4cdf4f857425f69d2522d37db437c",
|
|
19
19
|
"kibi-traceability/resources/source-authoring.md": "408c6ee2bef1b84e0194c0538ef929c26a0a617e631b2234247388140dbbdd08",
|
|
20
20
|
"kibi-traceability/resources/traceability.md": "38c290a0bc71bd1692e115f22694743946e2f69630e134acfd43cee5f613fb88",
|
|
21
|
-
"kibi-usage/SKILL.md": "
|
|
21
|
+
"kibi-usage/SKILL.md": "91639d49eae60a83b01017de1843ce49575db231f3f9cb1b0270c57a20462a88",
|
|
22
22
|
"kibi-usage/resources/branch-lifecycle.md": "f1bf359e9826e83c548f3cd0287f8175a62456527b0132b06b3f9f74aa59b7d6",
|
|
23
23
|
"kibi-usage/resources/fact-lanes.md": "7d487ffb794f6a7c32afabc7756a265a258b072ca83510ddb40d275863d44648",
|
|
24
24
|
"kibi-usage/resources/kb-improvement.md": "a8408fce27342bdce6415a6718599e53fe00bb33aa1fd3dc42353ec6f61adcd7",
|
|
25
25
|
"kibi-usage/resources/logic-ir.md": "0e8ce8aad07433ab4803ec169149ff6c4e1cf8cf010af18fa6fd67862d9be807",
|
|
26
26
|
"kibi-usage/resources/operation-access.md": "eb455796c066787ffd3fae8db0db1d3e87a84265a57f06ae61e30103cd6aed66",
|
|
27
|
-
"kibi-usage/resources/
|
|
27
|
+
"kibi-usage/resources/prolog-proofs.md": "b630f1edf32c4d14dbd096deb15c370f6ce05dede8aa9cda4fbf294d8668f164",
|
|
28
|
+
"kibi-usage/resources/proof.md": "fe5c0ed8117ec724f925c29a95345e2f7b9969a413a3ba56eece23273f91346e",
|
|
28
29
|
"kibi-usage/resources/relationship-directions.md": "0fdd67032c2d15299f772845fc4f807eb9435b09507bd87a5911ab33db2f143d",
|
|
29
30
|
"kibi-usage/resources/source-authoring.md": "cad93f1e0ae08a676f2de7492f9227677880302327e74d159618fea86ca50abe",
|
|
30
31
|
"kibi-usage/resources/ui-requirements.md": "f99c2a9a73bbb7bd92ce1f231db3056d544588be149a5b0d3f7cc6f28bc9eee9",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-commit-review
|
|
3
3
|
name: kibi-commit-review
|
|
4
4
|
description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, staging the tracked Kibi evidence with git add (symbol coordinates are derived and never staged), kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.4.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -91,7 +91,11 @@ apps); never attach the `.html` as a file, which chat apps show as raw source;
|
|
|
91
91
|
past 15 requirements the Markdown stops and only the page lists them all.
|
|
92
92
|
Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
|
|
93
93
|
on a large knowledge base. The summary is not an approval: never set
|
|
94
|
-
`approved_by` or `origin.ref` from it.
|
|
94
|
+
`approved_by` or `origin.ref` from it. Show it before you open or merge the
|
|
95
|
+
pull request. When the person answers, record their answer in the same
|
|
96
|
+
change (their name in `approved_by`, their words in `origin.ref` or
|
|
97
|
+
`approval_ref`) and push it to the same pull request; never move a signoff,
|
|
98
|
+
firmness or waiver approval into a separate pull request.
|
|
95
99
|
|
|
96
100
|
## Impact reviews
|
|
97
101
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-decisions
|
|
3
3
|
name: kibi-decisions
|
|
4
4
|
description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.5.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -115,7 +115,12 @@ again until none is open, then record each rule with their words in
|
|
|
115
115
|
`origin.ref`. Fields and outputs: `resources/signoff-views.md`.
|
|
116
116
|
|
|
117
117
|
Never invent words for `origin.ref`, never set `approved_by` yourself, and
|
|
118
|
-
mark your own picks `default` and guesses `exploratory`.
|
|
118
|
+
mark your own picks `default` and guesses `exploratory`. Once the person has
|
|
119
|
+
answered, recording their answer (their name in `approved_by` or a
|
|
120
|
+
`*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`)
|
|
121
|
+
is yours to do: put it on the branch of the change it approves and push it to
|
|
122
|
+
that pull request, never to a separate one. Ask before you open or merge the
|
|
123
|
+
pull request, so the answer lands in it. Payload shapes,
|
|
119
124
|
refusal messages and the `kb_compile_intent` review loop are in
|
|
120
125
|
`resources/decision-records.md`.
|
|
121
126
|
|
|
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
|
|
|
51
51
|
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
52
52
|
each answer into `answer`, render again, and record the rules only once every
|
|
53
53
|
question is answered. An answer is the person's words: quote it in
|
|
54
|
-
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
`origin.ref`; a view itself is never an approval. Record the answers on the
|
|
55
|
+
branch of the change they approve and push them to its pull request, never to
|
|
56
|
+
a separate one.
|
|
55
57
|
|
|
56
58
|
## Summary contents
|
|
57
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.40.1
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -20,6 +20,7 @@ resources:
|
|
|
20
20
|
- resources/fact-lanes.md
|
|
21
21
|
- resources/workflows.md
|
|
22
22
|
- resources/proof.md
|
|
23
|
+
- resources/prolog-proofs.md
|
|
23
24
|
- resources/ui-requirements.md
|
|
24
25
|
- resources/logic-ir.md
|
|
25
26
|
- resources/kb-improvement.md
|
|
@@ -94,8 +95,10 @@ it is a pointer to the knowledge, never proof. Each line answers one question:
|
|
|
94
95
|
requirement first. Read the lead requirement with `kb_query({id})` before
|
|
95
96
|
changing behavior; add `includeBody: true` to see its authored prose, and
|
|
96
97
|
fix a stale sentence there with `kb_upsert` `document.body`.
|
|
97
|
-
- `REQ-… must keep true:
|
|
98
|
-
|
|
98
|
+
- `REQ-… must keep true: <claim>` (edit only): what the lead requirement
|
|
99
|
+
requires, as the claims its facts model (with the operator and members,
|
|
100
|
+
such as "The greet function must not call console.log") or, without
|
|
101
|
+
them, its own statement. An edit that breaks one of them is a requirement
|
|
99
102
|
change: ask before changing the rule (see Decision firmness), and never
|
|
100
103
|
code around the fact.
|
|
101
104
|
- `Decision: ADR-…` (edit only): the decision behind the lead requirement.
|
|
@@ -372,6 +375,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
372
375
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
373
376
|
exists in `rationale`, or link the ADR that explains it.
|
|
374
377
|
|
|
378
|
+
A signoff belongs to the change it approves. Ask for it before you open or
|
|
379
|
+
merge the pull request, and when the person answers, record their answer
|
|
380
|
+
(`approved_by` or a `*_waiver_approved_by` field set to them, their words in
|
|
381
|
+
`origin.ref` or `approval_ref`) on the same branch and push it to the same pull
|
|
382
|
+
request. Writing down an answer the person gave is not approving it yourself.
|
|
383
|
+
Never open a separate pull request only to carry a signoff, firmness or waiver
|
|
384
|
+
approval.
|
|
385
|
+
|
|
375
386
|
## Decision firmness
|
|
376
387
|
|
|
377
388
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|