@csark0812/skeleton 4.0.1 → 5.0.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- source-of-truth: Package overview -->
4
4
 
5
- <!-- doc-meta: owner=eng | last-reviewed=2026-09-02 -->
5
+ <!-- doc-meta: owner=eng | last-reviewed=2026-09-13 -->
6
6
 
7
7
  <!-- review-deps: paths=src/cli.ts,package.json -->
8
8
 
@@ -10,7 +10,7 @@ Agent repos get messy fast. Skills get copied around, docs disagree, links go st
10
10
 
11
11
  Skeleton is an SSOT linter for that layer. Define the contract once; Skeleton checks it locally and in CI. If a canonical doc disappears, SSOT markers drift, a skill index stops matching disk, or a local link breaks, the audit fails before merge.
12
12
 
13
- Think ESLint — for the docs and skills your agents rely on. Primary CLI from `src/cli.ts`: `audit`, `validate`, `catalog`, `init`, and `build-plugin` (plus `customize` / `hook` when using overlays). Commands dispatch through that entry file.
13
+ Think ESLint — for the docs and skills your agents rely on. Primary CLI from `src/cli.ts`: `audit`, `validate`, `catalog`, `init`, and `build-plugin`. Commands dispatch through that entry file.
14
14
 
15
15
  Skeleton is **not** a runtime agent harness. It doesn't execute tools, enforce permissions, or manage memory. It checks whether the repo around those systems still holds together.
16
16
 
@@ -78,7 +78,7 @@ npm install -D @csark0812/skeleton
78
78
  npx skeleton init --skills
79
79
  ```
80
80
 
81
- That writes `skeleton.toml`, ensures `.skeleton/customize/`, adds validation scripts, and may wire **optional** customize hooks for Cursor, Claude Code, and Codex.
81
+ That writes `skeleton.toml`, adds validation scripts, and writes `.pre-commit-config.yaml`.
82
82
 
83
83
  Edit `skeleton.toml` for your repo layout, then verify:
84
84
 
@@ -119,9 +119,7 @@ skeleton.toml # scan perimeter, deny.paths, docsLint, …
119
119
  .skeleton/
120
120
  ├── catalog.md # generated by `skeleton catalog` (gitignored)
121
121
  ├── review-lock.json # generated review evidence when reviewProof.mode = "hash"
122
- ├── plugins/ # optional consumer audit plugins (.ts + built .mjs)
123
- └── customize/ # project-specific skill overrides (optional)
124
- └── code-review.md
122
+ └── plugins/ # optional consumer audit plugins (.ts + built .mjs)
125
123
  ```
126
124
 
127
125
  Legacy `.skeleton/config.yaml` still loads when no TOML is present.
@@ -138,18 +136,17 @@ Then refresh the agent index:
138
136
  skeleton catalog
139
137
  ```
140
138
 
141
- Synced skills stay pristine. Project overrides live in `.skeleton/customize/<slug>.md` and inject when the skill is read — no editing copied `SKILL.md` files.
139
+ Edit synced skills in the owning toolbox repo. Consumer copies stay read-only.
142
140
 
143
141
  ## Commands
144
142
 
145
143
  ```bash
146
- skeleton init [--skills] [--force-hooks]
144
+ skeleton init [--skills]
147
145
  skeleton catalog [--check] [--strict]
148
146
  skeleton audit docs|skills|self [--strict] [--json] [--paths=a,b] [--fix[=doc-meta|anchors|ssot]] [--dry-run]
149
147
  skeleton audit docs --paths=docs/a.md --fix=doc-meta --confirm-reviewed
150
148
  skeleton build-plugin [path] [--check]
151
149
  skeleton validate changed [--staged | --base <ref>] [paths…]
152
- skeleton customize resolve <slug>
153
150
  ```
154
151
 
155
152
  **Validate changed** routes git diffs to the right audit:
@@ -157,15 +154,15 @@ skeleton customize resolve <slug>
157
154
  | Path | Action |
158
155
  | ----------------------------------------------------------------------------------- | --------------------------------------------- |
159
156
  | Docs in scan perimeter | path-scoped audit |
160
- | Owned skill bodies (`SKILL.md` trees) | exit 1 → run `audit skills` |
157
+ | Owned skill bodies (`SKILL.md` trees) | run `audit skills` |
161
158
  | Foreign / lockfile-synced skill bodies | skip → lint in the owning skills/toolbox repo |
162
159
  | `.sh`, `.bash`, `.zsh` | shellcheck or `bash -n` |
163
160
  | Other `.json` | JSONC-tolerant syntax check |
164
161
  | Any repository file | native gates where applicable + audit documents whose `review-deps` path or glob matched |
165
162
 
166
- Pre-commit: `skeleton validate changed --staged` (path-scoped, fast).
163
+ Pre-commit: `skeleton validate changed --staged` (index bytes, coverage, owning papers).
167
164
 
168
- CI: `skeleton validate changed --base origin/main` (global rules first, then changed files).
165
+ CI: `skeleton validate changed --base origin/main` (global rules first, then changed files, same coverage fail).
169
166
 
170
167
  ## Ecosystem
171
168
 
@@ -186,7 +183,6 @@ See [tiers](docs/tiers.md). Related work: [Toolbox](https://github.com/csark0812
186
183
  - [Validation](docs/developer/validation.md)
187
184
  - [Audit rules](docs/developer/audit.md)
188
185
  - [Plugins](docs/developer/plugins.md)
189
- - [Customize](docs/developer/customize.md)
190
186
  - [Authoring conventions](docs/authoring.md)
191
187
 
192
188
  ## Development
@@ -200,8 +196,8 @@ bun run check
200
196
 
201
197
  `bun run check` = lint + test + typecheck + build + `audit:self`.
202
198
 
203
- `validate:changed` does not replace code tests. It classifies code separately and also audits every scanned document whose `review-deps` declaration matches a changed file. Owned skill-body edits need `audit skills`. Code-only changes with no linked document still exit non-zero locally and point to native gates.
199
+ `validate:changed` does not replace code tests. It classifies code separately and also audits every scanned document whose `review-deps` declaration matches a changed file. A coverage-candidate path with no owning paper fails on local and CI runs. Owned skill-body edits run the skills suite. `--staged` reads git index bytes.
204
200
 
205
201
  For code: `bun test`, `bun run typecheck`, `bun run build`.
206
202
 
207
- Optional: `brew install pre-commit` (or `pipx install pre-commit`), then `pre-commit install` to wire `.pre-commit-config.yaml`.
203
+ `skeleton init` writes `.pre-commit-config.yaml`. Install [pre-commit](https://pre-commit.com/) once (`brew install pre-commit` or `pipx install pre-commit`), then `pre-commit install`.
@@ -8,10 +8,6 @@ export interface DenyConfig {
8
8
  /** Repo-wide globs that must not exist — audit fails if matched. */
9
9
  paths?: string[];
10
10
  }
11
- export interface CustomizeConfig {
12
- /** Basenames under `.skeleton/customize/` appended on every customize inject. */
13
- alwaysInclude?: string[];
14
- }
15
11
  /**
16
12
  * Ownership policy for skill-body linting.
17
13
  * Lockfile `sourceType` other than `local` (e.g. `github`) marks skills foreign by default.
@@ -24,6 +20,13 @@ export interface SkillOwnershipConfig {
24
20
  /** Force these slugs foreign even if absent from the lockfile / local. */
25
21
  foreignSlugs?: string[];
26
22
  }
23
+ /** Files that must appear in at least one scanned document's review-deps. */
24
+ export interface ReviewCoverageConfig {
25
+ /** Repo-relative globs that require an owning paper. Empty include disables the gate. */
26
+ include?: string[];
27
+ /** Globs removed from the coverage set. */
28
+ exclude?: string[];
29
+ }
27
30
  /** Verifiable evidence that a human review covered exact document and code bytes. */
28
31
  export interface ReviewProofConfig {
29
32
  /** Hash mode stores reviewed document and code-target digests in a lockfile. */
@@ -51,9 +54,9 @@ export interface SkeletonConfig {
51
54
  /** Re-read cadence (days) for doc-meta last-reviewed; separate from git edit-behind-review. */
52
55
  daysUntilStale: number;
53
56
  deny?: DenyConfig;
54
- customize?: CustomizeConfig;
55
57
  skillOwnership?: SkillOwnershipConfig;
56
58
  reviewProof?: ReviewProofConfig;
59
+ reviewCoverage?: ReviewCoverageConfig;
57
60
  docsLint?: DocsLintConfig;
58
61
  /**
59
62
  * Plugin entry paths relative to `.skeleton/` (e.g. `plugins/example.ts`).
@@ -1,5 +1,6 @@
1
1
  import type { SkeletonConfig } from "../config/types.ts";
2
2
  import type { PolicyFile } from "../policies/types.ts";
3
+ import type { FileSource } from "./repo-files.ts";
3
4
  import { type SkillIndex } from "./skill-roots.ts";
4
5
  import type { SsotForm } from "./ssot.ts";
5
6
  import { type SsotFileEntry } from "./ssot-collect.ts";
@@ -30,6 +31,8 @@ export interface AuditContext {
30
31
  lockedSkillSlugs: Set<string>;
31
32
  /** Compiled prose policies from plugins (empty when no plugins / no policy globs). */
32
33
  policies: PolicyFile[];
34
+ /** Read document and dependency bytes from the worktree or the git index. */
35
+ fileSource?: FileSource;
33
36
  }
34
37
  export interface AuditOptions {
35
38
  root?: string;
@@ -42,5 +45,7 @@ export interface AuditOptions {
42
45
  * matches path-scoped / validate `--base` prove.
43
46
  */
44
47
  includeExcludedSkillTrees?: boolean;
48
+ /** When `index`, review-proof and coverage reads use `git show :path`. */
49
+ fileSource?: FileSource;
45
50
  }
46
51
  export declare function createContext(options?: AuditOptions): AuditContext;
@@ -0,0 +1,5 @@
1
+ export type FileSource = "worktree" | "index";
2
+ /** Read a repo-relative file from the worktree or the git index. */
3
+ export declare function readRepoText(root: string, relPath: string, source?: FileSource): string | null;
4
+ /** True when worktree bytes differ from HEAD, including new untracked files. */
5
+ export declare function pathDiffersFromHead(root: string, relPath: string): boolean;
@@ -29,3 +29,4 @@ export declare function issue(rule: string, file: string, details: string | Issu
29
29
  export declare function issue(rule: string, file: string, message: string, options?: IssueOptions): Issue;
30
30
  export declare function finalizeIssues(issues: Issue[], strict: boolean): Issue[];
31
31
  export declare function printReport(issues: Issue[], options: ReportOptions): number;
32
+ export declare function isRereadIssue(item: Issue): boolean;
@@ -0,0 +1,18 @@
1
+ import type { SkeletonConfig } from "../config/types.ts";
2
+ import { type FileSource } from "./repo-files.ts";
3
+ import type { SkillIndex } from "./skill-roots.ts";
4
+ export declare const DEFAULT_REVIEW_COVERAGE_INCLUDE: string[];
5
+ export declare const DEFAULT_REVIEW_COVERAGE_EXCLUDE: string[];
6
+ export declare function reviewCoveragePatterns(config: SkeletonConfig): {
7
+ include: string[];
8
+ exclude: string[];
9
+ };
10
+ export declare function pathRequiresReviewCoverage(relPath: string, config: SkeletonConfig): boolean;
11
+ export declare function collectReviewDependencyPatterns(input: {
12
+ root: string;
13
+ config: SkeletonConfig;
14
+ skillIndex: SkillIndex;
15
+ fileSource?: FileSource;
16
+ }): string[];
17
+ export declare function pathHasReviewOwner(relPath: string, patterns: string[]): boolean;
18
+ export declare function collectReviewCoverageFiles(root: string, config: SkeletonConfig): string[];
@@ -0,0 +1,8 @@
1
+ import type { AuditContext } from "../core/context.ts";
2
+ import { type Issue } from "../core/report.ts";
3
+ export declare function runReviewCoverageRule(ctx: AuditContext): Issue[];
4
+ export declare const reviewCoverageRule: {
5
+ id: string;
6
+ global: boolean;
7
+ run: typeof runReviewCoverageRule;
8
+ };