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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ npm install @klickd/core
| LlamaIndex (system prompt + vector index + session resume) | [`docs/integrations/llamaindex.md`](docs/integrations/llamaindex.md) |
| GitHub Copilot / M365 Copilot (hybrid pattern) | [`docs/integrations/copilot.md`](docs/integrations/copilot.md) |
| Any provider (generic pattern) | [`docs/integrations/generic.md`](docs/integrations/generic.md) |
| 42 x.klickd v4.1 skill packs (load / list / hash-verify) | [`docs/integrations/skill-loader-protocol.md`](docs/integrations/skill-loader-protocol.md) |

> **Developer path for the 42 v4.1 skill packs:** list, load, and **hash-verify** the 8 Lite + 34 Pro packs (`artifact_loaded` + `sha256_matches_manifest`) via `@klickd/core` (Node), `klickd` (PyPI), or the no-install `scripts/verify_xklickd_skill_packs.py` CLI. They are real JSON artifacts, **not** native skills in any assistant — see [`docs/integrations/skill-loader-protocol.md`](docs/integrations/skill-loader-protocol.md).

> **Experimental POC:** [`integrations/hermes/`](integrations/hermes/README.md) — Hermes Agent as workflow runner, `.klickd` as portable state layer. Local dry-run only; not a production integration.

Expand Down
33 changes: 33 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,39 @@ That's a real x.klickd skill loaded as model context. You're done with the smoke

---

## 2b. Load the 42 x.klickd v4.1 skill packs (optional)

Beyond the four starter skills, the repo ships **42 x.klickd v4.1 candidate
skill packs** (8 Lite + 34 Pro). The SDK can list them and load any one with a
SHA-256 check against the published manifest:

**Python**

```python
import klickd

skill = klickd.load_xklickd_skill_pack("llm-agent-engineering")
assert skill["artifact_loaded"] and skill["sha256_matches_manifest"]
print(skill["tier"], skill["pack"]) # -> pro x.klickd/llm_agent_engineering
```

**TypeScript / Node**

```ts
import { loadXKlickdSkillPack } from "@klickd/core";

const skill = loadXKlickdSkillPack("x.klickd/llm_agent_engineering");
if (!skill.artifact_loaded || !skill.sha256_matches_manifest) throw new Error("verify failed");
console.log(skill.tier, skill.pack); // -> pro x.klickd/llm_agent_engineering
```

A pack is only "used" once `artifact_loaded` **and** `sha256_matches_manifest`
are both true — these are JSON artifacts, not native skills in any assistant.
Full details, the no-install CLI, and the truth boundary:
[`integrations/skill-loader-protocol.md`](integrations/skill-loader-protocol.md).

---

## 3. Plug it into a model (~1 min)

A starter skill is built to drop into a **system prompt**. Pick the provider you already have a key for — each guide is a copy-paste minimal example:
Expand Down
1 change: 1 addition & 0 deletions docs/integrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Each guide here specialises the same core pattern: **parse → validate → stri
| [universal-bridge.md](universal-bridge.md) | design + reference | runtime-injection layer | **Bridge-mediated, not native** | One injection layer fronting any compatible surface |
| [generic.md](generic.md) | any | `system` (recommended) | Pattern (you implement it) | Any provider or agent framework not listed above |
| [starter-skills.md](starter-skills.md) | — | — | — (payload pack) | Ready-made plain starter payloads to load and inject |
| [skill-loader-protocol.md](skill-loader-protocol.md) | Python + Node + CLI | loader / hash-verify | — (artifact, not native) | Loading, listing, and hash-verifying the 42 x.klickd v4.1 skill packs (`artifact_loaded`) |

**Reading the Compatibility column.** *Direct* means the provider's own API accepts a system prompt and these guides inject `.klickd` content into it — no third party decrypts or auto-loads the file. *Complementary / Bridge-mediated* means there is no native `.klickd` support on that surface; compatibility is provided by a loader or injection layer you run. No third-party AI service decrypts or auto-loads a `.klickd` file today.

Expand Down
163 changes: 163 additions & 0 deletions docs/integrations/skill-loader-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# x.klickd skill-loader protocol — using the 42 v4.1 skill packs safely

This page explains how to load, list, and **hash-verify** the 42 public
x.klickd v4.1 candidate skill packs, and where the truth boundary sits between
"a `.klickd` file exists" and "a skill is being used".

> **Truth boundary.** The 42 packs under
> [`examples/v4.1/x-klickd-skills/`](../../examples/v4.1/x-klickd-skills/) are
> **real JSON artifacts** — byte-identical, hash-pinned, downloadable. They are
> **not** automatically native skills in any AI assistant. No third-party AI
> service decrypts, auto-loads, or natively adopts a `.klickd` file today.
> Runtime use requires a loader or host integration that you run.
>
> A pack is only **"used"** once one of these is true:
> 1. its bytes have been **loaded and SHA-256-verified** against the manifest
> (`artifact_loaded = true` **and** `sha256_matches_manifest = true`), **or**
> 2. a host runtime has otherwise **explicitly integrated** it (e.g. injected
> its content into a model's `system` prompt, per
> [`generic.md`](generic.md)).
>
> These packs are **NON-NORMATIVE** and **NOT a v4.1 GA release**. They carry no
> stability, compatibility, GDPR / EU AI Act, or benchmark-superiority claims.
> See the [claim boundary](../../README.md) in the main README.

---

## What the packs are

| | |
|---|---|
| Count | **42** total — **8 Lite**, **34 Pro** |
| Location | [`examples/v4.1/x-klickd-skills/lite/*.klickd`](../../examples/v4.1/x-klickd-skills/lite/) and [`/pro/*.klickd`](../../examples/v4.1/x-klickd-skills/pro/) |
| Index | [`examples/v4.1/x-klickd-skills/manifest.json`](../../examples/v4.1/x-klickd-skills/manifest.json) — 42 entries with `tier`, `pack`, `file`, `bytes`, `sha256_file` |
| Envelope | v4.0 (`klickd_version: "4.0"`), unencrypted JSON |
| Status | `candidate_mapped`, `non_normative: true`, `claims_v41_ga: false` |

Each pack is a `carrier_competency_pack`: it declares competency mappings
(ESCO / SFIA / O*NET / WEF), verification gates, an evidence policy, and
human-authority fields. It does **not** carry PII, secrets, or host-side prompt
strategy.

---

## `artifact_loaded` — the contract

`loadXKlickdSkillPack()` (Node) and `load_xklickd_skill_pack()` (Python) return
a summary object. Two fields define the safety contract:

- **`artifact_loaded: true`** — the bytes were read and hashed **in-process**.
This asserts the artifact reached your code; it does **not** assert any
assistant has adopted it.
- **`sha256_matches_manifest`** — the computed SHA-256 equals the
`sha256_file` recorded in the manifest. **Treat the pack as usable only when
this is `true`.** A `false` here means the bytes you loaded are not the
published artifact — stop and re-fetch.

Do not claim a skill is "used" or "active" before both are confirmed.

The summary also surfaces: `id`, `tier`, `file`, `pack`, `pack_version`,
`bytes`, `sha256`, `klickd_version`, `payload_schema_version`, `domain`,
`profile_kind`, `competency_ids`, `gates`, `evidence_policy`,
`human_authority`, and `human_veto` (when present).

---

## Node / TypeScript (`@klickd/core` ≥ 4.1)

The 42 packs ship as package data — no network fetch required.

```ts
import {
listXKlickdSkillPacks,
loadXKlickdSkillPack,
getXKlickdSkillPackBytes,
} from "@klickd/core";

// 1. List all 42 (manifest entries: tier, pack, file, bytes, sha256_file).
const packs = listXKlickdSkillPacks();
console.log(packs.length); // -> 42

// 2. Load + hash-verify one. Accepts a file name, full pack id, or bare id.
const skill = loadXKlickdSkillPack("x.klickd/llm_agent_engineering");
if (!skill.artifact_loaded || !skill.sha256_matches_manifest) {
throw new Error("pack failed hash verification — do not use it");
}
console.log(skill.tier, skill.competency_ids); // -> "pro" [ 'esco:S5.6.1', ... ]

// 3. Raw bytes (e.g. to inject into a system prompt per generic.md).
const bytes = getXKlickdSkillPackBytes("work-assistant.klickd");
```

---

## Python (`klickd` ≥ 4.1)

```python
import klickd

# 1. List all 42.
packs = klickd.list_xklickd_skill_packs()
assert len(packs) == 42

# 2. Load + hash-verify one.
skill = klickd.load_xklickd_skill_pack("llm-agent-engineering")
assert skill["artifact_loaded"] and skill["sha256_matches_manifest"]
print(skill["tier"], skill["competency_ids"]) # -> pro ['esco:S5.6.1', ...]

# 3. Raw bytes.
data = klickd.get_xklickd_skill_pack_bytes("x.klickd/work_assistant")
```

---

## CLI / no-install path

If you do not want the SDK, the repo ships a dependency-free verifier + CLI that
reads the public artifacts directly:

```bash
python scripts/verify_xklickd_skill_packs.py verify # 42 / 8 Lite / 34 Pro, JSON + fields + hashes
python scripts/verify_xklickd_skill_packs.py list # list all 42 packs
python scripts/verify_xklickd_skill_packs.py load work-assistant # load + hash-verify one (JSON summary)
```

`verify` checks: 42 total (8 Lite + 34 Pro), every `.klickd` parses as JSON,
required fields present (`klickd_version`, `payload_schema_version`, `domain`,
`profile_kind`, `x_klickd_pack`, `x_klickd_pack.pack`), and SHA-256 matches the
manifest. Exit code `0` = all pass.

---

## Identifier resolution

All three loaders accept any of:

- **file name** — `work-assistant.klickd`
- **full pack id** — `x.klickd/work_assistant`
- **bare id** — `work-assistant` or `work_assistant` (hyphen/underscore agnostic)

---

## Using a verified pack with a model

Loading and verifying gives you a trustworthy artifact. To actually influence a
model you still inject its content yourself — there is no native adoption. Use
the canonical [parse → validate → strip `_`-fields → build system prompt →
inject](generic.md) pattern. `verification_gates` in a pack are **instructions
surfaced to the model**; enforce the real gate semantics in your host
application, not inside the LLM.

---

## Package-coverage status

| Surface | Status |
|---|---|
| `@klickd/core` (npm ≥ 4.1) | Bundled — `listXKlickdSkillPacks`, `getXKlickdSkillPackBytes`, `loadXKlickdSkillPack`, `getXKlickdSkillsManifest`, `getXKlickdSkillsDir` |
| `klickd` (PyPI ≥ 4.1) | Bundled — `list_xklickd_skill_packs`, `get_xklickd_skill_pack_bytes`, `load_xklickd_skill_pack`, `get_xklickd_skills_manifest`, `get_xklickd_skills_dir` |
| Repo CLI | `scripts/verify_xklickd_skill_packs.py` (`verify` / `list` / `load`) |

The repository tree under `examples/v4.1/x-klickd-skills/` (per-tier manifests
plus this aggregated index) remains authoritative; the bundled package copies
are byte-identical mirrors verified by the package test suites.
28 changes: 28 additions & 0 deletions packages/@klickd/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,34 @@ const manifest = getStarterSkillsManifest();
const dir = getStarterSkillsDir(); // absolute path to bundled starter-skills/
```

### x.klickd v4.1 skill packs (42 candidate packs — non-normative)

The 42 x.klickd v4.1 candidate skill packs (8 Lite + 34 Pro) ship inside the
npm tarball under `x-klickd-skills/` alongside the aggregated download index
`manifest.json`. They are **NON-NORMATIVE** and **NOT a v4.1 GA release**, and
they are JSON artifacts — **not** native skills in any assistant. A pack is only
"used" once `artifact_loaded` **and** `sha256_matches_manifest` are both true.

```typescript
import {
listXKlickdSkillPacks,
loadXKlickdSkillPack,
getXKlickdSkillPackBytes,
getXKlickdSkillsManifest,
} from '@klickd/core';

listXKlickdSkillPacks().length; // → 42

const skill = loadXKlickdSkillPack('x.klickd/llm_agent_engineering');
// skill.artifact_loaded === true, skill.sha256_matches_manifest === true
// skill.tier, skill.competency_ids, skill.gates, skill.evidence_policy, ...

const bytes = getXKlickdSkillPackBytes('work-assistant.klickd'); // by file, pack id, or bare id
```

Full protocol and truth boundary:
[`docs/integrations/skill-loader-protocol.md`](https://github.com/Davincc77/klickdskill/blob/main/docs/integrations/skill-loader-protocol.md).

---

## Cryptographic specification (v3.0)
Expand Down
1 change: 1 addition & 0 deletions packages/@klickd/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"files": [
"dist",
"starter-skills",
"x-klickd-skills",
"README.md",
"LICENSE"
],
Expand Down
12 changes: 12 additions & 0 deletions packages/@klickd/core/scripts/verify-tarball.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ if (!(bytes instanceof Uint8Array) || bytes.byteLength <= 0) {
throw new Error('CJS: empty user.klickd');
}
if (k.listBundledSchemas().length !== 4) throw new Error('CJS: expected 4 schemas');
const xm = k.getXKlickdSkillsManifest();
if (xm.total_count !== 42 || xm.packs.length !== 42) throw new Error('CJS: expected 42 x.klickd packs');
const xs = k.loadXKlickdSkillPack('work-assistant');
if (xs.artifact_loaded !== true || xs.sha256_matches_manifest !== true) {
throw new Error('CJS: work-assistant did not load/verify');
}
console.log('CJS smoke OK');
`;

Expand All @@ -82,6 +88,12 @@ if (!(bytes instanceof Uint8Array) || bytes.byteLength <= 0) {
throw new Error('ESM: empty coding.klickd');
}
if (k.listBundledSchemas().length !== 4) throw new Error('ESM: expected 4 schemas');
const xm = k.getXKlickdSkillsManifest();
if (xm.total_count !== 42 || xm.packs.length !== 42) throw new Error('ESM: expected 42 x.klickd packs');
const xs = k.loadXKlickdSkillPack('x.klickd/llm_agent_engineering');
if (xs.artifact_loaded !== true || xs.sha256_matches_manifest !== true) {
throw new Error('ESM: llm_agent_engineering did not load/verify');
}
console.log('ESM smoke OK');
`;

Expand Down
69 changes: 69 additions & 0 deletions packages/@klickd/core/src/__tests__/x-klickd-skills.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// @klickd/core — x.klickd v4.1 skill-pack inclusion test
// SPDX-License-Identifier: CC0-1.0

import { createHash } from 'node:crypto';
import {
listXKlickdSkillPacks,
getXKlickdSkillPackBytes,
getXKlickdSkillsManifest,
getXKlickdSkillsDir,
loadXKlickdSkillPack,
} from '../index.js';

describe('bundled x.klickd v4.1 skill packs', () => {
it('exposes a 42-pack manifest (8 Lite + 34 Pro)', () => {
const manifest = getXKlickdSkillsManifest();
expect(manifest.non_normative).toBe(true);
expect(manifest.claims_v41_ga).toBe(false);
expect(manifest.total_count).toBe(42);
expect(manifest.packs.length).toBe(42);
const lite = manifest.packs.filter((p) => p.tier === 'lite');
const pro = manifest.packs.filter((p) => p.tier === 'pro');
expect(lite.length).toBe(8);
expect(pro.length).toBe(34);
});

it('every bundled pack hash matches the manifest', () => {
for (const pack of listXKlickdSkillPacks()) {
const bytes = getXKlickdSkillPackBytes(pack.file);
const hash = createHash('sha256').update(bytes).digest('hex');
expect(hash).toBe(pack.sha256_file);
expect(bytes.byteLength).toBe(pack.bytes);
}
});

it('resolves packs by file name, full pack id, and bare id', () => {
const byFile = loadXKlickdSkillPack('work-assistant.klickd');
const byPack = loadXKlickdSkillPack('x.klickd/work_assistant');
const byBare = loadXKlickdSkillPack('work-assistant');
expect(byFile.sha256).toBe(byPack.sha256);
expect(byPack.sha256).toBe(byBare.sha256);
});

it('loadXKlickdSkillPack reports artifact_loaded and a verified hash', () => {
const summary = loadXKlickdSkillPack('llm-agent-engineering');
expect(summary.artifact_loaded).toBe(true);
expect(summary.sha256_matches_manifest).toBe(true);
expect(summary.tier).toBe('pro');
expect(summary.pack).toBe('x.klickd/llm_agent_engineering');
expect(summary.klickd_version).toBe('4.0');
expect(summary.domain).toBe('software_engineering');
expect(summary.profile_kind).toBe('carrier_competency_pack');
expect(summary.competency_ids.length).toBeGreaterThan(0);
expect(summary.gates.length).toBeGreaterThan(0);
expect(summary.evidence_policy).not.toBeNull();
expect(summary.human_authority).not.toBeNull();
});

it('rejects unknown packs and path traversal', () => {
expect(() => getXKlickdSkillPackBytes('../package.json')).toThrow();
expect(() => getXKlickdSkillPackBytes('does-not-exist')).toThrow();
expect(() => loadXKlickdSkillPack('nope')).toThrow();
});

it('returns a directory path that exists', () => {
const dir = getXKlickdSkillsDir();
expect(typeof dir).toBe('string');
expect(dir.length).toBeGreaterThan(0);
});
});
13 changes: 13 additions & 0 deletions packages/@klickd/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,16 @@ export type {
StarterSkillEntry,
StarterSkillManifest,
} from './starter-skills.js';
export {
getXKlickdSkillsDir,
getXKlickdSkillsManifest,
listXKlickdSkillPacks,
getXKlickdSkillPackBytes,
loadXKlickdSkillPack,
} from './x-klickd-skills.js';
export type {
XKlickdSkillPackEntry,
XKlickdSkillManifest,
XKlickdSkillGateSummary,
XKlickdSkillPackSummary,
} from './x-klickd-skills.js';
Loading
Loading