kibi-cli 2.29.0 → 2.30.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/dist/cli-operation-metadata.d.ts +8 -8
- package/dist/cli-operation-metadata.js +8 -8
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +12 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +4 -0
- package/dist/commands/signoff.d.ts +37 -0
- package/dist/commands/signoff.d.ts.map +1 -0
- package/dist/commands/signoff.js +152 -0
- package/dist/operations/modeling/predicate-applicability.d.ts +5 -1
- package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applicability.js +35 -2
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +3 -1
- package/dist/operations/mutation/contradictions.d.ts +7 -5
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +8 -6
- package/dist/operations/mutation/source-authoring.d.ts +15 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +19 -7
- package/dist/operations/mutation/types.d.ts +5 -0
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +14 -0
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +42 -36
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +61 -37
- package/dist/public/operations/catalog.d.ts +29 -8
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +2 -0
- package/dist/public/operations/specs/bootstrap.d.ts +1 -1
- package/dist/public/operations/specs/bootstrap.js +1 -1
- package/dist/public/operations/specs/composite.d.ts +1 -1
- package/dist/public/operations/specs/composite.js +1 -1
- package/dist/public/operations/specs/discovery.d.ts +1 -1
- package/dist/public/operations/specs/discovery.js +1 -1
- package/dist/public/operations/specs/impact-review-preparation.d.ts +2 -1
- package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -1
- package/dist/public/operations/specs/impact-review-preparation.js +2 -1
- package/dist/public/operations/specs/planning.d.ts +1 -1
- package/dist/public/operations/specs/planning.js +1 -1
- package/dist/public/operations/specs/reporting.d.ts +23 -3
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +97 -21
- package/dist/public/skills/kibi-commit-review/SKILL.md +125 -0
- package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +98 -0
- package/dist/public/skills/kibi-decisions/SKILL.md +130 -0
- package/dist/public/skills/kibi-decisions/resources/decision-records.md +142 -0
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +66 -0
- package/dist/public/skills/kibi-freshness/SKILL.md +2 -0
- package/dist/public/skills/kibi-traceability/SKILL.md +4 -0
- package/dist/public/skills/kibi-usage/SKILL.md +20 -15
- package/dist/signoff/collect.d.ts +39 -0
- package/dist/signoff/collect.d.ts.map +1 -0
- package/dist/signoff/collect.js +398 -0
- package/dist/signoff/html.d.ts +4 -0
- package/dist/signoff/html.d.ts.map +1 -0
- package/dist/signoff/html.js +210 -0
- package/dist/signoff/markdown.d.ts +20 -0
- package/dist/signoff/markdown.d.ts.map +1 -0
- package/dist/signoff/markdown.js +203 -0
- package/dist/signoff/model.d.ts +134 -0
- package/dist/signoff/model.d.ts.map +1 -0
- package/dist/signoff/model.js +138 -0
- package/package.json +2 -2
- package/src/public/operations/contracts.ts +2 -0
- package/src/public/operations/specs/bootstrap.ts +1 -1
- package/src/public/operations/specs/composite.ts +1 -1
- package/src/public/operations/specs/discovery.ts +1 -1
- package/src/public/operations/specs/impact-review-preparation.ts +3 -1
- package/src/public/operations/specs/planning.ts +1 -1
- package/src/public/operations/specs/reporting.ts +109 -21
- package/src/public/skills/kibi-commit-review/SKILL.md +125 -0
- package/src/public/skills/kibi-commit-review/resources/staged-gate.md +98 -0
- package/src/public/skills/kibi-decisions/SKILL.md +130 -0
- package/src/public/skills/kibi-decisions/resources/decision-records.md +142 -0
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +66 -0
- package/src/public/skills/kibi-freshness/SKILL.md +2 -0
- package/src/public/skills/kibi-traceability/SKILL.md +4 -0
- package/src/public/skills/kibi-usage/SKILL.md +20 -15
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# The staged gate
|
|
2
|
+
|
|
3
|
+
Reference for `kibi-commit-review`: what `kibi check --staged` and
|
|
4
|
+
`kibi check-generated --staged` report, how to fix each finding, and the
|
|
5
|
+
impact-review record. The staged check reads blob content from the Git index,
|
|
6
|
+
not the working tree, so a fix counts only once it is staged.
|
|
7
|
+
|
|
8
|
+
## Reading a finding
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
symbols_manifest_stale: .kb/symbol-coordinates.yaml is stale or missing for staged source files: src/billing/refund.ts
|
|
12
|
+
Detail: src/billing/refund.ts — extraction finds 4 symbol(s), evidence covers 3.
|
|
13
|
+
Not in .kb/symbols.yaml: approveRefund (line 42)
|
|
14
|
+
Suggestion: Author .kb/symbols.yaml entries for the uncovered symbols (kibi upsert, with implements/covered_by links), then run kibi sync --refresh-symbol-coordinates && git add .kb/symbol-coordinates.yaml .kb/symbols.yaml, then re-run kibi check --staged.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Detail lines name every symbol, never a shortened list. `Evidence without a
|
|
18
|
+
matching symbol:` lists manifest entries whose declaration is gone or
|
|
19
|
+
renamed: rename the symbol's `title`, or retire the entry.
|
|
20
|
+
- `--format json` carries the same lists in the diagnostic `evidence`
|
|
21
|
+
(`symbolsManifest[].missing` / `extra`, `uncoveredSymbols[].titles`).
|
|
22
|
+
|
|
23
|
+
## Blocking findings
|
|
24
|
+
|
|
25
|
+
| Id or message | Cause | Fix |
|
|
26
|
+
| --- | --- | --- |
|
|
27
|
+
| `kibi_impact_evidence_missing` | A staged behavior edit (changed lines in exported or behavior-bearing code, not comments or formatting) has no staged Kibi evidence. Test-only edits do not need it unless they add executable test symbols. | Query the owning knowledge; update it when behavior changed; stage entity Markdown under `.kb/`, authored `.kb/symbols.yaml` entries for the listed symbols, or refreshed `.kb/symbol-coordinates.yaml`. |
|
|
28
|
+
| `symbols_manifest_stale` | Extraction output changed and the staged coordinates (or manifest) do not match it. | Author entries for the listed symbols first, then `kibi sync --refresh-symbol-coordinates`, then stage both manifests. |
|
|
29
|
+
| `symbol_granularity_violation` | A changed behavioral member is owned only by a coarse class or module symbol while a narrower declaration exists. | Add a symbol for the member itself (`title` = `Class.method` or the exported function) with its own links; use `granularity_reason` (`config-artifact`, `module-level-behavior`, `extractor-miss`, `legacy-link`, `test-suite`) only when it is true. |
|
|
30
|
+
| `symbol-coverage` | A changed symbol, or a symbol whose staged manifest entry changed, fails the full-check rule on the staged knowledge. | The symbol `implements` the requirement and is `covered_by` a test that verifies it: through the requirement's scenario (`verified_by` scenario -> test) when it has one, else `verified_by` requirement -> test. A direct requirement -> test link does not count while a scenario exists. The finding's suggestion names the missing link (see `kibi-traceability`). |
|
|
31
|
+
| `kibi_impact_override_missing_rationale` | A `Kibi-Impact: none` declaration has no `Rationale:` line. | Add the rationale, or drop the declaration and stage real evidence. |
|
|
32
|
+
| `entity-context-missing` (staged entity) | A staged requirement, scenario, test, ADR or observation fact has fewer than 12 words of context. | Upsert a sectioned `document.body` (see `kibi-usage`, Entity body contract). |
|
|
33
|
+
| `domain-contradictions`, `scenario-feasibility`, `exception-claim-keys` (staged `.kb/` change) | The staged knowledge introduces a violation the last commit did not have. | Fix the knowledge; a contradiction with a recorded rule goes to the person (`kibi-decisions`). |
|
|
34
|
+
| Proposition-complete ingestion | A staged requirement's semantic inventory is missing or no longer matches its prose. | Re-derive it (`kb_model` analyze with the complete prose) or run `kibi migrate` for drift. |
|
|
35
|
+
| `kibi check-generated --staged` drift | The staged `.kb/symbols.yaml` or `.kb/symbol-coordinates.yaml` differs from a refresh computed from the index. | `kibi sync --refresh-symbol-coordinates`, review the diff, stage only the intended hunks (`git add -p`). |
|
|
36
|
+
| `Staged impact review failed: impact_review_invalid: ...` | The base commit has `.kibi/impact-policy.json` and the staged `.kibi/impact-review.json` is missing, stale or incomplete. The message names the cause (missing review path, stale fingerprint, ...). | Prepare a fresh record (below). Any later staged change makes the fingerprints stale again, so prepare it last. |
|
|
37
|
+
|
|
38
|
+
## Advisory findings
|
|
39
|
+
|
|
40
|
+
These warn but do not block. Read them; they are often the real review.
|
|
41
|
+
|
|
42
|
+
- `requirement_statement_unverified`: quotes each current requirement the
|
|
43
|
+
changed code implements, with its firmness. Compare the code with the
|
|
44
|
+
statement yourself.
|
|
45
|
+
- `symbol_semantic_review_needed`: the links exist, but check that the linked
|
|
46
|
+
requirement, scenario and test still describe the changed behavior. In a
|
|
47
|
+
file with no linked symbol it says no recorded intent covers the change.
|
|
48
|
+
- `staged_file_ownership_missing` / `staged_file_impact_review_needed`: a
|
|
49
|
+
staged text file (not TypeScript or JavaScript) has no owning requirement,
|
|
50
|
+
or has one and no matching evidence changed.
|
|
51
|
+
|
|
52
|
+
## Audited no-impact declaration
|
|
53
|
+
|
|
54
|
+
For a false positive or an edit that changes no behavior, Kibi accepts a
|
|
55
|
+
staged Markdown note in a knowledge lane under `.kb/` with the two lines
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Kibi-Impact: none
|
|
59
|
+
Rationale: <why the staged source edits change no behavior>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
It never satisfies a genuine behavior change, and it is visible in review.
|
|
63
|
+
Prefer real evidence; use the note only when the person agrees the edit has
|
|
64
|
+
no behavior impact.
|
|
65
|
+
|
|
66
|
+
## Impact-review record
|
|
67
|
+
|
|
68
|
+
`kb_prepare_impact_review` (CLI `prepare-impact-review --input`) takes only
|
|
69
|
+
`scope`: `{"kind":"staged"}`, or
|
|
70
|
+
`{"kind":"diff","baseCommit":"<sha>","headCommit":"<sha>"}` with full
|
|
71
|
+
lowercase 40- or 64-hex commit ids. It returns `status: ready_for_authoring`,
|
|
72
|
+
the `snapshot` identity, `recordHeaders` (policy, evaluator and scope
|
|
73
|
+
fingerprints), complete per-file evidence in `files`, `requirementScopes`,
|
|
74
|
+
`residualReviewObligations`, and `authorship` with the record schemas and an
|
|
75
|
+
unauthored `recordTemplate`.
|
|
76
|
+
|
|
77
|
+
Fill only the authored fields (`files[].decision`, `files[].analysisReviews`,
|
|
78
|
+
`reviewer.id`, `reviewedAt`) and write the record to `.kibi/impact-review.json`,
|
|
79
|
+
then stage it. A file `decision` is one of:
|
|
80
|
+
|
|
81
|
+
- `{"kind":"impact","requirementIds":[...],"knowledge":{"state":"still_current","rationale":"..."}}`
|
|
82
|
+
- `{"kind":"impact","requirementIds":[...],"knowledge":{"state":"updated","entities":[{"entityId":"...","artifactPath":"...","beforeFingerprint":"<sha256 or null>","afterFingerprint":"<sha256>"}]}}`
|
|
83
|
+
- `{"kind":"no_impact","reason":"...","rationale":"..."}`
|
|
84
|
+
- `{"kind":"not_applicable","policyReason":"...","rationale":"..."}` (only
|
|
85
|
+
where the policy lists the path as not applicable)
|
|
86
|
+
|
|
87
|
+
`reviewer.source` is `self-claimed-local`: the record says who reviewed, it
|
|
88
|
+
does not prove it. Put the person's id there only when they reviewed it.
|
|
89
|
+
|
|
90
|
+
## Commands
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx --no-install kibi check --staged # the gate
|
|
94
|
+
npx --no-install kibi check --staged --format json # with full evidence
|
|
95
|
+
npx --no-install kibi check-generated --staged # manifest drift
|
|
96
|
+
npx --no-install kibi sync --refresh-symbol-coordinates # refresh coordinates
|
|
97
|
+
git status --short .kb # what Kibi wrote
|
|
98
|
+
```
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: kibi-decisions
|
|
3
|
+
name: kibi-decisions
|
|
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.2.0
|
|
6
|
+
kibiCompatibility: ">=1.0.0"
|
|
7
|
+
tags:
|
|
8
|
+
- kibi
|
|
9
|
+
- decisions
|
|
10
|
+
- firmness
|
|
11
|
+
- source-first
|
|
12
|
+
- agent-guidance
|
|
13
|
+
resources:
|
|
14
|
+
- resources/decision-records.md
|
|
15
|
+
- resources/signoff-views.md
|
|
16
|
+
---
|
|
17
|
+
## Goal
|
|
18
|
+
|
|
19
|
+
Keep the people's rules theirs. A recorded requirement or ADR says how firmly
|
|
20
|
+
it was decided; follow it, record new rules when they are stated, and put any
|
|
21
|
+
conflict with a rule to the person instead of coding around it.
|
|
22
|
+
|
|
23
|
+
## Interface Selection
|
|
24
|
+
|
|
25
|
+
Use the visible approved MCP tools or the trusted project-local CLI as equal
|
|
26
|
+
peer interfaces (CLI JSON: `printf '%s\n' '{"query":"..."}' | npx --no-install
|
|
27
|
+
kibi search --input -`). Exact routes are in
|
|
28
|
+
`kibi-usage/resources/operation-access.md`. If neither is available, stop and
|
|
29
|
+
name the missing capability. Never read or edit `.kb/` files directly.
|
|
30
|
+
|
|
31
|
+
## When this applies
|
|
32
|
+
|
|
33
|
+
- The person states a rule: "must", "never", "always", "from now on", "only
|
|
34
|
+
admins may", "we decided X because Y". The prompt hook may have noted it
|
|
35
|
+
("this request reads as a rule or decision").
|
|
36
|
+
- A hook says an edit changes code that implements a firm requirement: Claude
|
|
37
|
+
Code puts a permission prompt to the person; Codex, Cursor and ZCode tell
|
|
38
|
+
you to ask first unless the edit keeps the rule.
|
|
39
|
+
- The Stop hook says the session changed source files and recorded nothing.
|
|
40
|
+
- `kb_check` reports `requirement_statement_unverified`, quoting a requirement
|
|
41
|
+
the changed code implements, and the code no longer does what it says.
|
|
42
|
+
- A request contradicts a requirement or ADR you found.
|
|
43
|
+
|
|
44
|
+
## Read the rule first
|
|
45
|
+
|
|
46
|
+
1. `kb_search` the topic (or `sourceLocations` for the file you are changing),
|
|
47
|
+
then `kb_query({id})` each governing requirement or ADR. Add
|
|
48
|
+
`includeBody: true` to read its prose and context.
|
|
49
|
+
2. Read `firmness` (always shown, even when inferred) and `origin`:
|
|
50
|
+
- `firm`: a person set it. Follow it; changing it is the person's call.
|
|
51
|
+
A decision with no `firmness` reads as `firm` unless `origin.kind` is
|
|
52
|
+
`agent`.
|
|
53
|
+
- `default`: delegated or an agent's pick. Follow it; supersede it only on
|
|
54
|
+
evidence (a failing test, a measured cost, a constraint it missed).
|
|
55
|
+
- `exploratory`: a flagged guess; revisit it when you touch the area.
|
|
56
|
+
3. Compare the request with the statement. A request is not evidence against
|
|
57
|
+
a rule.
|
|
58
|
+
|
|
59
|
+
## Decide
|
|
60
|
+
|
|
61
|
+
- **Request conflicts with a recorded rule (any firmness):** name the rule (id
|
|
62
|
+
and what it requires) and ask whether to change it. Do not implement the
|
|
63
|
+
request and do not supersede the rule until the person says to change that
|
|
64
|
+
rule.
|
|
65
|
+
- **Edit confirmation declined, or nobody could answer:** the requirement
|
|
66
|
+
stands. Say which rule blocked it and ask how to proceed; never reach the
|
|
67
|
+
same change another way (another tool, a shell write, another file).
|
|
68
|
+
- **Edit confirmation allowed:** if the change still keeps the rule, carry on.
|
|
69
|
+
If it changes what the rule says, update the rule in this same change, citing
|
|
70
|
+
the person's words. Clicking allow is not a stated rule: when their request
|
|
71
|
+
did not state the new behavior, ask them to say it before rewriting the rule.
|
|
72
|
+
- **The person states a new rule:** record it with `kb_upsert` as part of the
|
|
73
|
+
change, not after: a requirement with `firmness: firm`, `origin.ref`
|
|
74
|
+
quoting their words and where they said them, a sectioned `document.body`,
|
|
75
|
+
a scenario, and an `implements` link from the code that enforces it. Use
|
|
76
|
+
`kb_compile_intent` first when the rule may touch several requirements.
|
|
77
|
+
- **The person changes a rule:** supersede it (new requirement linked
|
|
78
|
+
`supersedes` new -> old, `firmness: firm` when the old one was firm, a
|
|
79
|
+
`## Why this changed` section of at least 12 words naming their instruction
|
|
80
|
+
and answering the old reasoning, old one `status: closed` in the same
|
|
81
|
+
change). For a wording correction they asked for in place, update it with a
|
|
82
|
+
new `origin.ref` to those words instead.
|
|
83
|
+
- **You only prefer another approach:** a preference is not evidence. Propose
|
|
84
|
+
it; do not supersede.
|
|
85
|
+
|
|
86
|
+
## Put decisions to the person in one view
|
|
87
|
+
|
|
88
|
+
Whenever you ask the person to confirm rules (a stated rule to record as
|
|
89
|
+
firm, a change to a recorded rule, a conflict with one), render every open
|
|
90
|
+
question as one numbered view instead of scattering them through the chat:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
printf '%s\n' '{"questions":[{"title":"Refund approvals","statement":"Refunds above 500 EUR need a finance approval.","quote":"from now on refunds above 500 EUR must be approved by finance","firmness":"firm","governs":["src/refunds/approve.ts"],"question":"Record this as a firm rule?"}]}' | npx --no-install kibi signoff --questions -
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Put the printed Markdown in your reply unchanged (or, when your replies go
|
|
97
|
+
through a messaging tool, in that tool's message, with
|
|
98
|
+
`.kb/briefs/signoff/latest.html` attached or published when it can carry a
|
|
99
|
+
page), then wait. In the OpenCode terminal use `--format md` so the fenced
|
|
100
|
+
block renders as a card. Set `id` when a question would change a recorded
|
|
101
|
+
requirement and `conflictsWith` to the recorded rules it conflicts with: the
|
|
102
|
+
view quotes their current text from the knowledge base, so never retype it.
|
|
103
|
+
When the person answers by number, fill each question's `answer` and render
|
|
104
|
+
again until none is open, then record each rule with their words in
|
|
105
|
+
`origin.ref`. Fields and outputs: `resources/signoff-views.md`.
|
|
106
|
+
|
|
107
|
+
Never invent words for `origin.ref`, never set `approved_by` yourself, and
|
|
108
|
+
mark your own picks `default` and guesses `exploratory`. Payload shapes,
|
|
109
|
+
refusal messages and the `kb_compile_intent` review loop are in
|
|
110
|
+
`resources/decision-records.md`.
|
|
111
|
+
|
|
112
|
+
## Typed results
|
|
113
|
+
|
|
114
|
+
Parse `kibiProtocol`, `status`, diagnostics and typed `nextActions`. A
|
|
115
|
+
refused write (`Entity validation failed: <ID> is a firm decision ...`)
|
|
116
|
+
wrote nothing: do not retry it with the same payload; ask, then supersede or
|
|
117
|
+
cite new words. On `committed_with_repairs` the write stands: run the repair
|
|
118
|
+
actions and never resend the original. Kibi authors tracked files but never
|
|
119
|
+
Git-stages or commits them.
|
|
120
|
+
|
|
121
|
+
Validation is not completion. When a request conflicts with a recorded rule and you stop to ask, first kb_query that rule by id. Then make the conflict itself the verdict of your final answer: name the rule's id and what it requires, keep the answer format the request asked for (including any verdict field), and add your question after that. Asking the person, or showing a questions view, never takes the place of that verdict. When you record a stated rule or apply a kb_compile_intent plan, keep the actual target ids and the intended edges. Discover and kb_query each target, check each payload with kb_upsert and dryRun: true, then send that same payload as the real kb_upsert. Read the result back by exact id before kb_check. A dry run or kb_model output only validates; it records nothing. A stated rule is recorded only once the requirement, its scenario and the enforcing symbol's implements link have actually been written, followed by kb_check. Separate payloads may need several writes in sequence. Never resend a write that already committed, and handle refusals or repairs as the typed-result rules above say. After you apply a plan, make sure the new requirement is firm, with origin.ref quoting the person's words. A must-priority requirement also needs a scenario through specified_by. Leave compatible recorded rules unchanged. Rerun kb_check after each fix until it reports nothing about the new requirement, and only then report the work as done.
|
|
122
|
+
|
|
123
|
+
## Report
|
|
124
|
+
|
|
125
|
+
End with `kb_check` (and `kb_status` when freshness matters) and say:
|
|
126
|
+
|
|
127
|
+
- which rules you followed, asked about, recorded or changed (ids, firmness);
|
|
128
|
+
- under "Decisions I changed", each supersede and its evidence;
|
|
129
|
+
- the open question, if a conflict is waiting on the person;
|
|
130
|
+
- or, when the session made no decision, one line saying so.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Decision records
|
|
2
|
+
|
|
3
|
+
Reference for `kibi-decisions`: what the hooks say, the payloads that record
|
|
4
|
+
or change a rule, what Kibi refuses, and the `kb_compile_intent` review loop.
|
|
5
|
+
|
|
6
|
+
## What the hooks say
|
|
7
|
+
|
|
8
|
+
| Hook | Text you see | What it means |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| Prompt submit | `Kibi: this request reads as a rule or decision (it says "<phrase>").` | The phrase matched words such as "must", "never", "always", "from now on", "has to". It only asks whether there is something to record; check with `kb_search`. |
|
|
11
|
+
| Before an edit (Claude Code) | A permission prompt: `Kibi: this edit changes <symbol>, which implements a firm requirement recorded in the knowledge base: <ID>: <title>. Allow it if ...` | The person decides. You are also told: if the edit was declined or could not be confirmed, the requirement stands; if allowed and the change alters what the requirement says, update the requirement with `kb_upsert` in this change. |
|
|
12
|
+
| Before an edit (Codex, Cursor, ZCode) | `Kibi: this edit changes <where>, which implements a firm requirement, a rule the person set: ...` | The host cannot prompt the person, so you must: unless the edit keeps the rule, ask before making it and name the rule. |
|
|
13
|
+
| Stop | `Kibi: this session changed source files and recorded nothing in the knowledge base.` (or the variant naming a rule-like request) | Record the decision the person stated or the change made (a rule, a limit, a default, who may do what) as a requirement linked to its code, or say in one line that there was none. Asked once per session. |
|
|
14
|
+
|
|
15
|
+
The firm-edit prompt covers current requirements whose effective firmness is
|
|
16
|
+
`firm` and that the edited symbol (or, for a whole-file write, any symbol of
|
|
17
|
+
the file) implements. Superseded and retired requirements never ask. An
|
|
18
|
+
operator can turn the prompt off with `KIBI_CONFIRM_FIRM_EDITS=0`; that does
|
|
19
|
+
not make a firm rule negotiable.
|
|
20
|
+
|
|
21
|
+
`kb_check` with `sourceFiles` and `includeImpactDiagnostics: true` reports
|
|
22
|
+
`requirement_statement_unverified` (warning) for each current requirement a
|
|
23
|
+
changed behavioral symbol implements, quoting its statement and firmness.
|
|
24
|
+
Kibi never compares code with prose: you do. A change that no longer does what
|
|
25
|
+
the quote says is a conflict with a recorded rule.
|
|
26
|
+
|
|
27
|
+
## Effective firmness
|
|
28
|
+
|
|
29
|
+
| `firmness` | `origin.kind` | Effective |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `firm`, `default` or `exploratory` | any | as written |
|
|
32
|
+
| absent | `agent` | `default` |
|
|
33
|
+
| absent | `human`, `import`, `migration`, or no origin | `firm` |
|
|
34
|
+
|
|
35
|
+
`kb_search` answers and `kb_query` rows show the effective value. Hook
|
|
36
|
+
snippets label firm decisions `[firm: ask before changing]` and exploratory
|
|
37
|
+
ones `[exploratory]`; an unlabeled decision is `default`.
|
|
38
|
+
|
|
39
|
+
## Record a rule the person stated
|
|
40
|
+
|
|
41
|
+
Discover first (`kb_search`, `kb_query`). If a current requirement already
|
|
42
|
+
says it, link to it instead of restating it. Otherwise write the scenario
|
|
43
|
+
first, then the requirement (the requirement's write sends `specified_by`):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{"type":"req","id":"REQ-billing-refund-approval","properties":{"title":"Refunds above 500 EUR need a finance approval","status":"open","priority":"must","firmness":"firm","origin":{"kind":"agent","ref":"session request: \"from now on refunds above 500 EUR must be approved by finance\""}},"relationships":[{"type":"specified_by","from":"REQ-billing-refund-approval","to":"SCEN-billing-refund-approval"}],"document":{"body":"Refunds above 500 EUR need a finance approval.\n\n## Context\n\nThe person asked for this rule while changing the refund flow; reason not stated.\n\n## Source\n\n> from now on refunds above 500 EUR must be approved by finance\n\nSession request."}}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then link the enforcing symbol with `implements` (and its test with
|
|
50
|
+
`covered_by`). Preview with `dryRun: true` when unsure; a passing dry run is
|
|
51
|
+
validation, not the write.
|
|
52
|
+
|
|
53
|
+
- `origin.ref` is where the words are and the words themselves: a ticket URL,
|
|
54
|
+
a document path with line, or the session request quoted. Kibi checks that a
|
|
55
|
+
reference exists, not that it is genuine, so never write words nobody said.
|
|
56
|
+
- `kb_upsert` records `origin.kind: agent` when you omit `origin`; the explicit
|
|
57
|
+
`firmness: firm` is what makes the rule the person's. Leave
|
|
58
|
+
`origin.approved_by` to the person.
|
|
59
|
+
- A rule from a document, test or ticket a person wrote is `firm` too, with
|
|
60
|
+
`origin.ref` to that source.
|
|
61
|
+
- Your own choice is `default`; a guess is `exploratory`. Write the value
|
|
62
|
+
explicitly whenever you record a decision.
|
|
63
|
+
- For strict modeling (claim keys, predicate facts) follow `kibi-usage`,
|
|
64
|
+
"Second-agent edits", recipe 1.
|
|
65
|
+
|
|
66
|
+
## Supersede a rule
|
|
67
|
+
|
|
68
|
+
Only when the person said to change that rule (firm), or on evidence (default):
|
|
69
|
+
|
|
70
|
+
1. Write the new scenario, then the new requirement with `supersedes` to the
|
|
71
|
+
old one (direction new -> old), `firmness: firm` when the old one was firm,
|
|
72
|
+
`origin.ref` to the person's instruction, and a body section:
|
|
73
|
+
|
|
74
|
+
```markdown
|
|
75
|
+
## Why this changed
|
|
76
|
+
|
|
77
|
+
The person asked on 2026-10-21 to raise the approval threshold to 1000 EUR
|
|
78
|
+
because finance now reviews refunds weekly; the old 500 EUR limit predates
|
|
79
|
+
that review.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
At least 12 words, naming the evidence and answering the old decision's
|
|
83
|
+
reasoning.
|
|
84
|
+
2. Upsert the old requirement with `status: closed` in the same change (its
|
|
85
|
+
stored `title`, the new status; status and links stay editable on a firm
|
|
86
|
+
decision).
|
|
87
|
+
3. Re-point or close the old scenario, and move `implements` links to the new
|
|
88
|
+
requirement when the code now enforces it.
|
|
89
|
+
4. Run `kb_check`.
|
|
90
|
+
|
|
91
|
+
A preference ("this would be cleaner") is not evidence: propose it in the
|
|
92
|
+
report instead of superseding. An authored requirement is never deleted:
|
|
93
|
+
`kb_delete` returns `outcome: supersession_required`.
|
|
94
|
+
|
|
95
|
+
## Correct a firm rule in place
|
|
96
|
+
|
|
97
|
+
When the person asks for a correction that keeps the rule's meaning (a typo, a
|
|
98
|
+
clearer title), update the existing requirement with a new `origin.ref` citing
|
|
99
|
+
their words. Without new human words, Kibi refuses to change a firm decision's
|
|
100
|
+
title, statement (or an ADR's body) or to lower its firmness.
|
|
101
|
+
|
|
102
|
+
## What Kibi refuses or blocks
|
|
103
|
+
|
|
104
|
+
| Where | Code or message | Fix |
|
|
105
|
+
| --- | --- | --- |
|
|
106
|
+
| `kb_upsert`, `dryRun`, `kb_apply_plan` step | `Entity validation failed: <ID> is a firm decision, so kb_upsert does not change its <fields> in place.` | Ask the person; then cite their words in `origin.ref`, or supersede with a firm decision. |
|
|
107
|
+
| `kb_upsert` | `firmness: firm` without `origin.ref` (or `approval_ref` on a requirement) | Add the reference to the person's words. |
|
|
108
|
+
| `kb_upsert` | `firmness is only valid on req and adr entities` | Remove `firmness` from facts, scenarios, tests and symbols. |
|
|
109
|
+
| `kb_check` | `decision-firm-unreferenced` | As above. |
|
|
110
|
+
| `kb_check` | `decision-firm-superseded` | The superseding decision must be `firm` too. |
|
|
111
|
+
| `kb_check` | `decision-firm-edited` | A firm decision's claim changed in the working tree since `HEAD` without new words; revert, or cite their words. |
|
|
112
|
+
| `kb_check` | `supersedes-reason-missing` | Add `## Why this changed` (12+ words). |
|
|
113
|
+
| `kb_check` | `superseded-requirement-open` | Close the superseded requirement. |
|
|
114
|
+
|
|
115
|
+
## The kb_compile_intent review loop
|
|
116
|
+
|
|
117
|
+
`kb_compile_intent` (`mode: "create"` or `"update"`, the complete intent,
|
|
118
|
+
`context` when creating) is read-only and returns a plan.
|
|
119
|
+
|
|
120
|
+
- `contradictionAnalysis.outcome`:
|
|
121
|
+
- `no_conflict`: the check could decide and found none.
|
|
122
|
+
- `conflict`: a witness or your own verdict says the intent contradicts a
|
|
123
|
+
current requirement. The plan `status` is `blocked`.
|
|
124
|
+
- `unresolved`: Kibi could not decide. `reasons` say why
|
|
125
|
+
(`unmodeled_target`, `unmodeled_related`, `analysis_unavailable`). Never
|
|
126
|
+
read it as consistent.
|
|
127
|
+
- `reviewCandidates[]`: up to five current requirements Kibi could not compare
|
|
128
|
+
logically, each with `requirementId`, `title`, `sentence` (the closest
|
|
129
|
+
sentence), `statement`, `score`, `modeled` and `review` (`pending`,
|
|
130
|
+
`conflict` or `no_conflict`).
|
|
131
|
+
- Compare the intent with each candidate's `statement`, then compile again
|
|
132
|
+
with the same input plus
|
|
133
|
+
`conflictReviews: [{"requirementId": "...", "verdict": "conflict" | "no_conflict", "note": "..."}]`.
|
|
134
|
+
A verdict may also name a requirement discovery did not rank.
|
|
135
|
+
- On `conflict`: ask the person which rule holds. Then supersede or change
|
|
136
|
+
the requirement (as above), or change the intent, and compile again.
|
|
137
|
+
- Plan `status` is `ready`, `needs_resolution` (ambiguous or unmodeled
|
|
138
|
+
propositions, missing targets) or `blocked`. Apply only a `ready` plan the
|
|
139
|
+
person approved, with `kb_apply_plan` and its full `planHash`.
|
|
140
|
+
- A compiled plan records the new requirement as an agent's. When the intent
|
|
141
|
+
is the person's stated rule, follow the apply with a `kb_upsert` that sets
|
|
142
|
+
`firmness: firm` and `origin.ref` on that requirement.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Signoff views
|
|
2
|
+
|
|
3
|
+
`kibi signoff` renders what a person signs off, so the agent never retypes
|
|
4
|
+
requirement text from memory. It is a CLI command, not an MCP tool.
|
|
5
|
+
|
|
6
|
+
| View | Command | When |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Decisions to confirm | `kibi signoff --questions <file or ->` | Mid-work: rules to record as firm, a change to a recorded rule, a conflict |
|
|
9
|
+
| Requirements signoff | `kibi signoff` (`--staged` for the index) | End of work: before asking to commit |
|
|
10
|
+
|
|
11
|
+
Both print plain Markdown by default (`--format chat`): headings, quoted
|
|
12
|
+
statements and lists that render in any chat or messaging surface. Put it in
|
|
13
|
+
your reply unchanged: never wrap it in a code block, summarize it or retell a
|
|
14
|
+
requirement in your own words. Every run also writes
|
|
15
|
+
`.kb/briefs/signoff/latest.json`, `latest.md` and `latest.html` (git-ignored);
|
|
16
|
+
`latest.html` is a self-contained page with the full view.
|
|
17
|
+
|
|
18
|
+
## Showing it on your host
|
|
19
|
+
|
|
20
|
+
| Host | Best view |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| Claude Code, Codex, Cursor, ZCode, VS Code chat | Paste the default output; `/kibi-signoff` (Claude Code, Cursor, ZCode) runs it. Offer `kibi signoff --format html --open` for the page |
|
|
23
|
+
| OpenCode terminal | `kibi signoff --format md` and paste the fenced block unchanged: kibi-opencode draws it as a card, and `/kibi-signoff` reopens it |
|
|
24
|
+
| Replies sent through a messaging tool (cloud or project threads, chat bots) | Pass the default output as the message text, and attach or publish `.kb/briefs/signoff/latest.html` next to it when the tool can carry a file or a page |
|
|
25
|
+
| VS Code or Cursor with the kibi-vscode extension | The **Kibi: Show Requirements Signoff** panel follows every run |
|
|
26
|
+
| Remote machine, no browser | Give the person the path of `latest.html` |
|
|
27
|
+
|
|
28
|
+
`--format md` wraps the same Markdown in a ```` ```kibi-signoff ```` or
|
|
29
|
+
```` ```kibi-questions ```` fence for host renderers; use it only where one
|
|
30
|
+
draws it, because everywhere else a fence shows as raw code.
|
|
31
|
+
`KIBI_SIGNOFF_FORMAT` sets the default for a host. `--format html --open`
|
|
32
|
+
writes and opens the page; `--format json` prints the view.
|
|
33
|
+
|
|
34
|
+
## Questions input
|
|
35
|
+
|
|
36
|
+
`{"questions":[...]}` or a bare array. Each question:
|
|
37
|
+
|
|
38
|
+
| Field | Required | Meaning |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `statement` | yes | The rule as it would be recorded |
|
|
41
|
+
| `title` | no | A short name for the card |
|
|
42
|
+
| `id` | no | The recorded requirement the question would change; the view quotes its current statement and firmness |
|
|
43
|
+
| `quote` | no | The person's words that would go in `origin.ref` |
|
|
44
|
+
| `firmness` | no | `firm`, `default` or `exploratory`, as it would be recorded |
|
|
45
|
+
| `governs` | no | Files or symbols the rule governs |
|
|
46
|
+
| `conflictsWith` | no | Recorded requirement ids it conflicts with; the view quotes them |
|
|
47
|
+
| `question` | no | What you ask, when it is more than "record this?" |
|
|
48
|
+
| `answer` | no | The person's answer; answered questions are struck out |
|
|
49
|
+
|
|
50
|
+
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
51
|
+
each answer into `answer`, render again, and record the rules only once every
|
|
52
|
+
question is answered. An answer is the person's words: quote it in
|
|
53
|
+
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
|
|
55
|
+
## Summary contents
|
|
56
|
+
|
|
57
|
+
| Section | Meaning |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| New | Requirement documents the change adds |
|
|
60
|
+
| Changed | Rewritten requirements; a changed statement shows before and after |
|
|
61
|
+
| Affected by the code change | Unchanged requirements whose implementing code changed (the `requirement_statement_unverified` set) |
|
|
62
|
+
| Superseded or retired | Requirements the change retires, supersedes or deletes |
|
|
63
|
+
|
|
64
|
+
Each requirement shows its firmness, origin, superseded rules, changed code
|
|
65
|
+
symbols, scenarios and proof state (the earliest unmet proof gate). Parts
|
|
66
|
+
Kibi could not compute are named in a `Note:` line instead of failing.
|
|
@@ -53,6 +53,8 @@ echo '{}' | npx --no-install kibi status --input -
|
|
|
53
53
|
`committed_with_repairs`, follow required typed `nextActions`; never retry the
|
|
54
54
|
original operation.
|
|
55
55
|
|
|
56
|
+
For every freshness, branch, or completion question, call `kb_status` first, then `kb_query` the entities and source files that status names, then `kb_check` as the last Kibi call before answering. Never skip the query step, even when status alone seems to answer the question. If another query or write follows a check, run `kb_check` again before answering. When asked whether requirements are consistent or proven, run `kb_query`, then `kb_check` with the domain-contradictions rule, then `kb_coverage`, and read whether the analysis was complete. Report any unmodeled or unknown clause as incomplete analysis, not as consistent. Only when every clause is fully modeled and compatible, state plainly that no conflict was found. For authorized knowledge changes, keep the exact supplied target and intended relationship edges, and discover and query those targets first. Validate the payload with `kb_upsert` and `dryRun: true`, then perform the authorized `kb_upsert` with that same payload and read the result back exactly before the final checks. A passing dry run is validation, not completion. Distinct authorized payloads may need several sequential writes, each validated and read back, but never retry a mutation that already committed. If a mutation returns `committed_with_repairs`, follow its typed `nextActions` instead of repeating the original operation.
|
|
57
|
+
|
|
56
58
|
## Guidance
|
|
57
59
|
|
|
58
60
|
- Treat MCP and the trusted project-local CLI as equal peer surfaces.
|
|
@@ -29,6 +29,8 @@ interfaces. Select the surface by capability; neither is semantically preferred.
|
|
|
29
29
|
For CLI JSON, use a dedicated route such as
|
|
30
30
|
`printf '%s\n' '{}' | kibi status --input -`.
|
|
31
31
|
|
|
32
|
+
For every traceability answer, begin with `kb_search` even when an identifier is already named, then exact-filter with `kb_query`, inspect relationships with `kb_graph`, and make `kb_status` the final Kibi call, including after `kb_graph` or `kb_coverage`; report no conclusions until that closing `kb_status` returns. When judging scenario feasibility, ground each step in the queried requirements, scenarios, tests, and symbols, and state missing links, ambiguity, or stale evidence explicitly rather than inferring them. For authorized coverage or link work, keep the exact supplied target and intended edges, discover and query those targets, then validate the payload with `kb_upsert` and `dryRun: true`. A passing dry run is only validation, not completion: next perform the real `kb_upsert` with the same payload, exact-read the result back with `kb_query`, run `kb_check` and `kb_coverage`, report the resulting proof state, and finish with `kb_status`. Distinct authorized payloads may each need their own sequential dry run and write, so there is no single-write limit, but never retry a mutation that already committed; on `committed_with_repairs`, execute the typed repair action instead.
|
|
33
|
+
|
|
32
34
|
## Workflow
|
|
33
35
|
|
|
34
36
|
Use the visible approved MCP tools or trusted project-local CLI as equal peer
|
|
@@ -50,6 +52,8 @@ plan_returned` with a hash-bound plan whose `nextActions[0].input` is the exact
|
|
|
50
52
|
through a new requirement linked with `supersedes`. Relationship deletes patch
|
|
51
53
|
shards while preserving unrelated records.
|
|
52
54
|
|
|
55
|
+
For executable coverage work, keep the production symbol's implements link to its requirement and link that same production symbol to its qualifying test with covered_by; reserve executable_for for a symbol that stands for the executable test itself, and never put executable_for on a symbol that also carries production ownership or coverage. Preserve the exact supplied target and intended edges, discover and query those targets, validate the payload with `kb_upsert` and `dryRun: true`, then perform the authorized real `kb_upsert` with the same payload and exact-read the result with `kb_query` before final checks, because validation alone is not completion. A passing dry run does not guarantee the commit: if the real `kb_upsert` returns an error, read its message and correct only the conflicting relationship on the same target rather than working around it with a new entity, then validate again with `dryRun: true`, write again, and exact-read it back. Distinct authorized payloads may each need their own sequential validation and write, so there is no single write limit, but never retry a mutation that already committed; on `committed_with_repairs`, execute the typed repair action instead. Then run `kb_check` and `kb_coverage`, report the proof and verification state they return, treating a dirty verification snapshot after a write as expected rather than as a failure, and finish with `kb_status`.
|
|
56
|
+
|
|
53
57
|
## Typed recovery and proof
|
|
54
58
|
|
|
55
59
|
Parse `kibiProtocol`, `resultVersion`, `status`, `effects`, diagnostics, and
|
|
@@ -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.22.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -121,6 +121,10 @@ component that renders it) with `implements` through `kb_upsert`. Without a read
|
|
|
121
121
|
still answers and `kibi sync` regenerates the manifest. The search tip and the
|
|
122
122
|
`.kb/` note appear once per session and need no action.
|
|
123
123
|
|
|
124
|
+
Before you edit a source file that Kibi tracks, run `kb_search` with that file in `sourceLocations`, and treat both its ranked results and its `data.answer` layer as discovery only, not as the governing text. Then call `kb_query` by `id` on each current governing requirement that the search names, read what each one requires, and make the edit only after those exact reads. A `kb_check`, `kb_status` or `kb_coverage` result does not replace that `kb_query` read. This rule only adds an exact read before the edit and does not change the order of any other step in this workflow. It adds nothing to a modeling or write task: that task still ends with the real `kb_upsert` of every planned fact and requirement and the closing `kb_check`.
|
|
125
|
+
|
|
126
|
+
For an edit that keeps the governing rule, limit the consultation before the edit to exactly two Kibi calls: `kb_search` with the file in `sourceLocations`, then one `kb_query` (by the governing requirement's `id`, or by `sourceFile` when several requirements govern the file). Do not start with `kb_status`, and do not repeat the search or the query before editing; run `kb_status`, `kb_check` and `kb_coverage` after the edit. This limit applies only to source edits. A task that models a claim keeps its full order, one step after the other: `kb_search`, then the exact `kb_query` of the supplied target, then `kb_model` with `mode: "analyze"` on the complete claim, then `mode: "predicates"` for each relational clause, then `kb_model` with `mode: "requirement"` for a strict or typed-rule clause, and only then the real `kb_upsert` of every planned fact and requirement and the closing `kb_check`. Never call `kb_model` before that exact `kb_query`, and never stop at a dry run.
|
|
127
|
+
|
|
124
128
|
## Safe workflow
|
|
125
129
|
|
|
126
130
|
1. Always discover before you mutate: start with `kb_search`, then exact-filter with `kb_query`. Use
|
|
@@ -356,7 +360,9 @@ authored. Each one is the order the write path accepts.
|
|
|
356
360
|
|
|
357
361
|
Entities record `origin` (`kind`: `human`, `agent`, `migration`, or `import`,
|
|
358
362
|
plus optional `ref` and `approved_by`). `kb_upsert` records `kind: agent` on
|
|
359
|
-
entities you create; leave `origin.approved_by` to the person who reviews them
|
|
363
|
+
entities you create; leave `origin.approved_by` to the person who reviews them,
|
|
364
|
+
and ask for that review with `kibi signoff` (see `kibi-decisions`), never with
|
|
365
|
+
a summary in your own words.
|
|
360
366
|
An exception (a requirement that `exempts` another) exempts nothing until a
|
|
361
367
|
human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
362
368
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
@@ -365,6 +371,8 @@ exists in `rationale`, or link the ADR that explains it.
|
|
|
365
371
|
## Decision firmness
|
|
366
372
|
|
|
367
373
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|
|
374
|
+
Load `kibi-decisions` when a person states a rule, a hook asks before an edit
|
|
375
|
+
of firm code, or a request conflicts with a recorded rule.
|
|
368
376
|
Search answers, `kb_query` rows and hook snippets show it (snippets label only
|
|
369
377
|
`[firm: ask before changing]` and `[exploratory]`; an unlabeled decision is
|
|
370
378
|
`default`).
|
|
@@ -394,17 +402,12 @@ task or in reply: then supersede it with `firmness: firm` and `origin.ref` to
|
|
|
394
402
|
their words (or, for a correction they asked for in place, update it with
|
|
395
403
|
`origin.ref` to those words), and say in the final answer which rule changed.
|
|
396
404
|
|
|
397
|
-
Set `firmness` from what a human actually said: only their stated
|
|
398
|
-
`firm` (with `origin.ref`
|
|
399
|
-
guess is `exploratory`.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
words): name the evidence (a failing test, a measured cost, a constraint the
|
|
404
|
-
old decision missed, a new requirement, the person's instruction) and answer
|
|
405
|
-
the old decision's reasoning; `kb_check` blocks it otherwise. A preference is
|
|
406
|
-
not evidence: propose it instead of superseding. Kibi checks only that a firm
|
|
407
|
-
decision has a reference; never cite words nobody said.
|
|
405
|
+
Set `firmness` explicitly from what a human actually said: only their stated
|
|
406
|
+
rule is `firm` (with `origin.ref` to their words); your own pick is `default`;
|
|
407
|
+
a guess is `exploratory`. A supersede needs a `## Why this changed` section of
|
|
408
|
+
at least 12 words naming the evidence; a preference is not evidence. Never
|
|
409
|
+
cite words nobody said. `kibi-decisions` has the recording and supersede
|
|
410
|
+
payloads.
|
|
408
411
|
|
|
409
412
|
Conditional clauses ("only when", "only if", "must not ... unless") compile
|
|
410
413
|
into typed `forbid` rules linked by `requires_rule`, not property facts; one
|
|
@@ -418,7 +421,8 @@ read `unresolved` as consistent. Compare the intent with each candidate's
|
|
|
418
421
|
`statement`, then compile again with `conflictReviews`
|
|
419
422
|
(`{requirementId, verdict: "conflict" | "no_conflict", note}`). On a conflict
|
|
420
423
|
the plan is `blocked`: ask the human which rule holds (a firm requirement is
|
|
421
|
-
theirs), then supersede or change it, or change the intent
|
|
424
|
+
theirs), then supersede or change it, or change the intent (see
|
|
425
|
+
`kibi-decisions`).
|
|
422
426
|
|
|
423
427
|
## Semantic and proof guardrails
|
|
424
428
|
|
|
@@ -558,4 +562,5 @@ retrying the same payload; inspect the typed error and `nextActions`.
|
|
|
558
562
|
Kibi may now author tracked Markdown/YAML evidence transactionally. The former
|
|
559
563
|
statement “Kibi operation writes do not automatically stage markdown evidence”
|
|
560
564
|
means Kibi writes do not Git-stage it: review and commit remain ordinary Git
|
|
561
|
-
workflows.
|
|
565
|
+
workflows. When `kibi check --staged` or the pre-commit hook blocks a commit,
|
|
566
|
+
load `kibi-commit-review`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ExtractedEntity } from "../extractors/markdown.js";
|
|
2
|
+
import { type SignoffProof, type SignoffQuestionInput, type SignoffQuestions, type SignoffSummary } from "./model.js";
|
|
3
|
+
export type SignoffScope = "staged" | "working";
|
|
4
|
+
/** Changed code symbols per requirement they implement. */
|
|
5
|
+
export type AffectedRequirements = ReadonlyMap<string, readonly string[]>;
|
|
6
|
+
export type SignoffCollectDeps = Readonly<{
|
|
7
|
+
/** Run git in the workspace and return stdout; throws on failure. */
|
|
8
|
+
git?: (args: readonly string[]) => string;
|
|
9
|
+
/** Requirements the changed code implements, from the impact analysis. */
|
|
10
|
+
loadAffected?: (scope: SignoffScope) => Promise<AffectedRequirements>;
|
|
11
|
+
/** Proof rows by requirement id, from coverage. */
|
|
12
|
+
loadProof?: () => Promise<ReadonlyMap<string, SignoffProof>>;
|
|
13
|
+
now?: () => Date;
|
|
14
|
+
}>;
|
|
15
|
+
/** The requirement's statement: its semantic text, else its title. */
|
|
16
|
+
export declare function requirementStatement(entity: ExtractedEntity): string;
|
|
17
|
+
/**
|
|
18
|
+
* The end-of-work signoff summary: the requirements the change adds, rewrites,
|
|
19
|
+
* retires, or leaves unchanged while changing code that implements them, each
|
|
20
|
+
* with its statement, firmness, origin, scenarios and proof state.
|
|
21
|
+
*/
|
|
22
|
+
export declare function collectSignoffSummary(workspaceRoot: string, scope: SignoffScope, deps?: SignoffCollectDeps): Promise<SignoffSummary>;
|
|
23
|
+
/**
|
|
24
|
+
* Requirements whose implementing code the change edits, read from the
|
|
25
|
+
* `requirement_statement_unverified` impact diagnostics of `kibi check`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadAffectedForScope(workspaceRoot: string, scope: SignoffScope): Promise<AffectedRequirements>;
|
|
28
|
+
/**
|
|
29
|
+
* The mid-work decision questions, numbered, with the recorded requirement a
|
|
30
|
+
* question would change and the recorded rules it conflicts with quoted from
|
|
31
|
+
* the knowledge base rather than from the agent's memory.
|
|
32
|
+
*/
|
|
33
|
+
export declare function collectSignoffQuestions(workspaceRoot: string, inputs: readonly SignoffQuestionInput[], now?: () => Date): SignoffQuestions;
|
|
34
|
+
/**
|
|
35
|
+
* Parse the questions input: `{"questions":[{statement, id?, title?, quote?,
|
|
36
|
+
* firmness?, governs?, conflictsWith?, question?, answer?}]}` or a bare array.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseSignoffQuestionsInput(raw: string): SignoffQuestionInput[];
|
|
39
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/signoff/collect.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAGrB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AASpB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,2DAA2D;AAC3D,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,qEAAqE;IACrE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;IAC1C,0EAA0E;IAC1E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC,CAAC;AAuCH,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAEpE;AAyGD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,CA6JzB;AAGD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,oBAAoB,CAAC,CA8B/B;AAGD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,GAAG,GAAE,MAAM,IAAuB,GACjC,gBAAgB,CA4BlB;AA+BD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,GACV,oBAAoB,EAAE,CAkDxB"}
|