Catalog npm
PACKAGE EXPLORERView in registry

1000skills

npm

Typed authoring SDK and deterministic runtime for repository agent harnesses

Versions collected17
Direct dependencies20From release 0.11.0
Last observed20 Oct, 17:59 UTC

README

Current package documentation

1000skills compiles typed harness policy into deterministic harness-v6 and eval-v5 JSON for routing, checks, and explicit traces

Repository policy that agents can execute

1000skills is a typed authoring SDK and deterministic JSON runtime for repository agent harnesses.

Authors describe routes, required context, file-class checks, overlays, and evaluations in TypeScript or a language adapter. Routing commands consume generated harness-v6 and eval-v5 JSON without executing authoring code.

It ships as one ESM-only npm package for Node 22.12 and later. Non-TypeScript repositories can author the harness without Node.js; see Language-neutral authoring below.

Install

npm install --save-exact 1000skills
npm exec -- 1000skills harness init
npm exec -- 1000skills harness sync

The equivalent pnpm commands are pnpm add --save-exact 1000skills, pnpm exec 1000skills harness init, and pnpm exec 1000skills harness sync. With Yarn, use yarn add --exact 1000skills, yarn 1000skills harness init, and yarn 1000skills harness sync.

The package is ESM-only ("type": "module"): entry points are import-only with no CommonJS build. require("1000skills/harness/client") in a CommonJS project fails with ERR_REQUIRE_ESM — use a dynamic import() or an ESM module.

init writes starter source (harness.config.ts and .agents/harness/*.ts); it does not write the generated artifact pair and never overwrites starter files. When package.json exists, init wires missing harness package scripts from the public command catalog, including route, sync, diagnose, trace, complete check, and changed-file checks. Existing script values are preserved. After a behavior comparison, init --replace-legacy-scripts can replace recognized legacy values. sync compiles the typed source into .agents/harness.json and .agents/harness.evals.json, which route, check, and the other read-only commands read. Run it again whenever the typed source changes.

New projects keep generated artifacts and traces local. Existing projects keep committed mode until an explicit migration. See team adoption for staged adoption, runtime pins, prepared CI baselines, rollback, and host limits.

New to the vocabulary (harness, authoring IR, context bundle, file class, eval, fingerprints)? references/glossary.md has short definitions.

Want a 5-minute walkthrough from install to a routed prompt? See references/quickstart-ts.md.

harness check or diagnose refusing the .agents pair? references/harness-artifact-recovery.md has the safe recovery path.

CHANGELOG.md holds release history. All four files ship with the package.

Language-neutral authoring

The native 1000skills core compiles a language-neutral authoring IR, so a repository needs no Node.js to author or run a harness. The TypeScript package is one authoring adapter among several.

Adapters emit authoring IR v2 to stdout; the native core validates and compiles it. Adapters only emit IR — they must not compute fingerprints, registries, or adapter files.

AdapterPackageEmit command
TypeScriptpackages/1000skills1000skills harness emit
Pythonpackages/1000skills-pythonpython -m thousand_skills_harness emit
Javapackages/1000skills-javajava -cp <classpath> dev.thousandskills.harness.EmitCli emit --config-class <FQN>
Kotlinpackages/1000skills-kotlinjava -cp <classpath> dev.thousandskills.harness.EmitCliKt emit --config-class <FQN>
Swiftpackages/1000skills-swiftswift run harness-emit emit --config <name>

Pipe an adapter into the native compiler:

python -m thousand_skills_harness emit | 1000skills harness sync --source-stdin

This npm package is a complete runtime on its own: every read and write command works without the native binary. The native 1000skills core (built from source at crates/1000skills-core) is an optional accelerator for the --json commands; signed distribution is a Stage 5 goal, not shipped yet. Until then, run 1000skills harness <command> from this package, or set 1000SKILLS_FORCE_TS=1 to force the TypeScript handler (see Native delegation and the TypeScript fallback).

See the source-repo quickstart for a non-TypeScript first run, and the source-repo migration guide to move an existing TypeScript repository from harness.config.ts to the native core. These resolve only in the source repository; the npm package does not bundle docs/, so use the shipped TS quickstart instead.

Run A Bounded Goal

The package also installs goal-loop, a bounded foreground supervisor for agent work. A strict JSON manifest locks the objective, workspace, adapter, acceptance commands, and resource limits before the first attempt.

goal-loop run --spec ./goal.json
goal-loop status <goal-id>
goal-loop doctor --json
goal-loop abandon <goal-id> --reason "Superseded by a new goal"
goal-loop clean --ttl-hours 168 --max-bytes 1073741824 --json

Agent output is only a candidate. goal-loop records append-only lifecycle events and reports succeeded only after locked acceptance commands pass.

Concurrent runs use a durable per-state-root capacity policy and FIFO queue. Default capacity is one; one workspace stays exclusive. doctor --json reports safe recovery details. abandon accepts only queued or backoff goals; clean preserves active, locked, corrupt, unknown, and non-terminal evidence.

Foreground mode owns and terminates the complete process tree on timeout or interruption.

Background, resume, external-stop, and human-answer controls stay gated on verified private-worker ownership, restart reconciliation, panic-stop, and at-most-one-process tests.

Write the goal spec as JSON and validate it against 1000skills/schema/goal-loop-manifest.json. Parse the goal-loop output envelope with parseGoalLoopEnvelope from 1000skills/harness/client, the same entry point as every other CLI output parser.

The contract

harness.config.ts + .agents/harness/*.ts
              │
       check · snapshot · compile twice
              ▼
 .agents/harness.json + .agents/harness.evals.json
              │
 route · check · changed · inspect · diagnose · explicit trace

Compilation validates the closed source graph, strict types, ownership, membership, discovery, filesystem references, context budgets, collisions, and eval expectations. Matching fingerprints bind the generated pair.

ContractCurrent value
Harness schemav6
Eval schemav5
JSON output envelopev6
Trace protocolv2

package.json is the source of truth for the package version.

Keep the control plane small

harness.config.ts composes repository policy; it is not a second architecture document or a source-file inventory.

  • Routes are mutually exclusive primary work surfaces with meaningfully different context.
  • Overlays add concerns that can coexist with a primary route, such as testing, review, security, motion, or routing audit.
  • File classes map changed paths to verification. Start with one baseline and add only source-backed exceptions.
  • Guides and skills own durable knowledge. The config points to them instead of repeating them.

Review the shape when a harness grows beyond roughly a dozen primary routes, repeats effective route context, uses dense trigger lists, or defines routes with no context delta. harness check and harness diagnose report these as complexity warnings.

File-class counts have no complexity threshold because repository verification taxonomies vary legitimately.

Author a harness

Keep the root entrypoint small and put human-owned authoring modules under .agents/harness/:

// harness.config.ts
import { defineHarness } from "1000skills/harness";
import { author } from "./.agents/harness/author.ts";

export default defineHarness(author);
// .agents/harness/author.ts
import type {
  HarnessAuthoringContext,
  HarnessAuthoringResult,
  HarnessOwner,
} from "1000skills/harness";

const ids = {
  bugFix: "bug-fix",
  fallback: "fallback",
} as const satisfies Record<string, string>;

export function author<Owner extends HarnessOwner>(
  h: HarnessAuthoringContext<Owner>,
): HarnessAuthoringResult<Owner> {
  const policy = h.context.file("AGENTS.md", "Repository policy");
  const testing = h.reference.guide({
    id: "testing",
    path: ".agents/guides/testing.md",
  });
  const fixBug = h.reference.skill({
    id: "fix-bug",
    path: ".agents/skills/fix-bug/SKILL.md",
  });
  const typecheck = h.command.packageScript({ id: "typecheck", script: "typecheck" });
  const bugFix = h.route.define({
    id: ids.bugFix,
    priority: 80,
    skill: fixBug,
    triggers: {
      keywords: ["bug", "failing", "regression"],
      intents: ["fix", "repair"],
      paths: ["src/**"],
    },
    mandatory: [
      h.context.include(fixBug, "Use the repair workflow"),
      h.context.include(testing, "Add regression coverage"),
    ],
  });
  const fallback = h.route.fallback({ id: ids.fallback });
  const source = h.fileClass.define({
    id: "typescript",
    patterns: ["src/**/*.ts", "src/**/*.tsx"],
    recommendations: h.command.recommendations({
      command: typecheck,
      reason: "TypeScript changes require type checking",
    }),
  });
  const bugEvals = h.eval.cases.route({
    route: bugFix,
    skill: fixBug,
    mandatory: [policy, fixBug, testing],
    cases: [
      {
        id: "bug-fix-render",
        prompt: "Fix the failing render test in src/Button.test.tsx",
      },
    ],
  });
  const fallbackEval = h.eval.case.route({
    id: "fallback-general",
    prompt: "Explain the repository",
    expect: {
      route: fallback,
      mandatory: [policy],
    },
  });

  return {
    core: { mandatory: [policy] },
    routes: [bugFix, fallback],
    fallback,
    fileClasses: [source],
    evals: [...bugEvals, fallbackEval],
  };
}

The public authoring surface centers on defineHarness, opaque HarnessDefinition, owner-generic HarnessAuthoringContext, and HarnessAuthoringResult.

HarnessHandle supports owner-preserving generic utilities; named handle, input, and scalar/batch case contracts remain public so declaration consumers never depend on hidden types. Typed handles catch kind mistakes in TypeScript; compilation catches ownership, membership, discovery, filesystem, section, link, collision, budget, and eval errors. Normalized runtime models remain private.

Explicit reference inputs may declare authority: { files: ["path", ...] }; this applies to h.reference.guide, h.reference.skill, h.reference.helper, and h.reference.adapter. Authority files are securely resolved repository-relative inputs whose fingerprints are stored with that reference. They are not loaded as routed context, and no diagnostic judges either file's prose.

Changing authority bytes, registering or removing authority tracking, or changing its source set requires semantic review. Normal write-mode sync refuses to replace recorded fingerprints until the reviewer runs 1000skills harness sync --accept-authority. Unchanged authority continues through ordinary sync; initial authority registration also uses the explicit acceptance path.

The compact authoring families are h.reference.guides, h.context.namedSections, h.command.packageScripts, h.command.recommendations, h.sourceSet.define, h.sourceSet.harnessInputs, h.eval.cases.routeMap, and h.eval.cases.changedMap. recommend accepts one { command, reason } object or a readonly array of those objects and always returns a fresh mutable handle array, including for empty input.

h.sourceSet.define({ id, patterns }) returns an owner-branded reusable static pattern handle. Route and overlay triggers.paths, fallback-only intentionalPaths, and file-class patterns accept it beside literal strings, flatten it at authoring time in first-occurrence order, and emit only literal patterns; source-set identity never enters generated artifacts. Primary route inputs reject intentionalPaths; every generated fallback route contains its canonical string array, including []. Static sets require a safe unique ID and at least one nonblank string pattern. They cannot contain another source-set handle, and a private scoped set must be exported and imported before another scope can use it.

h.route.overlayGroup({ id, mandatory?, variants }) keeps one conceptual concern within the overlay complexity budget while giving each source-backed trigger family its own mandatory context. Variant record keys become stable flat overlay IDs in <group>.<variant> form; the returned variants map and overlays array contain ordinary owner-branded overlay handles. Group-common context is prepended to each variant, matching variants compose additively, and runtime output, eval expectations, coverage, inspect, and trace use the flat IDs without a second selection mechanism.

// The mandatory and triggers handles below (externalFetchSecurity,
// mediaProxySources, mediaProxyApi, pinterestSources, pinterestContract,
// providerSecrets) are context/source-set handles defined earlier in the
// same author callback; only the overlayGroup call is shown here.
const externalFetch = h.route.overlayGroup({
  id: "external-fetch",
  mandatory: [externalFetchSecurity],
  variants: {
    "media-proxy": {
      triggers: { paths: [mediaProxySources] },
      mandatory: [mediaProxyApi],
    },
    pinterest: {
      triggers: { paths: [pinterestSources] },
      mandatory: [pinterestContract, providerSecrets],
    },
  },
});

return {
  overlays: [...externalFetch.overlays],
  // ...
};

Harness-v6 stores optional strict group identity on each flat variant so complexity checks count conceptual groups while retaining per-variant coverage and trace recall. Ordinary overlays remain unchanged. One-variant groups, groups above six variants, more than 32 flat overlays, duplicate effective context, and variants with no context delta fail or warn through the normal complexity gate.

const applicationSources = h.sourceSet.define({
  id: "application-sources",
  patterns: ["app/**", "src/**", "lib/**"],
});

const implementation = h.route.define({
  id: "implementation",
  triggers: { paths: [applicationSources, "packages/**"] },
});

const source = h.fileClass.define({
  id: "source",
  patterns: [applicationSources, "tests/**"],
  recommendations: [],
});

const fallback = h.route.fallback({
  id: "fallback",
  intentionalPaths: [applicationSources, "README.md"],
});

h.sourceSet.harnessInputs(options?) is a separate dynamic handle accepted only beside literal file-class patterns. The compiler expands it to harness-v6 string patterns. Its closure comes from the prepared config graph, referenced knowledge, explicit required files, the fixed artifact pair, configured generated surfaces, and selected human-owned root adapters. Runtime traces are excluded unless runtime-evidence is explicitly included. Referenced knowledge includes each reference file and its declared authority files. Authority bytes also participate in the discovery fingerprint even when the routed reference is unchanged. include selects facets and exclude removes facets, so references can remain under a different file-class gate.

// checkHarness is a command handle (e.g. h.command.packageScript) defined
// earlier in the same author callback; only the file-class call is shown here.
const harnessInputs = h.fileClass.define({
  id: "harness-inputs",
  patterns: [h.sourceSet.harnessInputs({ exclude: ["references"] }), "docs/harness-policy.md"],
  recommendations: h.command.recommendations({
    command: checkHarness,
    reason: "Harness inputs must leave generated surfaces fresh",
  }),
});

Split modules can contribute definitions without making the root re-list every handle. h.scope(id, scoped => ({ exports, routes, overlays, evals, fileClasses, subagents })) requires explicit exports and contributions. Grouped variants contribute and export their ordinary overlay handles. h.compose({ core, fallback, scopes, ... }) flattens them. A dependent scope calls scoped.imports(otherScope.exports) before using public handles. Omitted scopes, private imports, uncontributed definitions or exports, duplicate contributions, and foreign owners fail closed. Existing configs can keep returning HarnessAuthoringResult directly.

const routing = h.scope("routing", (scoped) => {
  const fallback = scoped.route.fallback({ id: "fallback" });
  return { exports: { fallback }, routes: [fallback] };
});

const evals = h.scope("evals", (scoped) => {
  const publicRouting = scoped.imports(routing.exports);
  const fallback = scoped.eval.case.route({
    id: "fallback-general",
    prompt: "Explain the repository",
    expect: { route: publicRouting.fallback },
  });
  return { exports: {}, evals: [fallback] };
});

return h.compose({
  core: { mandatory: [] },
  fallback: routing.exports.fallback,
  scopes: [routing, evals],
});

Registry keys are local aliases, eval-map keys are explicit eval IDs, and reasons and artifact IDs remain explicit. Scalar and batch declarations with the same decoded meaning may have different config fingerprints because fingerprints include the exact checked source graph.

Route evals make context promotion intent explicit. When a selected overlay supplies route-conditional context as mandatory, authoring fails with eval.promotions_required unless expect.promotions names the promoted context in the exact composed order. A supplied list that differs from the composed result fails with eval.promotions_mismatch; with no promotions, omission or an empty list is valid. expect.promotions: ["auto"] accepts the composer-derived list instead of hand-mirroring it; the compiler resolves the sentinel to concrete ids at emit time, and drift checking recomputes the composed list on every sync.

const testing = h.context.file("docs/testing.md", "Use test policy");
const implementation = h.route.define({
  id: "implementation",
  triggers: { intents: ["implement"] },
  conditional: [testing],
});
const verify = h.route.overlay({
  id: "verify",
  triggers: { keywords: ["verify"] },
  mandatory: [testing],
});
const implementationEval = h.eval.case.route({
  id: "implementation-verify",
  prompt: "Implement and verify the change",
  expect: { route: implementation, overlays: [verify], promotions: [testing] },
});

The authoring API and runtime client deliberately use separate entry points. 1000skills/harness stays dependency-light and hermetic because it is the only module a harness config may import.

1000skills/harness/client is for programs that consume versioned CLI envelopes, so it includes runtime schema validation. The boundary keeps authoring configs from loading the runtime validator while both interfaces evolve within the same package.

The config graph is closed and bounded to 8 import levels, 32 files including the root, and 512 KiB of source. Static imports may target only 1000skills/harness or explicit relative .ts files whose logical and real paths remain under .agents/harness/.

Aliases, other bare packages, JavaScript, JSON, extensionless imports, dynamic imports, cycles, duplicate realpaths, symlink escapes, and oversized graphs are rejected.

Sync typechecks every source module before execution with SDK-pinned TypeScript 6.0.3 and hardcoded strict options. It does not load repository tsconfig files, plugins, path aliases, ambient project declarations, or suppression directives.

as const and satisfies are supported; explicit any, unsafe assertions, non-null assertions, and TypeScript suppression/reference directives are rejected.

The parent process securely reads, validates, typechecks, and transpiles one bounded source snapshot. Two fresh sanitized VM children receive those exact immutable bytes over stdin; they never reread target config files.

harness.config.ts and the exact imported .agents/harness/*.ts graph are human-owned source. .agents/harness.json, .agents/harness.evals.json, and configured generated adapter surfaces are generated. Root adapter entrypoints such as AGENTS.md and CLAUDE.md remain human-owned. Source-set closure diagnostics retain this ownership distinction even though artifacts contain only literal paths.

Use h.eval.cases.route when several prompts share one route expectation and h.eval.cases.changed when several paths share one command set. Route array/map cases inherit shared overlays and promotions; an explicit per-case array, including [], deterministically replaces the shared value. h.command.packageScript verifies that a declared script exists in the selected manifest while still emitting fixed argv. h.command.define, h.command.packageScript, and package-script registry entries accept same-owner command handles in subsumes. Direct targets are deduplicated deterministically and emitted as artifact-only command IDs. A selected command suppresses a direct or transitive target only when that target is also selected; the relation never expands a recommendation set.

Commands

1000skills harness init
1000skills harness sync
1000skills harness sync --check
1000skills harness sync --diff
1000skills harness sync --repair
1000skills harness sync --accept-authority
1000skills harness emit
1000skills harness emit --check
1000skills harness migrate
1000skills harness check
1000skills harness check --baseline origin/main
1000skills harness check --exhaustive
1000skills harness route "Fix the failing selector" --explain
1000skills harness changed -- src/button.ts
1000skills harness changed --require-classification -- src/button.ts
1000skills harness changed --from origin/main
1000skills harness changed --from origin/main --to HEAD
1000skills harness inspect --prompt "Fix the failing selector"
1000skills harness inspect --file src/button.ts
1000skills harness inspect --id bug-fix
1000skills harness inspect --target claude
1000skills harness suggest-evals
1000skills harness trace start --session repair-1 --route bug-fix
1000skills harness trace record --session repair-1 --path AGENTS.md
1000skills harness trace finish --session repair-1
1000skills harness trace clean --ttl-hours 720 --max-bytes 1073741824
1000skills harness diagnose
1000skills harness measure
1000skills harness doctor
1000skills harness setup-check
1000skills install-native

Add --json to any command for output-envelope version 6. The one exception among harness subcommands is plain emit: 1000skills harness emit writes the raw authoring IR v2 document to stdout with or without --json, not an envelope, because its pipe target 1000skills harness sync --source-stdin consumes raw IR. emit --check is not an exception: it reports drift in a version-6 envelope because its consumer is a human or CI step, not a pipe. install-native is a top-level command, not a harness subcommand: it runs the native-binary installer shipped inside this package and passes its stdout, stderr, and exit code through. Nothing downloads on npm install; a remote install fails closed (cosign plus a signed release required) until a signed native release exists. Current trace writers use protocol version 2. The CLI allows stdout and stderr to drain before the process exits, including JSON envelopes larger than the platform pipe buffer.

Native delegation and the TypeScript fallback

With --json set and the native binary present, the CLI delegates route, changed, inspect, suggest-evals, diagnose, measure, doctor, the trace-* commands, sync, check, and uninstall to the native binary, and uses the TypeScript handler as the rollback. Without --json, the TypeScript handler always runs. The binary is resolved once per process: an explicit 1000SKILLS_NATIVE_BIN path, then the workspace build (crates/target/{release,debug}/1000skills), then the version-specific installed binary, then ~/.1000skills/bin/1000skills, then nothing. A different or unknown native version is refused.

Two environment variables control this. 1000SKILLS_FORCE_TS=1 forces the TypeScript handler even when the binary is present; use it in CI without the binary or to reproduce the TypeScript path. 1000SKILLS_NATIVE_BIN=/path/to/1000skills points at a specific binary. Both names start with a digit, so a POSIX shell rejects export 1000SKILLS_FORCE_TS=1; set them inline with env instead — env 1000SKILLS_FORCE_TS=1 1000skills harness sync --json, or env 1000SKILLS_NATIVE_BIN=/path 1000skills harness doctor --json.

check --baseline <ref> reads the generated pair from git at <ref>, so commit .agents/harness.json and .agents/harness.evals.json before running it. A ref without the committed pair fails with baseline.read_failed (a usage error with a fix hint, not an internal failure).

Routing commands load harness-v6 .agents/harness.json and eval-v5 .agents/harness.evals.json without executing authoring code. Source-verified check and sync compile the authoring input. Unsupported artifact schemas fail with artifact.schema_version_unsupported.

They fail closed on malformed, incomplete, unowned, or mismatched artifacts; sync owns atomic paired generation and interrupted-transaction recovery.

When normal commands refuse the pair, run harness doctor --json. A valid pending transaction is recovered by normal write-mode sync. Malformed transaction evidence stays fail-closed and must follow the artifact recovery runbook, shipped with the package — never delete it to make sync --repair proceed.

For ordinary drift, edit harness.config.ts or human-owned knowledge and run normal sync.

In committed mode, check and diagnose emit authority.review_required with the affected reference and authority path; normal sync refuses to reset the recorded fingerprint. Local mode reports authority changes as review guidance and keeps fingerprints in local build state. After semantic review, sync --accept-authority accepts the current secure authority files in write mode. The flag is invalid with --check or --diff.

When Claude is a tool target, sync also tracks its managed UserPromptSubmit activation in .claude/settings.json. Check and diff modes report a missing or changed managed hook without writing. Normal sync repairs only that managed entry and preserves unrelated settings and hooks. The generated hook selects the first configured Node candidate satisfying the package's >=22.12 engine range, routes with --format hook, and never adds --trace. Start traces through explicit trace start/record/finish commands, or explicitly pass --format hook --trace when a caller owns the complete trace lifecycle.

trace clean is an explicit retention action. It deletes only valid finished sessions that exceed the age or byte budget. It preserves unfinished, active, corrupt, locked, symlinked, unknown, and foreign-host evidence and reports each retained class in structured output.

Managed surface writes use a fixed recovery record plus deterministic sibling stage and recovery paths.

A later write sync restores or finishes an interrupted per-file mutation before compilation, including interrupted .claude/settings.json merges; check and diff modes fail with generated.recovery_required instead of changing recovery state.

Custom agents are generated for Claude (.claude/agents/*.md), OpenCode (.opencode/agents/*.md), Cursor (.cursor/agents/*.md), Codex (.codex/agents/*.toml), and Pi. Pi keeps definitions in .agents/harness.json. Install its versioned host package with pi install -l npm:1000skills@0.11.0. The adapter adds no project npm dependency or local extension shim. A sync removes an old SDK-owned shim and preserves user extensions. h.subagent.readOnly maps to a Claude tool allowlist, an OpenCode deny-all rule with declared read capabilities, Cursor readonly: true, or Pi's read, grep, find, and ls tool allowlist. Codex custom agents inherit parent permissions; an independent read-only request is refused.

Live host tests must confirm each restriction claim. Custom agents omit restriction claims where a target cannot map arbitrary tool names.

Prompt routing uses a Claude UserPromptSubmit hook, a Cursor always-applied rule, and the canonical AGENTS.md instruction consumed natively by OpenCode, Codex, and Pi. With bridgeSkills: true, sync creates Claude skill bridges for both explicit h.reference.skill entries and skills resolved through h.discover.skills; Cursor, OpenCode, Codex, and Pi use native .agents/skills discovery without duplicate links.

Adding a supported agent

Supported agents use one closed, compile-time registry. Add the target ID and artifact policy in src/contracts/tool-targets.ts, add one HarnessAdapter module under src/compiler/agent-adapters/, and register it in src/compiler/agent-adapters/registry.ts. If goal-loop can launch the agent, add one goal-loop adapter module and register it in src/goal-loop/adapters/registry.ts.

Do not add target checks to schema, CLI, source-set, diagnostics, or generated-surface code. These consumers derive target IDs, instruction inputs, managed directories, generated prefixes, delivery capabilities, and executable settings from the registries. Add the target to the cross-tool fixture and registry conformance tests, then regenerate schemas and API reports.

Use sync --repair only after diagnosis confirms that generated artifacts are malformed; it stages and validates a complete replacement pair before touching either fixed target. Do not use repair instead of correcting typed source.

The package manager is set per h.command.packageScript({ packageManager }); it defaults to npm and accepts npm, pnpm, or yarn. Each declaration controls its own manifest, so a harness can mix managers across commands. Package scripts compile to npm run <script>, pnpm run <script>, or yarn <script> argv.

Generated Cursor routing rules use the exact local-binary wrappers below, and diagnostics parse the same forms rather than accepting lookalikes:

Package managerGenerated route command
npmnpm exec -- 1000skills harness route "<task>"
pnpmpnpm exec 1000skills harness route "<task>"
Yarnyarn 1000skills harness route "<task>"

Changed-file recommendations return structured argv and never execute commands. Results always include unmatchedFiles and a deterministic effective plan that lists each retained command once with its contributing file classes, files, reasons, cwd, and argv. Raw groups remain explanatory, while retained commands inherit provenance from selected commands they transitively suppress. Artifact-only subsumes metadata is not included in output-v6 changed command objects. --require-classification returns exit 5 with changed.files_unclassified while preserving the complete evidence payload. Use inspect --file <path> for one-path classification and plan explanations; changed does not overload the file separator with an explain mode. A matched file class remains an explicit output group even when it intentionally recommends no commands, so metadata-only classes can return commands: [] and reasons: []. Initialized check:changed package scripts end in --, allowing npm run check:changed -- path and equivalent package-manager invocations to forward file paths naturally.

Route prompt path signals accept repository-relative, ./, <repo-root>, POSIX absolute, and Windows absolute forms. CLI routing passes the actual repository root so contained absolute paths become relative trigger candidates; paths outside that root remain absolute and are not falsely stripped. Path extraction recognizes Next.js dynamic ([id]), catch-all ([...slug]), optional catch-all ([[...slug]]), and route-group ((marketing)) segments. It also recognizes the case-sensitive conventional root files Dockerfile, LICENSE, Makefile, and Procfile, while ordinary parenthesized or lowercase prose is not treated as a path. Candidates matching a declared route or overlay path trigger remain path-only. Unmatched slash-separated candidates contribute normalized segment words back to keyword and pattern matching, so prose such as privacy/logging/provider is not discarded.

inspect accepts exactly one of --prompt, --file, --id, or --target. Prompt inspection reports the selected route and competitors, exact selected-overlay signals, context suppliers, deduplication, conditional-to-mandatory promotions, and per-overlay net deltas. File inspection reports normalization, every raw matching class and recommendation, reasons, and the collapsed effective command plan. Definition inspection reports derivable relations and eval coverage; command definitions include direct subsumes and subsumed-by edges. Target inspection reads the generated repository artifact, reports whether adapter metadata is available, and distinguishes native restrictions created by h.subagent.readOnly from custom-agent prose and tool policy. Artifacts generated before adapter metadata was added report configuration and restriction evidence as unknown; custom agents are never reported as natively read-only.

Coverage checks are built from actual routing and changed-file classification results. A recommendation is covered when an eval retains that command or a selected command that transitively subsumes it; changed eval expectations compare effective recommendation IDs in historical recommendation order.

Normal check and sync require behavioral evidence for every route, overlay, file class, fallback, recommendation, and declared trigger kind. They do not require one eval per synonym or literal file pattern. check --exhaustive adds every actionable diagnose finding to the quality gate, promotes diagnostic warnings to errors, and exits 5 when any remain. It does NOT emit per-signal eval.route_signal_uncovered or per-pattern eval.file_class_pattern_uncovered — those come only from diagnose and suggest-evals, which keep exhaustive per-signal and per-pattern evidence for audits without treating every alias as an ordinary quality-gate warning.

Overlay coverage requires global positive and negative evidence; the SDK does not invent obligations for every undeclared route-overlay cross-product. The shared graph records eval IDs per route and overlay signal, confusion edges, observed overlay-route evidence, file-class patterns and intersections, and recommendation coverage. When secure inventory matches uncovered file-class patterns, suggest-evals groups paths with the same effective command plan. It emits the exact recommendation union across every matching class.

Signal suggestions exercise the exact uncovered keyword, intent, or path; when no concrete evidence can exercise the gap, the result returns a blocker instead of substituting another owner signal or fabricating a path. Unsupported route and overlay patterns fail with the owner, offending pattern, and exact bounded-subset constraint rather than a generic regular-expression error. Diagnostic details summarize large evidence lists as deterministic samples with total and omitted counts, preserving owner, signal, and aggregate issue evidence without returning unbounded inventory arrays.

diagnose --json returns required actionable issues, required non-actionable observations, clean, and bounded metrics without changing its exit-zero evidence behavior. clean is true exactly when actionable issues are empty; observations remain visible audit evidence and never act as warnings. metrics.trackedFiles reports whether Git tracked-file evidence was available and the tracked, classified, unclassified, synthetic-fallback, intentional-fallback, and unexplained-fallback counts. syntheticFallback always equals intentionalFallback + unexplainedFallback. metrics.routeEvalMandatoryContext.words and .units report count, nearest-rank p50, nearest-rank p95, and max across route-eval mandatory context. Direct files are securely read and counted; unmeasured reports route evals whose direct-file words were unavailable instead of adding zero-valued word samples.

Tracked-file diagnostics use actionable diagnose.tracked_file_unclassified issues. Intentional fallback matches produce observational diagnose.tracked_file_fallback evidence; fallback wins outside intentionalPaths produce actionable diagnose.tracked_file_fallback_unexplained issues. Explicitly eval-declared promotions, same-context-ID duplicate suppliers, equivalent same-ID placements, promotion-intended observed same-ID mandatory/conditional status differences, and theoretical same-ID mandatory/conditional overlaps without not-selected context are observations. Different IDs resolving to one target even theoretically, reason conflicts, every status conflict involving not-selected context, undeclared observed mandatory/conditional conflicts, and zero-delta overlays remain issues. Trace diagnostics include malformed or inconsistent logs, invalid session IDs, and diagnose.trace_unfinished for sessions idle more than 24 hours. Finished trace symptoms are clustered by route, symptom, and explicit cause category: mandatory-missing causes are route-stale, trigger-too-broad, agent-skipped, file-missing, or unknown; not-selected violations are over-read, not-selected-wrong, or unknown. All path, session, item, and eval-ID evidence uses bounded deterministic samples.

Exit codes are stable:

CodeMeaning
0Success
2CLI misuse
3Invalid configuration or security state
4Generated artifact drift
5Eval or quality failure
70Internal failure

CI integration and eval semantics

In local mode, prepare base and candidate sources in separate checkouts, then run check --baseline-dir <prepared-base-root>. In committed mode, use check --baseline origin/main with the committed pair. A non-zero exit code is the gate signal. See team adoption. check runs eval cases deterministically: it routes each route eval's prompt through the harness router, classifies each changed eval's files through the changed-file classifier, and compares the result to the declared expectation. No LLM and no agent run; actual/expected divergence drives exit 5. quality eval cases are the exception: mustMention and mustReadFiles are directive-only — check injects them into the routed prompt and the LLM judges them at runtime; it does not compare them deterministically. check only structurally validates a quality case (its route exists and its mustReadFiles are secure repository paths). check also structurally confirms eval cases reference real routes, overlays, and commands (eval.route_missing, eval.overlay_missing, eval.command_missing). Use diagnose for drift and coverage gaps.

The first sync typechecks every authoring source module (harness.config.ts and its imports) with the SDK-pinned compiler and strict options, not your repository's tsconfig.json plugins or suppressions. A type error reports under the SDK compiler — fix it in the authoring source, not the SDK. This is the slowest feedback loop in the SDK — run sync early and often while authoring.

Generated contracts

sync writes current harness-v6 .agents/harness.json and eval-v5 .agents/harness.evals.json as one rollback-capable transaction. Harness core, route, and overlay context entries use a target-keyed contexts registry; route eval cases use an eval-local expectations registry whose expectations include ordered promotions.

Context registry keys are tagged target-only tokens (f:<path> for files, r:<kind>:<id>#<section> for references), each storing a per-entry integrity fingerprint in the registry value. Expectation registry IDs use 64-bit base64url digests (ep- plus 11 characters), and route/overlay trigger objects omit empty categories.

Strict parsers validate registry references, IDs, command subsumption targets, self edges, and cycles, then hydrate both wire artifacts into expanded private runtime models before routing, changed-file checks, diagnostics, or eval execution.

Matching generator, config, and discovery fingerprints bind the pair. The config fingerprint covers both decoded authoring semantics and the normalized source graph, so source-only edits intentionally produce artifact drift.

Artifacts contain no timestamps, absolute paths, environment data, or secrets.

The package publishes Draft 2020-12 schemas:

  • 1000skills/schema/harness.json (current v6)
  • 1000skills/schema/harness-evals.json (current v5)
  • 1000skills/schema/command-envelope.json (current v6)
  • 1000skills/schema/trace-event.json (current v2)

Non-Node consumers (a Python/Ruby/Go CI gate, a form-builder service) can fetch the same schemas without a Node install: the schemas ship in the npm tarball, so a CDN such as jsDelivr serves them directly.

Pin a version in the URL, e.g. https://cdn.jsdelivr.net/npm/1000skills@0.10.0/schemas/harness.schema.json; drop the @<version> to resolve to the latest published release.

The four published schema files are harness.schema.json, harness-evals.schema.json, command-envelope.schema.json, and trace-event.schema.json.

Runtime, check, diff, diagnose, and baseline readers never migrate old artifacts and report artifact.schema_version_unsupported when the pair is not current.

Normal write-mode sync also refuses stale or unsupported schema pairs and never migrates them. Malformed, mismatched, mixed-owner, and unowned pairs continue to fail closed. sync --repair is the only intentional path that may replace a refused pair with artifacts compiled from current typed source.

JSON-only repositories may author current harness-v6 and eval-v5 artifacts directly and use the same runtime commands.

Client parsers

Client parsers use a separate entrypoint: 1000skills/harness is the minimal hermetic authoring interface for harness.config.ts; 1000skills/harness/client is the runtime interface for programs that consume current CLI envelopes.

import { assertOk, parseRouteEnvelope } from "1000skills/harness/client";

export function readRoute(cliStdout: string): string {
  const envelope = parseRouteEnvelope(cliStdout);
  assertOk(envelope);
  return envelope.data.routeId;
}

Parsers validate JSON, the envelope, output version, command identity, and command-specific data. They accept only current output v6; output versions 2, 3, 4, and 5 fail with client.output_version_unsupported. Output-v6 diagnose requires observations plus intentionalFallback and unexplainedFallback, and enforces clean === (issues.length === 0). Trace envelopes also use output v6 while trace events retain the current trace protocol v2 contract.

parseTraceEnvelope keeps the event-only client contract. parseTraceCommandEnvelope accepts events or cleanup data. parseTraceCleanupEnvelope accepts only the cleanup result. CommandEnvelope is a discriminated union on ok: a valid ok: false envelope (FailedEnvelope) can be inspected manually via if (!envelope.ok), or assertOk narrows to SuccessfulEnvelope and throws on failure.


Everything below this point is for developers working on this package (building, releasing), not developers using it. If you are adopting 1000skills in your repository, you can stop reading here.

Development

Run from the repository root:

npm install
npm run typecheck
npm test
npm run build

TypeScript 7.0.2 is the package build compiler and emits JavaScript and declarations directly. The closed harness-config checker is pinned independently to TypeScript 6.0.3, and the packed-consumer gate compiles declaration fixtures with both versions. The package also uses Vitest 4, TypeBox, Ajv, Changesets, publint, Are the Types Wrong, API Extractor, Knip, and JSCPD; direct dependencies are pinned exactly.

npm run api:update --workspace=1000skills is the only command that updates checked-in API reports. npm run api:check --workspace=1000skills compares declarations and normalized reports without writing them.

prepack runs package verification but not the complete exact-tarball consumer gate. release:candidate owns the full workflow: archive the exact committed source, install its lockfile with lifecycle scripts disabled, run the controlled verification/build commands, and pack once. It checks that exact tarball with publint, Are the Types Wrong, npm, Yarn, pnpm, TypeScript 6.0.3, and TypeScript 7.0.2.

Release

npm run release:candidate
git add docs/releases/candidates/1000skills/<version>.json
gh workflow run publish.yml --ref main

After package documentation is approved, run npm run release:candidate. It requires clean committed source and writes one sealed tarball under /tmp/1000skills-release/1000skills/<version>/<candidate-id>/; macOS may expose the same directory through /private/tmp. Review and commit the path-free durable receipt at docs/releases/candidates/1000skills/<version>.json before authorizing publication.

The receipt binds the package and version to an opaque candidate ID, source revision, root tree, and a canonical SHA-256 over the sorted Git blob modes, paths, and bytes in the package source plus every repository-owned verification input declared by the release builder. It also records the artifact SHA-256, npm SHA-1, and npm SRI. A metadata-only later commit may publish it only while the current package-source digest remains identical. The staging hierarchy must be owned by the current user, use mode 0700, and contain no symlinks. The sealed candidate directory and tarball use modes 0500 and 0400; another build cannot replace either one.

The protected publish.yml workflow reconstructs the exact receipt-bound artifact once, uploads/downloads those bytes between jobs, and publishes with GitHub OIDC plus npm provenance. It never repacks in the publish job. Manual npm run release:publish is a fail-closed fallback that requires an explicit RELEASE_NPM_IDENTITY, a GitHub token authorized to create the durable lease, exact npm config and identity preflight, and authoritative version absence. npm run release:publish -- --npm-only is the no-GitHub variant: it skips the durable lease, keeps the identity preflight, the local attempt file, and the registry absence check, verifies the published artifact hashes against the receipt, and reports that a provenance-less publish stays pending. The local publish runs npm non-interactively, so the registry credential must be an automation or granular publish token; a token that requires a one-time password cannot complete it. Publication uses explicit public-registry, latest, public-access, and no-lifecycle-script flags. An atomic protected GitHub ref keyed by version and candidate prevents every second invocation, including fresh-runner retries. A successful publish runs the same registry verifier exposed as npm run release:verify; every failure after lease creation is resolved through recover-release.yml or the verifier instead of another publish attempt. Recovery needs only the durable receipt and registry bytes, not local staging.

Temporary consumers, rather than the local link, prove the packed artifact before publication.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 17

Collected releases
VersionPublishedDirect dependenciesOpen version
0.11.0Registry latest20 Oct 202620
0.10.09 Aug 202619
0.9.18 Aug 202619
0.9.05 Aug 202619
0.8.04 Aug 202619
0.7.03 Aug 202619
0.6.03 Aug 202619
0.5.23 Aug 202619
0.5.12 Aug 202619
0.5.02 Aug 202619
0.4.131 Jul 202619
0.4.031 Jul 202619
0.3.131 Jul 202619
0.3.030 Jul 202619
0.2.029 Jul 202619
0.1.125 Jul 202618
0.1.023 Jul 202618

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
kioviensis/1000skills

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 17:59 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:1822a03c987efdb907249125a96dfd243e775409786c7a3e44e7e2e15e60307f