Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 79 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ system.
Bun 1.3.14 or newer is required.

```sh
bun add --global @hraness/kb@0.18.1
bun add --global @hraness/kb@0.19.0
kb --help
```

Expand Down Expand Up @@ -188,6 +188,14 @@ Retrieval is bounded. The high-level `kb search` and `KnowledgeBaseSession.searc

Each note owns its outbound typed relationships in frontmatter. KB derives backlinks, inverse edges, and bounded traversal at read time, so parallel agents do not contend on one generated fact file. `kb percolate <note>` reports recurring concepts and missing-link candidates with inspectable support but writes nothing. An agent reads the cited notes before creating a reusable concept or relationship. Semantic similarity never creates an edge automatically.

Percolation Result V2 presents a missing relationship as an unordered pair of
notes with a required predicate. It does not choose the source, direction, or a
`related-to` fallback. Recommended authored predicates include `synthesizes`,
`evidenced-by`, `informed-by`, `supersedes`, and `contradicts`; they are an
advisory vocabulary, so a vault can use another canonical predicate when its
prose and evidence define the claim. KB never infers reciprocal, inverse,
transitive, or similarity-derived relationships.

Git provenance is opt-in. A search without `--history` performs no Git indexing. `--history` requests best-effort provenance, while `--require-history` rejects unavailable history or incomplete provenance for the selected notes. If one commit exceeds the 2,000-path detail limit, KB retains its identity and vault-local note associations, marks its co-change detail incomplete, and continues through later commits. Best-effort search reports that requested lane as partial.

Local attachment checks cover Markdown and Obsidian references to images, PDFs, and editable tldraw sources. They reject missing or escaping files while leaving external URLs alone. A source-inbox view separately lists recent captures that have no inbound disposition from maintained knowledge. It is an advisory, not an automatic backlink requirement: a saved source may intentionally remain a leaf.
Expand All @@ -204,6 +212,39 @@ The same mixed-cache, single-run test recorded p95 latencies of 44.345 milliseco

Search finds candidates. Similarity does not establish that a passage is current, correct, or supported by its sources. The Markdown, cited captures, explicit relationships, and requested Git history supply the material a reader must inspect.

### Customize through an approved proposal

The Agent Skill routes setup and evolution requests before it prepares a
runtime. It inspects the proposed location without mutation, interviews the
user about the memory questions the KB should answer, and presents exact read
and write targets. Only the approved targets may be scaffolded. A changed path,
repository, account, integration, or companion skill requires renewed
approval.

The standard router may be enough. A recurring ritual can instead receive a
companion skill with explicit inputs, authority, durable outputs, idempotence,
failure behavior, and verification. These skills are inert instructions. They
do not create a plugin runtime, execute vault metadata, inherit ambient account
access, or couple application code to the KB. An exact repeat is a no-op;
divergence, path escape, symbolic links, partial writes, and unapproved
external surfaces stop the workflow.

The repository's fake-capability suite exercises those transitions. It is a
tested contract example, not proof that every agent or host integration
complies.

This workflow builds on Frank Chen's public notes about [designing a personal
knowledge base with an
agent](https://gist.github.com/fxchen/773397095d7a6bffda621e4237da0da9)
and [extending it with
skills](https://gist.github.com/fxchen/09cb410b22c9c5256d80243ee925b57e).

KB ships no `kb_role` metadata, lifecycle resolver or API, lifecycle CLI,
compatibility diagnostic, or metadata migration. A frozen Phase 0 value gate
must show that those surfaces improve deterministic agent decisions before they
are introduced. Current and historical plan routing remains derived from
existing type, path, and status conventions.

### Adopt the smallest useful split

Start with a short inherited `AGENTS.md` path for rules whose omission would make an edit wrong. A small knowledge base may need only Markdown, Git, an index page, and ordinary file search. Add source capture when evidence keeps disappearing. Add repository scopes when agents need to recover current memory from code paths. Add metadata or hybrid search when file search stops answering the repository's questions. Add links and graph views only when the relationships themselves help people make decisions.
Expand All @@ -219,43 +260,43 @@ Treat the knowledge base as repository-adjacent durable memory. Authored Markdow
Copy this prompt into Codex, Claude Code, or another coding agent:

```text
Install the `kb` Agent Skill from `hraness/kb#v0.18.1` with the standard skills
Install the `kb` Agent Skill from `hraness/kb#v0.19.0` with the standard skills
CLI. Use the skill's runtime instructions to install the exact
`@hraness/kb@0.18.1` registry release only when the command is missing. Verify it
`@hraness/kb@0.19.0` registry release only when the command is missing. Verify it
with `kb doctor` and `kb --help`, but do not initialize or modify a vault until
I ask.
```

Install the single public skill with either runner:

```sh
npx skills add hraness/kb#v0.18.1
bunx skills add hraness/kb#v0.18.1
npx skills add hraness/kb#v0.19.0
bunx skills add hraness/kb#v0.19.0
```

Both commands discover the same `kb` skill and install it into the selected
agent runner. Skill installation is inert: it does not initialize a vault,
refresh a catalog, or edit Markdown. When invoked, the skill uses an existing
`kb` command or, when the command is missing, checks for Bun and installs the
CLI from the immutable `@hraness/kb@0.18.1` npm version.
CLI from the immutable `@hraness/kb@0.19.0` npm version.

The public skills CLI reads `skills/kb/` from the repository. The immutable
`0.18.1` npm package includes the same tree under
`0.19.0` npm package includes the same tree under
`node_modules/@hraness/kb/skills/kb/`, and the package check verifies that the
installed skill is byte-identical to the repository source.

Install the two global commands with Bun:

```sh
bun add --global @hraness/kb@0.18.1
bun add --global @hraness/kb@0.19.0
kb --help
kb-evaluation-builder --help
```

The same registry package can be installed with npm:

```sh
npm install --global --ignore-scripts @hraness/kb@0.18.1
npm install --global --ignore-scripts @hraness/kb@0.19.0
kb --help
```

Expand All @@ -268,20 +309,20 @@ reviewed and enabled; run `kb doctor` to inspect the resulting capabilities.
For programmatic use, add the exact npm version to a Bun project:

```sh
bun add --exact @hraness/kb@0.18.1
bun add --exact @hraness/kb@0.19.0
```

The resulting dependency should remain exact:

```json
{
"dependencies": {
"@hraness/kb": "0.18.1"
"@hraness/kb": "0.19.0"
}
}
```

Version 0.18.1 retains three public GitHub dependencies: `@hraness/oh` at
Version 0.19.0 retains three public GitHub dependencies: `@hraness/oh` at
immutable release `v0.2.0` for closure verification,
`@steipete/sweet-cookie` at Hraness release `v0.4.2` for the cookie-scope safety
fork, and `@tobilu/qmd` at commit
Expand Down Expand Up @@ -467,7 +508,12 @@ Predicates use lower-kebab-case. Local targets use exact vault-root IDs without
`.md`; cross-vault targets use canonical stable `kb://` URIs. `kb graph`, `kb backlinks`, `kb relation list`, and `kb links` derive
inverse edges and bounded paths without injecting reciprocal or inferred facts into notes.
`kb percolate` proposes reusable concepts and missing connections with explicit
support; an agent reviews the cited prose before authoring anything.
support; an agent reviews the cited prose before authoring anything. In its V2
result, a missing relationship is an unordered endpoint pair with a required
predicate, never an executable directed assertion or an automatic
`related-to`. Common reviewed claims use `synthesizes`, `evidenced-by`,
`informed-by`, `supersedes`, or `contradicts`; other canonical custom predicates
remain valid when their meaning is supported.

Within a portfolio, a note can target a stable cross-vault identity such as
`kb://hraness/sleepyland/sound-wellness-expansion`. The target vault must be
Expand Down Expand Up @@ -540,26 +586,38 @@ diffs, and the explicit local job ledger are available from
The repository ships one reusable `kb` Agent Skill under `skills/kb/`. Its
intent router loads focused references only when a task needs them: querying
repository context and agent memory, capturing URLs or PDFs, writing durable
plans, promoting concepts and typed relationships, or refreshing and checking
a vault. The package smoke test keeps future tagged packages byte-identical to
plans, promoting concepts and typed relationships, refreshing and checking a
vault, or designing a setup through an interview and approved proposal. An
approved setup may scaffold a bounded companion skill for a distinct recurring
ritual. The package smoke test keeps future tagged packages byte-identical to
that source tree.

```sh
npx skills add hraness/kb#v0.18.1
npx skills add hraness/kb#v0.19.0
# or
bunx skills add hraness/kb#v0.18.1
bunx skills add hraness/kb#v0.19.0
```

The skill invokes the installed `kb` command without depending on a repository
checkout. Its runtime setup installs the pinned CLI only when the command is
missing, and it never initializes or mutates a vault as an installation side
effect. The repository's phase-orchestration skill remains available to local
repository agents but is marked internal, so public skill discovery omits it.
checkout. It routes setup and evolution before runtime preparation. For
execution workflows, runtime setup installs the pinned CLI only when the
command is missing, and it never initializes or mutates a vault as an
installation side effect. The repository's phase-orchestration skill remains
available to local repository agents but is marked internal, so public skill
discovery omits it.

See [Design](docs/design.md), [Portfolio federation](docs/portfolio.md), [Agent workflow](docs/agent-workflow.md), [PDF capture](docs/pdf.md), and [Contributing](CONTRIBUTING.md) for the durable contracts and development gate. hraness/kb is available under the [MIT License](LICENSE).

## Release notes

### Upgrade to v0.19.0

Version 0.19.0 adds interview-first setup and evolution guidance, a bounded
filesystem-only companion-skill scaffold contract, and Percolation Result V2.
V2 requires an explicit predicate and leaves relationship ownership and
direction to review. The release does not add lifecycle metadata, a resolver,
a lifecycle CLI, inferred edges, or automatic account and network actions.

### Upgrade to v0.18.1

Version 0.18.1 restructures the public README and hosted projection around one
Expand Down
4 changes: 2 additions & 2 deletions dist/authoring.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import {
normalizeRelationPredicate,
noteRevision,
removeNoteRelation
} from "./index-01jj6rbv.js";
} from "./index-gxr0fctd.js";
import"./index-3rm7cz6h.js";
import"./index-cxfrakt7.js";
import"./index-ekpwvbra.js";
export {
removeNoteRelation,
noteRevision,
Expand Down
6 changes: 3 additions & 3 deletions dist/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {
createSyntheticRankFusionFixture,
evaluateRanking,
evaluateRetrievalBenchmark
} from "./index-s2gw5aw9.js";
import"./index-cv6fh7z5.js";
} from "./index-qwgsmtsz.js";
import"./index-gm9t95d9.js";
import"./index-d13v9ckt.js";
import"./index-48pz4jpc.js";
import"./index-06c9ctr6.js";
import"./index-5vwpzb5a.js";
import"./index-cxfrakt7.js";
import"./index-ekpwvbra.js";
export {
evaluateRetrievalBenchmark,
evaluateRanking,
Expand Down
28 changes: 16 additions & 12 deletions dist/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
loadPortfolioRegistry,
openKnowledgePortfolio,
snapshotPortfolioRegistry
} from "./index-jsmvyyvf.js";
} from "./index-ey46z1zf.js";
import {
diffCaptureBundle
} from "./index-j4zgmzjr.js";
Expand All @@ -34,19 +34,19 @@ import {
MAX_PERCOLATION_NOTES,
MAX_SCOPED_PERCOLATION_MENTION_PAIRS,
percolateVault
} from "./index-dyqwejk5.js";
} from "./index-nd6nynv2.js";
import {
knowledgeBaseEvaluationRetrieverIds,
openKnowledgeBaseEvaluation
} from "./index-n5dd7r0v.js";
} from "./index-xw9ac71d.js";
import {
DEFAULT_SEARCH_RESULTS,
MAX_SEARCH_CANDIDATES,
MAX_SEARCH_NOTE_REFERENCE_BYTES,
MAX_SEARCH_RELATED_SEEDS,
MAX_SEARCH_RESULTS,
openKnowledgeBase
} from "./index-zzhgcwyt.js";
} from "./index-vxmf14m1.js";
import {
MAX_SEARCH_RULE_CONFIG_BYTES,
parseSearchRules
Expand All @@ -59,7 +59,7 @@ import {
refreshVault,
scanVault,
sha256EmbeddingModelFile
} from "./index-zxdy5pby.js";
} from "./index-5m2ydj5q.js";
import"./index-4j3tt0c3.js";
import"./index-1gwbassd.js";
import {
Expand All @@ -79,11 +79,11 @@ import {
addNoteRelation,
createNote,
removeNoteRelation
} from "./index-01jj6rbv.js";
} from "./index-gxr0fctd.js";
import"./index-3rm7cz6h.js";
import {
validateSearchQuery
} from "./index-cv6fh7z5.js";
} from "./index-gm9t95d9.js";
import {
navigateLinks
} from "./index-d13v9ckt.js";
Expand Down Expand Up @@ -111,7 +111,7 @@ import {
lookupNote,
parseVaultKey,
renderCatalog
} from "./index-cxfrakt7.js";
} from "./index-ekpwvbra.js";
import {
main
} from "./index-0kavxzqj.js";
Expand Down Expand Up @@ -2885,7 +2885,7 @@ function renderPercolation(result, note) {
if (candidate.kind === "missing-concept") {
lines.push(` concept #${safe(candidate.tag)} \u2192 ${safe(candidate.suggestedId)} (${candidate.support} supporting notes)` + (candidate.collidesWith === null ? "" : `; natural ID is occupied by ${safe(candidate.collidesWith)}`));
} else if (candidate.kind === "missing-relation") {
lines.push(` relation ${safe(candidate.source)} ${safe(candidate.suggestedPredicate)} ${safe(candidate.target)} (${candidate.support} shared signals)`);
lines.push(` relation pair {${safe(candidate.source)}, ${safe(candidate.target)}} (predicate required; ${candidate.support} shared signals)`);
} else if (candidate.kind === "unlinked-mention") {
lines.push(` mention ${safe(candidate.source)} \u2192 ${safe(candidate.target)} (${candidate.support})`);
} else {
Expand Down Expand Up @@ -2927,12 +2927,16 @@ async function runPercolate(command, output, dependencies) {
minSupport: command.minSupport,
limit: command.limit
});
output.stdout(command.json ? terminalSafeJson({
const jsonOutput = {
root: snapshot.root,
note: command.note ?? null,
minSupport: command.minSupport,
...result
}) : sanitizeTerminalText(renderPercolation(result, command.note)));
limit: command.limit,
schemaVersion: result.schemaVersion,
candidates: result.candidates,
truncated: result.truncated
};
output.stdout(command.json ? terminalSafeJson(jsonOutput) : sanitizeTerminalText(renderPercolation(result, command.note)));
return 0;
}
async function runList(command, output, dependencies) {
Expand Down
10 changes: 5 additions & 5 deletions dist/evaluation-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {
knowledgeBaseEvaluationRetrieverIds,
openKnowledgeBaseEvaluation,
verifyFrozenEvaluationSnapshot
} from "./index-n5dd7r0v.js";
import"./index-zzhgcwyt.js";
} from "./index-xw9ac71d.js";
import"./index-vxmf14m1.js";
import"./index-adx6khj5.js";
import {
indexSemanticVault,
recommendedEmbeddingModel,
recommendedEmbeddingModelSha256,
scanVault
} from "./index-zxdy5pby.js";
} from "./index-5m2ydj5q.js";
import"./index-4j3tt0c3.js";
import {
runGitCommand
Expand All @@ -22,12 +22,12 @@ import {
MAX_EVALUATION_EVIDENCE_BYTES,
MAX_EVALUATION_RESULTS_PER_QUERY
} from "./index-b88v3vtm.js";
import"./index-cv6fh7z5.js";
import"./index-gm9t95d9.js";
import"./index-d13v9ckt.js";
import"./index-48pz4jpc.js";
import"./index-06c9ctr6.js";
import"./index-5vwpzb5a.js";
import"./index-cxfrakt7.js";
import"./index-ekpwvbra.js";
import"./index-1xxnjn0d.js";

// src/evaluation-builder.ts
Expand Down
10 changes: 5 additions & 5 deletions dist/evaluation-kb.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import {
knowledgeBaseEvaluationRetrieverIds,
openKnowledgeBaseEvaluation,
verifyFrozenEvaluationSnapshot
} from "./index-n5dd7r0v.js";
import"./index-zzhgcwyt.js";
} from "./index-xw9ac71d.js";
import"./index-vxmf14m1.js";
import"./index-adx6khj5.js";
import"./index-zxdy5pby.js";
import"./index-5m2ydj5q.js";
import"./index-4j3tt0c3.js";
import"./index-1gwbassd.js";
import"./index-b88v3vtm.js";
import"./index-cv6fh7z5.js";
import"./index-gm9t95d9.js";
import"./index-d13v9ckt.js";
import"./index-48pz4jpc.js";
import"./index-06c9ctr6.js";
import"./index-5vwpzb5a.js";
import"./index-cxfrakt7.js";
import"./index-ekpwvbra.js";
import"./index-1xxnjn0d.js";
export {
verifyFrozenEvaluationSnapshot,
Expand Down
Loading