@erclx/aitk 3.8.0 → 3.10.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/create-skill/REQUIREMENT.md +5 -1
- package/claude/skills/create-skill/SKILL.md +10 -4
- package/claude/skills/toolkit-cli/SKILL.md +0 -2
- package/docs/agents/audits.md +2 -2
- package/docs/agents/census.md +23 -0
- package/docs/agents/commands.md +2 -0
- package/docs/agents/index.md +2 -0
- package/docs/agents/restated.md +78 -0
- package/governance/rules/claude/570-skill.md +2 -0
- package/package.json +1 -1
- package/src/audits/catalog.ts +77 -0
- package/src/census/count.ts +113 -0
- package/src/cli.ts +5 -0
- package/src/commands/census.ts +105 -0
- package/src/commands/gov.ts +160 -0
- package/src/gov/restated.ts +688 -0
- package/standards/skill.md +1 -0
- package/tooling/base/manifest.toml +0 -2
- package/tooling/base/reference.md +12 -12
- package/tooling/base/seeds/.claude/context/development.md +4 -6
- package/tooling/base/configs/scripts/clean.sh +0 -45
- package/tooling/base/configs/scripts/update.sh +0 -49
package/src/commands/gov.ts
CHANGED
|
@@ -14,6 +14,15 @@ import {
|
|
|
14
14
|
mergeExtraRules,
|
|
15
15
|
resolveRules,
|
|
16
16
|
} from '@/gov/stacks'
|
|
17
|
+
import {
|
|
18
|
+
INSTRUCTIONS_REL,
|
|
19
|
+
type RestatedEntry,
|
|
20
|
+
type RestatedRefusal,
|
|
21
|
+
type RestatedReport,
|
|
22
|
+
readRestated,
|
|
23
|
+
SEED_REL,
|
|
24
|
+
SHIPPED_SKILLS_REL,
|
|
25
|
+
} from '@/gov/restated'
|
|
17
26
|
import {
|
|
18
27
|
readSuperseded,
|
|
19
28
|
SUPERSEDED_MARKER,
|
|
@@ -68,6 +77,17 @@ interface SupersededOptions {
|
|
|
68
77
|
readonly json?: boolean
|
|
69
78
|
}
|
|
70
79
|
|
|
80
|
+
interface RestatedOptions {
|
|
81
|
+
readonly root?: string
|
|
82
|
+
readonly json?: boolean
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** What a reader does about each way the sweep produced no reading. */
|
|
86
|
+
const RESTATED_REFUSALS: Record<RestatedRefusal, string> = {
|
|
87
|
+
'no-instructions': `No ${INSTRUCTIONS_REL} here, or it carries no bullet, so there is no instruction corpus to sweep.`,
|
|
88
|
+
'no-surfaces': `Neither ${SEED_REL} nor ${SHIPPED_SKILLS_REL}/ is here, so no second surface exists to match against.`,
|
|
89
|
+
}
|
|
90
|
+
|
|
71
91
|
export function register(program: Command): void {
|
|
72
92
|
const gov = program
|
|
73
93
|
.command('gov')
|
|
@@ -245,6 +265,146 @@ export function register(program: Command): void {
|
|
|
245
265
|
process.exitCode = await runSuperseded(superseded, replacement, opts)
|
|
246
266
|
},
|
|
247
267
|
)
|
|
268
|
+
|
|
269
|
+
gov
|
|
270
|
+
.command('restated')
|
|
271
|
+
.description(
|
|
272
|
+
'Report every instruction the always-loaded file states that a second surface states too',
|
|
273
|
+
)
|
|
274
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
275
|
+
.option('--root <path>', 'Tree to read, defaulting to the cwd')
|
|
276
|
+
.option('--json', 'Add a machine-readable record on stdout')
|
|
277
|
+
.addHelpText(
|
|
278
|
+
'after',
|
|
279
|
+
[
|
|
280
|
+
'',
|
|
281
|
+
`Matches every bullet in ${INSTRUCTIONS_REL} against ${SEED_REL}`,
|
|
282
|
+
`and every ${SHIPPED_SKILLS_REL}/*/SKILL.md body. Matching is recall-first,`,
|
|
283
|
+
'keyed on distinctive tokens two statements share rather than on a phrase',
|
|
284
|
+
'they spell the same way, because the case this exists for was one rule',
|
|
285
|
+
'written three different ways.',
|
|
286
|
+
'',
|
|
287
|
+
'What it separates:',
|
|
288
|
+
' mirror a declared authoring-to-consumed pair, where repeating is the design',
|
|
289
|
+
' repetition two surfaces state one rule and neither is declared a copy',
|
|
290
|
+
' contradiction the prohibition falls on one surface alone, on a strong match',
|
|
291
|
+
'',
|
|
292
|
+
'The contradiction class is a polarity reading rather than a judgment',
|
|
293
|
+
'about meaning, so weigh each against the surfaces it names.',
|
|
294
|
+
'',
|
|
295
|
+
'What it does not measure:',
|
|
296
|
+
' a rule stated in two skill bodies and never in the always-loaded file,',
|
|
297
|
+
' since the bullets there are the subjects and the bodies are searched',
|
|
298
|
+
'',
|
|
299
|
+
'Exit codes:',
|
|
300
|
+
' 0 no instruction is restated outside a declared mirror',
|
|
301
|
+
' 1 refused, with the reason on stderr or in the JSON record',
|
|
302
|
+
' 2 at least one instruction is restated outside a declared mirror',
|
|
303
|
+
'',
|
|
304
|
+
'Examples:',
|
|
305
|
+
' aitk gov restated',
|
|
306
|
+
' aitk gov restated --json',
|
|
307
|
+
'',
|
|
308
|
+
].join('\n'),
|
|
309
|
+
)
|
|
310
|
+
.action((opts: RestatedOptions) => {
|
|
311
|
+
process.exitCode = runRestated(opts)
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Reports and never gates, matching the two sweeps above. A restatement is
|
|
317
|
+
* legitimate more often than not, so failing a push on one would fail on the
|
|
318
|
+
* ordinary case and teach contributors to route around the stage.
|
|
319
|
+
*/
|
|
320
|
+
function runRestated(opts: RestatedOptions): number {
|
|
321
|
+
const root = resolve(opts.root ?? process.cwd())
|
|
322
|
+
const report = readRestated(root)
|
|
323
|
+
const emitJson = opts.json ?? false
|
|
324
|
+
|
|
325
|
+
if (report.kind === 'unreadable') {
|
|
326
|
+
intro('aitk gov restated')
|
|
327
|
+
logStep('Refused')
|
|
328
|
+
logWarn(RESTATED_REFUSALS[report.reason])
|
|
329
|
+
outro()
|
|
330
|
+
|
|
331
|
+
if (emitJson) {
|
|
332
|
+
process.stdout.write(
|
|
333
|
+
`${JSON.stringify({
|
|
334
|
+
root,
|
|
335
|
+
reason: report.reason,
|
|
336
|
+
message: RESTATED_REFUSALS[report.reason],
|
|
337
|
+
})}\n`,
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return 1
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
reportRestated(report, root)
|
|
345
|
+
|
|
346
|
+
if (emitJson) {
|
|
347
|
+
process.stdout.write(`${JSON.stringify({ root, ...report })}\n`)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const findings = report.counts.contradictions + report.counts.repetitions
|
|
351
|
+
return findings > 0 ? 2 : 0
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function describeEntry(entry: RestatedEntry): string[] {
|
|
355
|
+
const lines = [`${entry.subject.file}:${entry.subject.line}`]
|
|
356
|
+
|
|
357
|
+
for (const surface of entry.surfaces) {
|
|
358
|
+
lines.push(
|
|
359
|
+
` [${surface.restatement}] ${surface.file}:${surface.line} via ${surface.anchors.join(', ')}`,
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return lines
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function reportRestated(
|
|
367
|
+
report: Extract<RestatedReport, { kind: 'measured' }>,
|
|
368
|
+
root: string,
|
|
369
|
+
): void {
|
|
370
|
+
intro('aitk gov restated')
|
|
371
|
+
|
|
372
|
+
// A count of what matched reads as a verdict on the repository unless the run
|
|
373
|
+
// also says how wide the corpus behind it was.
|
|
374
|
+
logStep('Corpus')
|
|
375
|
+
logInfo(
|
|
376
|
+
`${report.corpus.instructions} instruction(s) against ${report.corpus.candidates} statement(s) from the seed and ${report.corpus.bodies} shipped body/bodies in ${root}`,
|
|
377
|
+
)
|
|
378
|
+
logInfo(
|
|
379
|
+
`matched on ${report.matcher.anchors} weighted anchor(s), dropping any token in more than ${report.matcher.common} statements`,
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
// Named rather than counted. A polarity split is the only class claiming a
|
|
383
|
+
// defect, and a reader weighing one has to reach both surfaces.
|
|
384
|
+
logStep(
|
|
385
|
+
report.counts.contradictions === 0 ? 'No contradiction' : 'Contradictions',
|
|
386
|
+
)
|
|
387
|
+
if (report.counts.contradictions === 0) {
|
|
388
|
+
logInfo('no restatement puts a prohibition on one surface alone')
|
|
389
|
+
} else {
|
|
390
|
+
for (const entry of report.restatements) {
|
|
391
|
+
const carries = entry.surfaces.some(
|
|
392
|
+
(surface) => surface.restatement === 'contradiction',
|
|
393
|
+
)
|
|
394
|
+
if (!carries) continue
|
|
395
|
+
for (const line of describeEntry(entry)) logWarn(line)
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
logStep('Restated')
|
|
400
|
+
logInfo(
|
|
401
|
+
`${report.counts.repetitions} repetition(s) outside a declared mirror, and ${report.counts.mirrors} on one`,
|
|
402
|
+
)
|
|
403
|
+
logInfo(
|
|
404
|
+
`${report.counts.threeSurface} instruction(s) reach three surfaces or more`,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
outro()
|
|
248
408
|
}
|
|
249
409
|
|
|
250
410
|
/**
|