@hraness/kb 0.18.0 → 0.19.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/README.md +197 -113
- package/dist/authoring.js +2 -2
- package/dist/benchmark.js +3 -3
- package/dist/cli.js +16 -12
- package/dist/evaluation-builder.js +5 -5
- package/dist/evaluation-kb.js +5 -5
- package/dist/graph.js +3 -1
- package/dist/{index-zxdy5pby.js → index-5m2ydj5q.js} +2 -2
- package/dist/{index-cxfrakt7.js → index-ekpwvbra.js} +5 -2
- package/dist/{index-jsmvyyvf.js → index-ey46z1zf.js} +4 -4
- package/dist/{index-cv6fh7z5.js → index-gm9t95d9.js} +1 -1
- package/dist/{index-01jj6rbv.js → index-gxr0fctd.js} +3 -3
- package/dist/index-nd6nynv2.js +1162 -0
- package/dist/{index-s2gw5aw9.js → index-qwgsmtsz.js} +1 -1
- package/dist/{index-zzhgcwyt.js → index-vxmf14m1.js} +3 -3
- package/dist/{index-n5dd7r0v.js → index-xw9ac71d.js} +2 -2
- package/dist/{index-1vrd1rmn.js → index-ykvvkd77.js} +1 -1
- package/dist/index.js +30 -8
- package/dist/percolate.js +22 -2
- package/dist/portfolio.js +5 -5
- package/dist/sdk.js +4 -4
- package/dist/search.js +2 -2
- package/dist/semantic.js +3 -3
- package/dist/workflows/decision-context.js +5 -5
- package/dist/workflows/index.js +5 -5
- package/package.json +1 -1
- package/skills/kb/AGENTS.md +3 -0
- package/skills/kb/SKILL.md +38 -29
- package/skills/kb/agents/openai.yaml +2 -2
- package/skills/kb/references/companion-skills.md +96 -0
- package/skills/kb/references/customize.md +123 -0
- package/skills/kb/references/percolate.md +39 -7
- package/skills/kb/references/query.md +21 -0
- package/skills/kb/templates/companion-skill.template.md +57 -0
- package/src/authoring.ts +5 -3
- package/src/cli.ts +12 -7
- package/src/graph.ts +8 -1
- package/src/percolate.ts +1088 -17
- package/dist/index-dyqwejk5.js +0 -531
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Customize a KB setup
|
|
2
|
+
|
|
3
|
+
Design the smallest KB arrangement that answers the user's recurring memory
|
|
4
|
+
questions. Begin with an interview and read-only inspection. Do not install a
|
|
5
|
+
runtime, initialize a vault, build an index, access an account, or write a file
|
|
6
|
+
before the proposal has the user's approval.
|
|
7
|
+
|
|
8
|
+
## Establish the boundary
|
|
9
|
+
|
|
10
|
+
Identify the repositories, vaults, people, agents, and time horizons in scope.
|
|
11
|
+
Ask what the KB must help a future agent recover, which information must remain
|
|
12
|
+
outside it, and which existing instructions govern the target paths. Treat the
|
|
13
|
+
user's explicit request as authorization for the named work. Do not extend it
|
|
14
|
+
to another path, repository, account, application, or integration.
|
|
15
|
+
|
|
16
|
+
For a new vault, ask for or propose an exact location. Do not require an
|
|
17
|
+
existing `index.md`. For an existing vault, resolve its front door and read the
|
|
18
|
+
applicable `AGENTS.md` files before proposing changes.
|
|
19
|
+
|
|
20
|
+
## Inspect without mutation
|
|
21
|
+
|
|
22
|
+
Inspect only the surfaces needed to understand the current setup. Typical
|
|
23
|
+
evidence includes directory structure, existing Markdown conventions, scoped
|
|
24
|
+
agent guides, active plans, source records, repository paths, and available
|
|
25
|
+
local commands. Keep filesystem, application, account, network, and
|
|
26
|
+
integration access within the user's stated scope and the host's actual
|
|
27
|
+
permissions.
|
|
28
|
+
|
|
29
|
+
Do not run `kb doctor`, `kb init`, `kb index`, QMD, hybrid or semantic search,
|
|
30
|
+
an installer, or a command that may create a cache during this phase. Do not
|
|
31
|
+
create a hidden profile such as `.context/me.md` or infer personal context from
|
|
32
|
+
an ambient account.
|
|
33
|
+
|
|
34
|
+
## Interview in small batches
|
|
35
|
+
|
|
36
|
+
Ask only questions whose answers change the proposed structure. Prefer a small
|
|
37
|
+
batch about one decision at a time:
|
|
38
|
+
|
|
39
|
+
- Which recurring questions should the KB answer?
|
|
40
|
+
- Which sources, maintained explanations, plans, and repository rules already
|
|
41
|
+
exist?
|
|
42
|
+
- Which writes should happen automatically, require review, or never happen?
|
|
43
|
+
- Which recurring action is common enough to justify a companion skill?
|
|
44
|
+
|
|
45
|
+
Summarize each resolved decision before moving to the next uncertain one. A
|
|
46
|
+
short interview may conclude that the standard profile or no change is best.
|
|
47
|
+
|
|
48
|
+
## Propose the smallest useful change
|
|
49
|
+
|
|
50
|
+
Describe the exact files and surfaces before editing. Use this table:
|
|
51
|
+
|
|
52
|
+
| Surface | Exact target | Read | Write | Purpose | Approval |
|
|
53
|
+
| --- | --- | --- | --- | --- | --- |
|
|
54
|
+
| Vault | `<path>` | `<bounded inputs>` | `<files or none>` | `<memory question>` | `<approved or pending>` |
|
|
55
|
+
|
|
56
|
+
Propose zero to three companion skills. Each proposed skill must own a distinct
|
|
57
|
+
recurring request that the main `kb` router cannot express clearly enough. Do
|
|
58
|
+
not add a skill only to restate repository policy or wrap one command.
|
|
59
|
+
|
|
60
|
+
State the verification, idempotence, retry, and failure behavior for every
|
|
61
|
+
write. Keep Markdown and Git authoritative. Treat indexes, embeddings,
|
|
62
|
+
catalogs, graph reports, and caches as replaceable views.
|
|
63
|
+
|
|
64
|
+
## Obtain approval
|
|
65
|
+
|
|
66
|
+
Present the proposal and wait when its writes are not already authorized by
|
|
67
|
+
the user's explicit request. Approval applies to the exact targets and
|
|
68
|
+
operations shown. A changed path, expanded repository, additional skill,
|
|
69
|
+
account surface, network action, or broader write requires renewed approval.
|
|
70
|
+
|
|
71
|
+
Silence, a denial, or an ambiguous response is not approval. Inspection does
|
|
72
|
+
not grant write authority. Discovery of a command, application, account, or
|
|
73
|
+
integration does not authorize its use.
|
|
74
|
+
|
|
75
|
+
## Scaffold within the approved boundary
|
|
76
|
+
|
|
77
|
+
Create only approved paths. For a companion skill, read [Companion skill
|
|
78
|
+
contracts](companion-skills.md) and copy
|
|
79
|
+
[`companion-skill.template.md`](../templates/companion-skill.template.md) to
|
|
80
|
+
`<explicit-skill-root>/<name>/SKILL.md`. Never edit the template inside an
|
|
81
|
+
installed package or `node_modules`.
|
|
82
|
+
|
|
83
|
+
If approved execution needs the KB CLI, prepare the runtime now using the main
|
|
84
|
+
skill's pinned installation instructions. Installation does not authorize
|
|
85
|
+
`kb init`, indexing, semantic search, or vault writes. Run only the approved
|
|
86
|
+
commands and exact allowlisted writes.
|
|
87
|
+
|
|
88
|
+
The scaffold executor writes filesystem targets only. It never performs an
|
|
89
|
+
application, account, network, or integration write. A companion skill may
|
|
90
|
+
describe one of those later actions, but its execution is a separate runtime
|
|
91
|
+
request with its own exact proposal, approval, tool boundary, and result.
|
|
92
|
+
|
|
93
|
+
On a repeated request, compare the desired bytes with the approved targets.
|
|
94
|
+
Treat an exact match as a no-op. Stop on divergent existing content, a symlink,
|
|
95
|
+
a path that escapes the approved root, an unapproved external surface, or a
|
|
96
|
+
partial write. Report the retained state instead of overwriting, silently
|
|
97
|
+
retrying, or widening the boundary.
|
|
98
|
+
|
|
99
|
+
## Start with real material
|
|
100
|
+
|
|
101
|
+
Use a small amount of material that exercises the agreed structure: one saved
|
|
102
|
+
source, one maintained explanation, one plan, or one repository-context
|
|
103
|
+
mapping. Do not manufacture empty directories, placeholder notes, a complete
|
|
104
|
+
ontology, or speculative metadata merely to make the vault look populated.
|
|
105
|
+
|
|
106
|
+
## Verify and hand off
|
|
107
|
+
|
|
108
|
+
Verify every approved file and record the exact paths changed. Run the
|
|
109
|
+
narrowest applicable KB checks only when they were approved and the runtime is
|
|
110
|
+
available. State what remains unconfigured, which views are rebuildable, and
|
|
111
|
+
which action would require separate authority.
|
|
112
|
+
|
|
113
|
+
Keep durable output free of credentials, session material, account exports,
|
|
114
|
+
and hidden ambient context. Record source provenance and the boundary of any
|
|
115
|
+
incomplete acquisition.
|
|
116
|
+
|
|
117
|
+
## Evolve an existing setup
|
|
118
|
+
|
|
119
|
+
Re-run the boundary, inspection, interview, proposal, and approval steps when
|
|
120
|
+
the vault's recurring questions change. Prefer a focused convention or skill
|
|
121
|
+
revision to a migration. Preserve authored Markdown and Git history, and do not
|
|
122
|
+
mass-rewrite metadata to fit a new taxonomy unless a measured retrieval or
|
|
123
|
+
maintenance problem justifies that work.
|
|
@@ -42,6 +42,16 @@ minimum of two therefore requires two shared signals, not merely both endpoints
|
|
|
42
42
|
of one tag match. Other candidate kinds count their natural unit: supporting
|
|
43
43
|
notes, mention occurrences, or authored hygiene evidence.
|
|
44
44
|
|
|
45
|
+
Percolation Result V2 reports a missing relationship as an unordered pair of
|
|
46
|
+
endpoints with `predicate: { "kind": "required" }`. The output does not choose
|
|
47
|
+
which note owns the assertion, its direction, or its predicate. In particular,
|
|
48
|
+
it never inserts `related-to` as a fallback. Read both notes and their evidence,
|
|
49
|
+
then choose a source, target, and predicate only when the prose establishes that
|
|
50
|
+
claim. Historical unversioned V1 results may contain a suggested predicate;
|
|
51
|
+
parse them through the explicit V1 compatibility surface and do not treat that
|
|
52
|
+
suggestion as an authored fact or silently upgrade it to V2. V1 remains
|
|
53
|
+
available through the 0.19 release line and is not removed before 0.20.0.
|
|
54
|
+
|
|
45
55
|
For a missing concept, use `suggestedId`. When `collidesWith` is non-null, the
|
|
46
56
|
natural ID is already an ordinary note, so KB chooses an unoccupied
|
|
47
57
|
`*-concept` ID. Read the occupied note before deciding whether to create the
|
|
@@ -88,11 +98,26 @@ kb relation add notes/write-path supports notes/durable-agent-memory \
|
|
|
88
98
|
--root "$KB_ROOT"
|
|
89
99
|
```
|
|
90
100
|
|
|
91
|
-
Use a specific lower-kebab-case predicate.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
Use a specific lower-kebab-case predicate. Recommended predicates for common
|
|
102
|
+
KB evidence and maintenance claims are:
|
|
103
|
+
|
|
104
|
+
- `synthesizes` when the source combines and maintains conclusions from the
|
|
105
|
+
target material;
|
|
106
|
+
- `evidenced-by` when the target directly supports a claim in the source;
|
|
107
|
+
- `informed-by` when the target influenced the source without serving as its
|
|
108
|
+
direct evidence;
|
|
109
|
+
- `supersedes` when the source deliberately replaces the target as the current
|
|
110
|
+
account;
|
|
111
|
+
- `contradicts` when the source records a supported incompatible claim.
|
|
112
|
+
|
|
113
|
+
This vocabulary is advisory. A vault may use any canonical custom predicate
|
|
114
|
+
whose meaning its prose establishes. Do not assign a recommended predicate by
|
|
115
|
+
directory, note type, shared tags, chronology, or similarity alone. A local
|
|
116
|
+
target is an exact vault-root note ID without `.md`. A reviewed cross-vault
|
|
117
|
+
target is its stable qualified identity, such as
|
|
118
|
+
`kb://hraness/kb/document-id`; never use a checkout path as cross-vault
|
|
119
|
+
identity. Ground the assertion in nearby prose or evidence; the frontmatter is
|
|
120
|
+
an indexable statement, not a substitute for explanation.
|
|
96
121
|
|
|
97
122
|
List or remove relationships without editing reciprocal notes:
|
|
98
123
|
|
|
@@ -103,8 +128,15 @@ kb relation remove notes/write-path supports notes/durable-agent-memory \
|
|
|
103
128
|
```
|
|
104
129
|
|
|
105
130
|
Never write inverse edges, generated backlinks, inferred transitive
|
|
106
|
-
relationships,
|
|
107
|
-
|
|
131
|
+
relationships, reciprocal edges, similarity-derived relationships, or
|
|
132
|
+
semantic-search scores into Markdown. External or unclassified material is
|
|
133
|
+
outside this vocabulary evaluation and remains unresolved. Those are derived
|
|
134
|
+
views or review work.
|
|
135
|
+
|
|
136
|
+
The interview-first setup and relationship-review pattern builds on Frank
|
|
137
|
+
Chen's public notes about [designing a personal knowledge base with an
|
|
138
|
+
agent](https://gist.github.com/fxchen/773397095d7a6bffda621e4237da0da9)
|
|
139
|
+
and [extending it with skills](https://gist.github.com/fxchen/09cb410b22c9c5256d80243ee925b57e).
|
|
108
140
|
|
|
109
141
|
## Query before concluding
|
|
110
142
|
|
|
@@ -14,6 +14,27 @@ authority; search scores, metadata rows, and graph results are derived views.
|
|
|
14
14
|
- Pass the resolved path to every `--root`; do not scan a repository root merely
|
|
15
15
|
because that is where the agent session started.
|
|
16
16
|
|
|
17
|
+
## Recover a stopped session
|
|
18
|
+
|
|
19
|
+
When the user asks to resume earlier work, begin with the path being changed.
|
|
20
|
+
Keep each retrieval signal separate so the agent can inspect why a record was
|
|
21
|
+
returned:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
kb context packages/parser/src/index.ts --root "$KB_ROOT" --repo "$KB_REPO"
|
|
25
|
+
kb search "why parser retries stop" --root "$KB_ROOT" --mode exact \
|
|
26
|
+
--history --repo "$KB_REPO" --json
|
|
27
|
+
kb backlinks notes/parser-contract --root "$KB_ROOT" --json
|
|
28
|
+
kb history notes/parser-contract --root "$KB_ROOT" \
|
|
29
|
+
--repo "$KB_REPO" --json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Replace the example path, query, and note ID with values from the current task.
|
|
33
|
+
Read the inherited guides and authoritative Markdown returned by these views.
|
|
34
|
+
Use the backlink to inspect related plans and use Git history as provenance,
|
|
35
|
+
not as proof that the note remains correct. This workflow recovers only context
|
|
36
|
+
that was persisted in files or Git; it does not reconstruct private chat.
|
|
37
|
+
|
|
17
38
|
## Choose the retrieval lane
|
|
18
39
|
|
|
19
40
|
- Repository file or directory: run `kb context` first. Read its inherited
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: replace-with-skill-name
|
|
3
|
+
description: Replace with the recurring KB request that should select this skill.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Replace with the skill title
|
|
7
|
+
|
|
8
|
+
## Use when
|
|
9
|
+
|
|
10
|
+
State the exact recurring KB request that this skill owns.
|
|
11
|
+
|
|
12
|
+
## Do not use when
|
|
13
|
+
|
|
14
|
+
Route generic query, capture, plan, percolation, refresh, and validation work
|
|
15
|
+
to the public `kb` skill. State any additional exclusions that prevent an
|
|
16
|
+
unsafe or ambiguous match.
|
|
17
|
+
|
|
18
|
+
## Inputs and preconditions
|
|
19
|
+
|
|
20
|
+
List required inputs, existing state, commands, and authorization. Do not
|
|
21
|
+
install, probe an account, create a cache, or mutate state while resolving
|
|
22
|
+
these preconditions.
|
|
23
|
+
|
|
24
|
+
## Surfaces and authority
|
|
25
|
+
|
|
26
|
+
List every filesystem, repository, application, account, network, and
|
|
27
|
+
integration surface this workflow may read or write. Discovery and an existing
|
|
28
|
+
session grant no authority. The setup scaffold writes filesystem targets only;
|
|
29
|
+
describe any later external action as a separate runtime request with its own
|
|
30
|
+
proposal, approval, capable tool, and result.
|
|
31
|
+
|
|
32
|
+
## Approval
|
|
33
|
+
|
|
34
|
+
Name the exact write targets and effects. State when existing user
|
|
35
|
+
authorization applies and which proposal changes require renewed approval.
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
Describe the smallest deterministic sequence that produces the approved
|
|
40
|
+
result. Keep every effect inside the approved boundary.
|
|
41
|
+
|
|
42
|
+
## Idempotence, retries, and failure
|
|
43
|
+
|
|
44
|
+
Treat matching output as a no-op. Stop on divergent existing content, path
|
|
45
|
+
escape, symbolic links, partial writes, or an unapproved surface. Do not
|
|
46
|
+
silently retry or overwrite.
|
|
47
|
+
|
|
48
|
+
## Durable outputs and provenance
|
|
49
|
+
|
|
50
|
+
Name the files or records that persist, the evidence they retain, and their
|
|
51
|
+
authority. Exclude credentials, tokens, cookies, session data, and unrelated
|
|
52
|
+
ambient context.
|
|
53
|
+
|
|
54
|
+
## Verification
|
|
55
|
+
|
|
56
|
+
Name the narrow checks that demonstrate the approved result and the KB
|
|
57
|
+
maintenance required after durable edits.
|
package/src/authoring.ts
CHANGED
|
@@ -35,7 +35,10 @@ import {
|
|
|
35
35
|
type NoteLock,
|
|
36
36
|
type NoteLockOptions,
|
|
37
37
|
} from "./note-lock.js";
|
|
38
|
-
import {
|
|
38
|
+
import {
|
|
39
|
+
isCanonicalNoteId,
|
|
40
|
+
isCanonicalRelationPredicate,
|
|
41
|
+
} from "./graph.js";
|
|
39
42
|
import {
|
|
40
43
|
parseDocumentId,
|
|
41
44
|
parseQualifiedDocumentUri,
|
|
@@ -43,7 +46,6 @@ import {
|
|
|
43
46
|
|
|
44
47
|
const MAX_NOTE_BYTES = 16 * 1024 * 1024;
|
|
45
48
|
const NOTE_REVISION_PATTERN = /^sha256:[0-9a-f]{64}$/u;
|
|
46
|
-
const PREDICATE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
47
49
|
const MAX_PARENT_DIRECTORY_ENTRIES = 100_000;
|
|
48
50
|
const MAX_RECOVERY_LOCATIONS_PER_NOTE = 8;
|
|
49
51
|
|
|
@@ -259,7 +261,7 @@ export function normalizeRelationPredicate(value: string): string {
|
|
|
259
261
|
.replaceAll("_", "-")
|
|
260
262
|
.replace(/\s+/gu, "-")
|
|
261
263
|
.replace(/-{2,}/gu, "-");
|
|
262
|
-
if (!
|
|
264
|
+
if (!isCanonicalRelationPredicate(normalized)) {
|
|
263
265
|
throw new TypeError(`not a valid relation predicate: ${JSON.stringify(value)}`);
|
|
264
266
|
}
|
|
265
267
|
return normalized;
|
package/src/cli.ts
CHANGED
|
@@ -81,6 +81,7 @@ import {
|
|
|
81
81
|
MAX_PERCOLATION_NOTES,
|
|
82
82
|
MAX_SCOPED_PERCOLATION_MENTION_PAIRS,
|
|
83
83
|
percolateVault,
|
|
84
|
+
type PercolationCliOutputV2,
|
|
84
85
|
type PercolationResult,
|
|
85
86
|
} from "./percolate.js";
|
|
86
87
|
import {
|
|
@@ -2693,7 +2694,7 @@ function renderPercolation(result: PercolationResult, note: string | undefined):
|
|
|
2693
2694
|
);
|
|
2694
2695
|
} else if (candidate.kind === "missing-relation") {
|
|
2695
2696
|
lines.push(
|
|
2696
|
-
` relation ${safe(candidate.source)} ${safe(candidate.
|
|
2697
|
+
` relation pair {${safe(candidate.source)}, ${safe(candidate.target)}} (predicate required; ${candidate.support} shared signals)`,
|
|
2697
2698
|
);
|
|
2698
2699
|
} else if (candidate.kind === "unlinked-mention") {
|
|
2699
2700
|
lines.push(
|
|
@@ -2754,13 +2755,17 @@ async function runPercolate(
|
|
|
2754
2755
|
limit: command.limit,
|
|
2755
2756
|
},
|
|
2756
2757
|
);
|
|
2758
|
+
const jsonOutput: PercolationCliOutputV2 = {
|
|
2759
|
+
root: snapshot.root,
|
|
2760
|
+
note: command.note ?? null,
|
|
2761
|
+
minSupport: command.minSupport,
|
|
2762
|
+
limit: command.limit,
|
|
2763
|
+
schemaVersion: result.schemaVersion,
|
|
2764
|
+
candidates: result.candidates,
|
|
2765
|
+
truncated: result.truncated,
|
|
2766
|
+
};
|
|
2757
2767
|
output.stdout(command.json
|
|
2758
|
-
? terminalSafeJson(
|
|
2759
|
-
root: snapshot.root,
|
|
2760
|
-
note: command.note ?? null,
|
|
2761
|
-
minSupport: command.minSupport,
|
|
2762
|
-
...result,
|
|
2763
|
-
})
|
|
2768
|
+
? terminalSafeJson(jsonOutput)
|
|
2764
2769
|
: sanitizeTerminalText(renderPercolation(result, command.note)));
|
|
2765
2770
|
return 0;
|
|
2766
2771
|
}
|
package/src/graph.ts
CHANGED
|
@@ -327,6 +327,13 @@ type ParsedMetadata = {
|
|
|
327
327
|
const relationPredicatePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
328
328
|
const maxNoteIdLength = 2_048;
|
|
329
329
|
|
|
330
|
+
/** Whether a value is the exact lower-kebab predicate accepted by the graph. */
|
|
331
|
+
export function isCanonicalRelationPredicate(value: string): boolean {
|
|
332
|
+
return value !== ""
|
|
333
|
+
&& value === value.normalize("NFC")
|
|
334
|
+
&& relationPredicatePattern.test(value);
|
|
335
|
+
}
|
|
336
|
+
|
|
330
337
|
/**
|
|
331
338
|
* Whether a value is the exact, extensionless vault-root ID used on disk.
|
|
332
339
|
*
|
|
@@ -476,7 +483,7 @@ function parsedRelations(
|
|
|
476
483
|
}
|
|
477
484
|
|
|
478
485
|
const predicate = pair.key.value.normalize("NFC");
|
|
479
|
-
if (!
|
|
486
|
+
if (!isCanonicalRelationPredicate(predicate)) {
|
|
480
487
|
relationIssues.push(malformedRelation(
|
|
481
488
|
source,
|
|
482
489
|
predicateLine,
|