Skip to content

Latest commit

 

History

History
162 lines (116 loc) · 9.23 KB

File metadata and controls

162 lines (116 loc) · 9.23 KB

Config

Machine schema: schemas/config.schema.json (validates the loaded object). Init template: templates/skeleton-init/skeleton.toml. Day-one walkthrough: getting started.

Loader: loadConfig / loadConfigDetailed / findRepoRoot / mergedExcludes in src/audit/config/load.ts. Typed shape: SkeletonConfig (ScanConfig, DocsLintConfig, DenyConfig, SkillOwnershipConfig, ReviewProofConfig, ReviewCoverageConfig).

Preferred path: skeleton.toml at the repo root. Legacy .skeleton/config.yaml still loads when no TOML is present. If both exist, TOML wins and the CLI warns that YAML is ignored.

Required

Top-level required keys: scan and daysUntilStale. Inside scan, required: include, exclude.

Key Purpose
scan.include Glob patterns for markdown/docs/skills in the audit perimeter (links, doc-meta, SSOT)
scan.exclude Removed from the perimeter (drafts, refs, local install trees)
daysUntilStale Re-read cadence: warn (error under --strict) when last-reviewed is older than N days — not the same as “edited after review” (that uses git; see doc system)

Optional

Key Purpose
deny.paths Repo-wide globs that must not exist — audit fails if matched (often outside include)
scan.nonPublicSkills Slugs on disk that must not appear in nested skills README ## Taxonomy
plugins Plugin entry paths relative to .skeleton/ (each needs a built sibling .mjs) — plugins
draftPathPrefixes Allow-list prefixes for draft-marker prose policy (plus _draft-*.md). Not scan.exclude
skillOwnership Provenance-aware skill body linting (see below)
reviewProof Hash-backed evidence for exact reviewed document and review-deps bytes (see below)
reviewCoverage Globs that must appear in at least one scanned paper's review-deps (see below)
docsLint Near-duplicate / SSOT-summary thresholds and ignore pairs (see below)

Deleted skills need no denylist: links to missing …/SKILL.md fail under the links / skill-index rules.

Hard cut: scan.banned and scan.retiredSkills are rejected by the schema — use deny.paths instead of banned.

deny

[deny]
paths = ["apps/**/*_ANALYSIS.md"]

docsLint

Key Purpose
nearDuplicateThreshold Jaccard on word shingles (default 0.72); warn / --strict → error
ssotOverlapMin Min fraction of stemmed SSOT tokens in H1/lead/body evidence (default 0.35)
ssotBetterMatchMargin Sibling must beat own overlap by this much for better-match (default 0.15)
ssotPhraseCheck When overlap fails, mention missing SSOT phrase in the message (default true)
ignorePairs Path pairs skipped by near-dupe / duplicate-SSOT
ignoreGlobs Globs skipped by near-dupe / duplicate-SSOT

ssot-summary scores stemmed unigrams against H1 + lead + body (SSOT line stripped). Exact phrase match only explains a failed overlap — abstract titles can pass without verbatim phrasing. Better-match warns only when own overlap is weak and another SSOT paper fits better; the message lists rewrite / retarget / consider-combine options.

review-deps: opt-in HTML comment markers with comma-separated paths=. Docs may declare exact repo-relative files or globs. Exact missing files error; empty globs warn (or error under --strict). See doc system.

reviewProof

[reviewProof]
mode = "hash"
# lockfile = ".skeleton/review-lock.json"

Hash mode makes last-reviewed verifiable. Explicit attestation stores SHA-256 digests for the complete document and every resolved review-deps dependency. Any byte or resolved-set change invalidates the review until a human re-reads and attests the document again. Commit the lockfile. Init enables this section by default.

Without this section, Skeleton uses compatibility date mode. Changed review dependencies still pull linked documents into validate changed; the document must co-change with an explicit review date. Under --base, that date must be on or after the UTC date of the latest non-merge commit in the range that touched the dependency; local runs require today's UTC date.

reviewCoverage

[reviewCoverage]
include = ["src/**/*.ts", "package.json"]
exclude = ["src/**/__tests__/**", "src/**/*.test.ts"]

Files that match include (minus exclude and built-in test or fixture excludes) must appear in at least one scanned paper's review-deps. The global review-coverage rule checks the whole set. validate changed also fails uncovered-changed-path when a changed candidate has no owner.

Omit the section to use built-in code defaults (**/*.{ts,tsx,js,jsx,mjs,cjs,py}, package.json, project.json). Built-in excludes drop tests, fixtures, templates, nested node_modules / dist / .venv, and .skeleton/plugins/**. Production .mjs stays in the coverage set. Set include = [] to disable the gate.

skillOwnership

When a consumer repo syncs skills from a toolbox (via skills-lock.json), Skeleton skips foreign skill bodies so linting stays with the owning repo. That skip covers skill-body lint (audit skills), path-scoped validate routing, and doc-meta for paths under foreign skill trees — including SSOT-bearing references/** files.

Key Purpose
lockfile Repo-relative lock path (default skills-lock.json)
ownedSlugs Force these slugs owned (lint here) even if the lock marks them foreign
foreignSlugs Force these slugs foreign (skip body lint) even if absent from the lock

Default rules without overrides:

  • Lock entry sourceType: github (or any non-local) → foreign
  • Lock entry sourceType: local, or slug not in the lock → owned
[skillOwnership]
lockfile = "skills-lock.json"
# ownedSlugs = ["skeleton"]
# foreignSlugs = ["experimental-local-copy"]

See audit and validation.

What affects validate vs full audit

Concern Keys / behavior
Path-scoped validate changed Files in scan.include (minus exclude) get docs audit; owned skill trees run the skills suite; foreign lock skills skip; coverage-candidate code without an owning paper fails
Global rules (--base / full audit) deny.paths (rule banned), SSOT dual/malformed, near-dupe, ssot-summary, coverage outside include, review-coverage, scan-roots, skill-index
Prose policies Idle until plugins contribute policy YAML
Skill body ownership skillOwnership + skills-lock.json (foreign bodies skipped)
Catalog Local audit and validate changed write .skeleton/catalog.md on each run; skipped when CI=true

Example: toolbox / docs-only

daysUntilStale = 365

[scan]
include = [
  "docs/**",
  "README.md",
  "AGENTS.md",
]
exclude = ["refs/**"]

[deny]
paths = []

Example: app with plugins

daysUntilStale = 365

[scan]
include = [
  "docs/**",
  "README.md",
  "AGENTS.md",
  ".claude/skills/**",
]
exclude = [
  "refs/**",
  "**/_draft-*/**",
]

[deny]
paths = ["apps/**/*_ANALYSIS.md"]

plugins = ["plugins/example/example.ts"]

Legacy YAML is still accepted when skeleton.toml is absent — same keys under .skeleton/config.yaml.