@mmnto/totem 1.78.0 → 1.80.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/dist/artifacts/panel.d.ts +48 -48
- package/dist/artifacts/schema.d.ts +40 -40
- package/dist/compiler-schema.d.ts +2455 -35
- package/dist/compiler-schema.d.ts.map +1 -1
- package/dist/compiler-schema.js +229 -1
- package/dist/compiler-schema.js.map +1 -1
- package/dist/compiler-schema.test.js +249 -2
- package/dist/compiler-schema.test.js.map +1 -1
- package/dist/compiler.d.ts +2 -2
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +1 -1
- package/dist/compiler.js.map +1 -1
- package/dist/config-schema.d.ts +6 -6
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/spine/authored-rule.d.ts +1358 -0
- package/dist/spine/authored-rule.d.ts.map +1 -0
- package/dist/spine/authored-rule.js +313 -0
- package/dist/spine/authored-rule.js.map +1 -0
- package/dist/spine/authored-rule.test.d.ts +2 -0
- package/dist/spine/authored-rule.test.d.ts.map +1 -0
- package/dist/spine/authored-rule.test.js +226 -0
- package/dist/spine/authored-rule.test.js.map +1 -0
- package/dist/spine/authoring-ledger.d.ts +204 -0
- package/dist/spine/authoring-ledger.d.ts.map +1 -0
- package/dist/spine/authoring-ledger.js +220 -0
- package/dist/spine/authoring-ledger.js.map +1 -0
- package/dist/spine/authoring-ledger.test.d.ts +2 -0
- package/dist/spine/authoring-ledger.test.d.ts.map +1 -0
- package/dist/spine/authoring-ledger.test.js +144 -0
- package/dist/spine/authoring-ledger.test.js.map +1 -0
- package/dist/spine/candidate-rule.d.ts +32 -0
- package/dist/spine/candidate-rule.d.ts.map +1 -1
- package/dist/spine/candidate-rule.js +2 -2
- package/dist/spine/candidate-rule.js.map +1 -1
- package/dist/spine/classify.d.ts +5 -5
- package/dist/spine/compile.d.ts +16 -4
- package/dist/spine/compile.d.ts.map +1 -1
- package/dist/spine/compile.js +23 -0
- package/dist/spine/compile.js.map +1 -1
- package/dist/spine/compile.test.js +72 -0
- package/dist/spine/compile.test.js.map +1 -1
- package/dist/spine/corpus-dispositions.d.ts +22 -22
- package/dist/spine/extract.d.ts +2 -2
- package/dist/spine/extract.d.ts.map +1 -1
- package/dist/spine/extract.js +5 -4
- package/dist/spine/extract.js.map +1 -1
- package/dist/spine/ledgers.d.ts +46 -21
- package/dist/spine/ledgers.d.ts.map +1 -1
- package/dist/spine/ledgers.js +16 -8
- package/dist/spine/ledgers.js.map +1 -1
- package/dist/spine/rule-policy.d.ts +27 -0
- package/dist/spine/rule-policy.d.ts.map +1 -0
- package/dist/spine/rule-policy.js +43 -0
- package/dist/spine/rule-policy.js.map +1 -0
- package/dist/spine/rule-policy.test.d.ts +2 -0
- package/dist/spine/rule-policy.test.d.ts.map +1 -0
- package/dist/spine/rule-policy.test.js +31 -0
- package/dist/spine/rule-policy.test.js.map +1 -0
- package/dist/spine/windtunnel-lock.d.ts +14 -14
- package/dist/store/lance-schema.d.ts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authored-rule.d.ts","sourceRoot":"","sources":["../../src/spine/authored-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
// ─── ADR-112 Gate-1 authored producer: the AuthoredRuleRecord envelope ───────
|
|
2
|
+
//
|
|
3
|
+
// The human-authored counterpart to ADR-111's mined `CandidateRuleRecord`. An
|
|
4
|
+
// authored rule is anchored to a real historical DEFECT (its `provenance` is the
|
|
5
|
+
// AUTHORED variant of the ADR-112 union — train-side preimage fixtures, §3/§4),
|
|
6
|
+
// carries an INDEPENDENTLY-judged structural-eligibility result (NOT author-
|
|
7
|
+
// asserted — §3), an accelerant-lineage marker (§7), and is minted
|
|
8
|
+
// `unverified`/Yellow (ADR-089) with zero enforcement blast radius.
|
|
9
|
+
//
|
|
10
|
+
// SLICE A scope: the schema spine + the deterministic eligibility check + the
|
|
11
|
+
// stable rule-id mint. The `totem rule author` CLI + the `.totem/spine/
|
|
12
|
+
// authored-rules.yaml` reader are slice B; the compile-feed integration into
|
|
13
|
+
// `runCompileStage` is gated on the `compileCandidate` param-widening flagged in
|
|
14
|
+
// the slice-A report (a controller decision). The whitelist REGISTRY of
|
|
15
|
+
// decidable classes lives in the CLI (slice B, mirroring `valueEqualityFieldsFor`);
|
|
16
|
+
// this core check takes it injected (DI), staying network-free + LLM-free.
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
import { AuthoredFixtureSchema, AuthoredProvenanceRecordSchema, isIso8601CalendarDate, } from '../compiler-schema.js';
|
|
20
|
+
/** The matcher engines an authored rule may declare (mirrors `CompiledRule.engine`). */
|
|
21
|
+
export const DeclaredEngineSchema = z.enum(['regex', 'ast', 'ast-grep']);
|
|
22
|
+
// The §3 eligibility-basis forms: `whitelist:<class>` (the cert-#1 deterministic basis,
|
|
23
|
+
// a non-empty class after the colon), or the deferred `capability-check` /
|
|
24
|
+
// `draft-classifier+stage4`. Pins `basis` to the contract so a free-form/typo'd value
|
|
25
|
+
// can't validate (strategy item 2, #2259).
|
|
26
|
+
const ELIGIBILITY_BASIS_RE = /^(?:whitelist:.+|capability-check|draft-classifier\+stage4)$/;
|
|
27
|
+
/**
|
|
28
|
+
* ADR-112 §3 — the result of the INDEPENDENT structural-eligibility check.
|
|
29
|
+
* Produced by `evaluateStructuralEligibility` (NOT by the author): only
|
|
30
|
+
* `decidable: true` reaches the compiler, mapping to the compiler's
|
|
31
|
+
* `classifierDisposition: 'structural'`. `judgedBy` records who/what judged it
|
|
32
|
+
* (ledger-recorded, never the author), so a human cannot smuggle a behavioral
|
|
33
|
+
* policy past ADR-091's gate by hand-asserting "structural" (FM(d)).
|
|
34
|
+
*/
|
|
35
|
+
export const StructEligResultSchema = z.object({
|
|
36
|
+
decidable: z.boolean(),
|
|
37
|
+
/**
|
|
38
|
+
* `whitelist:<class>` for the cert-#1 static-whitelist basis; the
|
|
39
|
+
* `capability-check` / `draft-classifier+stage4` bases are contract-legal but
|
|
40
|
+
* deferred (slice-A uses the deterministic whitelist only). On a `decidable:
|
|
41
|
+
* false` verdict the basis still names the attempted whitelist class — the
|
|
42
|
+
* diagnostic is "no/ambiguous whitelist match", carried in `judgedBy`'s log.
|
|
43
|
+
* Constrained to the §3 forms (strategy item 2, #2259) so a typo'd/free-form
|
|
44
|
+
* basis can't validate — non-mutating (no `.trim()`), matching the hash-stability
|
|
45
|
+
* discipline on the other reference fields.
|
|
46
|
+
*/
|
|
47
|
+
basis: z.string().refine((s) => ELIGIBILITY_BASIS_RE.test(s), {
|
|
48
|
+
message: 'basis must be a §3 eligibility basis: whitelist:<class> | capability-check | draft-classifier+stage4',
|
|
49
|
+
}),
|
|
50
|
+
judgedBy: z.string().refine((s) => s.trim().length > 0, {
|
|
51
|
+
message: 'judgedBy must name the check/agent that judged eligibility (never the author)',
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
/** ADR-112 §3/§7 — accelerant-lineage marker. A mined hint that informed a human is recorded, never erased. */
|
|
55
|
+
export const AuthoredOriginSchema = z.union([
|
|
56
|
+
z.object({ kind: z.literal('from-scratch') }),
|
|
57
|
+
z.object({
|
|
58
|
+
kind: z.literal('mined-accelerant'),
|
|
59
|
+
sourceRunId: z.string().refine((s) => s.trim().length > 0, { message: 'sourceRunId required' }),
|
|
60
|
+
suggestionHash: z.string().refine((s) => s.trim().length > 0, {
|
|
61
|
+
message: 'suggestionHash required',
|
|
62
|
+
}),
|
|
63
|
+
}),
|
|
64
|
+
]);
|
|
65
|
+
// The persisted minted-rule-id shape (ADR-112 §8): a 16-char lowercase-hex base from
|
|
66
|
+
// `mintAuthoredRuleId`, with an optional collision suffix. The suffix is EXACTLY what the
|
|
67
|
+
// mint emits — `-<n>` for n≥1, never `-0` and never zero-padded — so schema-valid ≡
|
|
68
|
+
// mint-producible (#2259 CR: a looser `-\d+` admitted ids like `…-0`/`…-01` the mint can't
|
|
69
|
+
// make). Pinned as a shared constant binding the SCHEMA boundary to the mint's codomain.
|
|
70
|
+
const AUTHORED_RULE_ID_HEX_LEN = 16;
|
|
71
|
+
const AUTHORED_RULE_ID_RE = new RegExp(`^[0-9a-f]{${AUTHORED_RULE_ID_HEX_LEN}}(?:-[1-9]\\d*)?$`);
|
|
72
|
+
/**
|
|
73
|
+
* ADR-112 §3 — the authored producer's sole output envelope. Parallel to
|
|
74
|
+
* ADR-111's `CandidateRuleRecord` but carrying the AUTHORED provenance variant,
|
|
75
|
+
* the INDEPENDENTLY-judged eligibility result, and the accelerant lineage.
|
|
76
|
+
* Minted `unverified: true` (ADR-089) — zero enforcement blast radius.
|
|
77
|
+
*/
|
|
78
|
+
export const AuthoredRuleRecordSchema = z.object({
|
|
79
|
+
/**
|
|
80
|
+
* ADR-112 §3/§8 — the stable, minted rule identity (`mintAuthoredRuleId`),
|
|
81
|
+
* assigned ONCE at authoring time and PERSISTED on the record; NEVER re-derived
|
|
82
|
+
* from content at read time. `firingLabelId` + the §5.3
|
|
83
|
+
* `controls.positive[].targetRuleId` ground-truth labels embed it, so a
|
|
84
|
+
* content-re-derived id would orphan them (§8). Slice A reserves the field (this
|
|
85
|
+
* IS the schema spine); the authoring flow (slice B) mints it, and threading it
|
|
86
|
+
* into the compiled artifact's identity (`firingLabelId ← ruleId`, replacing the
|
|
87
|
+
* `dslSource`-derived `lessonHash`) is slice C/D. The RESOLVED id (with any `-N`
|
|
88
|
+
* collision suffix) is what is stored.
|
|
89
|
+
*/
|
|
90
|
+
ruleId: z.string().regex(AUTHORED_RULE_ID_RE, {
|
|
91
|
+
message: 'ruleId must be a minted authored rule id — 16 hex chars + optional -<n> suffix (ADR-112 §3/§8)',
|
|
92
|
+
}),
|
|
93
|
+
provenance: AuthoredProvenanceRecordSchema,
|
|
94
|
+
/** INDEPENDENTLY established (§3) — the author never sets this; the check does. */
|
|
95
|
+
structuralEligibility: StructEligResultSchema,
|
|
96
|
+
origin: AuthoredOriginSchema,
|
|
97
|
+
declaredEngine: DeclaredEngineSchema,
|
|
98
|
+
/** Reference to the §8 authoring-ledger entry (author/date/engine/splitRef/attestations). */
|
|
99
|
+
authoringLedgerRef: z.string().refine((s) => s.trim().length > 0, {
|
|
100
|
+
message: 'authoringLedgerRef must be a non-empty ledger reference',
|
|
101
|
+
}),
|
|
102
|
+
/** The human-written matcher (same DSL the compiler accepts from the miner). */
|
|
103
|
+
dslSource: z.string().refine((s) => s.trim().length > 0, {
|
|
104
|
+
message: 'dslSource must be non-empty',
|
|
105
|
+
}),
|
|
106
|
+
/** Zero-trust mint (ADR-089 / ADR-112 §1) — always literally `true`. */
|
|
107
|
+
unverified: z.literal(true),
|
|
108
|
+
});
|
|
109
|
+
// ── SLICE B — the authoring INTAKE schema (ADR-112 §3/§8, FM(d)) ──────────────
|
|
110
|
+
//
|
|
111
|
+
// `AuthoredRuleInput` is the STRICT shape a human may supply in
|
|
112
|
+
// `.totem/spine/authored-rules.yaml`. It is DELIBERATELY distinct from
|
|
113
|
+
// `AuthoredRuleRecord`: the author sets ONLY the fields they legitimately own —
|
|
114
|
+
// the matcher, the declared engine + claimed structural class, the defect
|
|
115
|
+
// anchor, the fixtures, the accelerant origin. Every PRODUCER-owned field is
|
|
116
|
+
// REJECTED at parse (`.strict()` ⇒ unknown keys fail), so an author cannot
|
|
117
|
+
// hand-edit the YAML to inject a `structuralEligibility` / `decidable` / `ruleId`
|
|
118
|
+
// / `disposition` / `judgedBy` verdict — those keys are simply not expressible.
|
|
119
|
+
// The reader (slice B, CLI) re-runs `evaluateStructuralEligibility` over the DI
|
|
120
|
+
// whitelist and mints/upserts the id ITSELF; the author's `structuralClass` is a
|
|
121
|
+
// CLAIM that the independent check decides, never a self-certification (FM(d) /
|
|
122
|
+
// the greptile-#3 trust boundary). A file that already looks like an
|
|
123
|
+
// `AuthoredRuleRecord[]` (carrying `structuralEligibility`/`ruleId`/…) therefore
|
|
124
|
+
// fails the read as the WRONG SHAPE — it is never accepted as an "advanced" form.
|
|
125
|
+
//
|
|
126
|
+
// Identity/metadata strings are `.transform(trim)` BEFORE the refine (GCA-high
|
|
127
|
+
// diff-review): a non-mutating `.refine` would let `"alice "` (trailing space)
|
|
128
|
+
// bypass the `judgedBy !== author` independence check and mint a DIFFERENT ruleId
|
|
129
|
+
// for a semantically-identical input. `dslSource` is the one string NOT trimmed —
|
|
130
|
+
// trimming a matcher could change its meaning (leading/trailing pattern chars).
|
|
131
|
+
export const AuthoredRuleInputSchema = z
|
|
132
|
+
.object({
|
|
133
|
+
/** Agent-id or operator handle — attributable (mirrors the provenance field). Trimmed. */
|
|
134
|
+
author: z
|
|
135
|
+
.string()
|
|
136
|
+
.transform((s) => s.trim())
|
|
137
|
+
.refine((s) => s.length > 0, { message: 'author must be a non-empty, attributable handle' }),
|
|
138
|
+
/**
|
|
139
|
+
* ISO-8601 authoring date — trimmed + calendar-validated at the INTAKE boundary
|
|
140
|
+
* (CR diff-review): the same `isIso8601CalendarDate` the record provenance uses,
|
|
141
|
+
* so a malformed `not-a-date` fails here with a clean `CONFIG_INVALID` instead of
|
|
142
|
+
* escaping to a raw ZodError at record construction (pass 1).
|
|
143
|
+
*/
|
|
144
|
+
authoredAt: z
|
|
145
|
+
.string()
|
|
146
|
+
.transform((s) => s.trim())
|
|
147
|
+
.refine(isIso8601CalendarDate, {
|
|
148
|
+
message: 'authoredAt must be a valid ISO-8601 calendar date (YYYY-MM-DD or a full timestamp)',
|
|
149
|
+
}),
|
|
150
|
+
/** The declared DEFECT the rule targets — the pre-image, not its fix (ADR-110 §4 TP-def). Trimmed. */
|
|
151
|
+
targetDefect: z
|
|
152
|
+
.string()
|
|
153
|
+
.transform((s) => s.trim())
|
|
154
|
+
.refine((s) => s.length > 0, {
|
|
155
|
+
message: 'targetDefect must be a non-empty defect description',
|
|
156
|
+
}),
|
|
157
|
+
/** The matcher engine the author declares; the eligibility check confirms it can represent the class. */
|
|
158
|
+
declaredEngine: DeclaredEngineSchema,
|
|
159
|
+
/**
|
|
160
|
+
* The structural rule-CLASS the author CLAIMS. Fed to the INDEPENDENT
|
|
161
|
+
* `evaluateStructuralEligibility` against the DI whitelist; it is NOT stored
|
|
162
|
+
* verbatim on the record — the *verdict* (`structuralEligibility`, basis
|
|
163
|
+
* `whitelist:<class>`) is. Naming a class is a claim the check adjudicates,
|
|
164
|
+
* never a self-certification of `decidable`. Trimmed so a stray space can't
|
|
165
|
+
* cause an exact-match miss against the registry.
|
|
166
|
+
*/
|
|
167
|
+
structuralClass: z
|
|
168
|
+
.string()
|
|
169
|
+
.transform((s) => s.trim())
|
|
170
|
+
.refine((s) => s.length > 0, {
|
|
171
|
+
message: 'structuralClass must be a non-empty rule-class for the whitelist to decide',
|
|
172
|
+
}),
|
|
173
|
+
/** The human-written matcher (same DSL the compiler accepts from the miner). */
|
|
174
|
+
dslSource: z.string().refine((s) => s.trim().length > 0, {
|
|
175
|
+
message: 'dslSource must be non-empty',
|
|
176
|
+
}),
|
|
177
|
+
/** ≥1 real lc instance the rule claims to catch — ALL train-side (§5). */
|
|
178
|
+
positiveFixtures: z.array(AuthoredFixtureSchema).min(1, {
|
|
179
|
+
message: 'an authored rule must declare ≥1 positive fixture (ADR-112 §3)',
|
|
180
|
+
}),
|
|
181
|
+
/** Declared near-misses the rule must stay silent on (feeds §6 negative controls). */
|
|
182
|
+
negativeFixtures: z.array(AuthoredFixtureSchema).optional(),
|
|
183
|
+
/**
|
|
184
|
+
* Accelerant lineage (§7). Optional in the YAML; the reader defaults an
|
|
185
|
+
* absent value to `{ kind: 'from-scratch' }` when constructing the record, so
|
|
186
|
+
* the persisted `origin` is always explicit (§7 lineage is never erased).
|
|
187
|
+
*/
|
|
188
|
+
origin: AuthoredOriginSchema.optional(),
|
|
189
|
+
})
|
|
190
|
+
.strict();
|
|
191
|
+
/**
|
|
192
|
+
* SLICE B — the on-disk shape of `.totem/spine/authored-rules.yaml`. A file-level
|
|
193
|
+
* authoring header carries the §5/§8 leakage-guard ATTESTATIONS once for the
|
|
194
|
+
* session (not per-rule, since all rules in one file are authored under one
|
|
195
|
+
* frozen split), followed by the rules. Slice B RECORDS these faithfully into the
|
|
196
|
+
* authoring-ledger (strategy's boundary confirm: B records `splitRef` /
|
|
197
|
+
* `authoredAfterSplit` / `fixturePrs`); the MECHANICAL verification — the split
|
|
198
|
+
* was frozen BEFORE authoring (§5.1/FM(g)), fixtures resolve train-side (§5.2),
|
|
199
|
+
* the harness is sandboxed (§5.4) — is the cert-run harness in SLICE C. The
|
|
200
|
+
* attestations are `literal(true)`: an author who cannot attest them is not
|
|
201
|
+
* authoring legitimately, so a `false` fails the read rather than recording a
|
|
202
|
+
* self-defeating attestation. `.strict()` rejects unknown header keys.
|
|
203
|
+
*/
|
|
204
|
+
export const AuthoredRulesFileSchema = z
|
|
205
|
+
.object({
|
|
206
|
+
/** The frozen split (ADR-110 §6) the rules were authored under (recorded; verified in C). Trimmed (GCA) so stray whitespace can't bypass the non-empty check or perturb the revision fingerprint. */
|
|
207
|
+
splitRef: z
|
|
208
|
+
.string()
|
|
209
|
+
.transform((s) => s.trim())
|
|
210
|
+
.refine((s) => s.length > 0, {
|
|
211
|
+
message: 'splitRef must name the frozen split the rules were authored under (ADR-112 §5.1)',
|
|
212
|
+
}),
|
|
213
|
+
/** §1(g) embargo attestation — authored AFTER the split was frozen. Always `true`; verified in C. */
|
|
214
|
+
authoredAfterSplit: z.literal(true),
|
|
215
|
+
/** §5 attestation — the author did not inspect the held-out slice. Always `true`; sandboxed in C. */
|
|
216
|
+
heldOutNonInspectionAttestation: z.literal(true),
|
|
217
|
+
/** The authored rules (≥1). */
|
|
218
|
+
rules: z.array(AuthoredRuleInputSchema).min(1, {
|
|
219
|
+
message: 'authored-rules.yaml must declare ≥1 rule',
|
|
220
|
+
}),
|
|
221
|
+
})
|
|
222
|
+
.strict();
|
|
223
|
+
/**
|
|
224
|
+
* ADR-112 §3 — the INDEPENDENT structural-eligibility check. A CLOSED registry
|
|
225
|
+
* predicate, NOT prose: `decidable` is true iff EXACTLY ONE whitelist entry
|
|
226
|
+
* matches `(declaredEngine, structuralClass)`. Unknown class, unsupported
|
|
227
|
+
* engine, or multiple matches → `decidable: false` (NO default-to-structural).
|
|
228
|
+
* The author supplies `declaredEngine` + `structuralClass`; this check OWNS the
|
|
229
|
+
* verdict — any author-supplied disposition is irrelevant here (FM(d)).
|
|
230
|
+
* Deterministic + pure (no IO, no LLM) — the same input always yields the same
|
|
231
|
+
* verdict (Tenet-15).
|
|
232
|
+
*/
|
|
233
|
+
export function evaluateStructuralEligibility(input, whitelist, judgedBy) {
|
|
234
|
+
const matches = whitelist.filter((e) => e.engine === input.declaredEngine && e.structuralClass === input.structuralClass);
|
|
235
|
+
return {
|
|
236
|
+
decidable: matches.length === 1,
|
|
237
|
+
basis: `whitelist:${input.structuralClass}`,
|
|
238
|
+
judgedBy,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// ── Stable rule-id mint (ADR-112 §8) ──────────────────────────────────────────
|
|
242
|
+
/**
|
|
243
|
+
* ADR-112 §8 — mint a stable, deterministic authored rule-id. The seed is
|
|
244
|
+
* `sha256(JSON.stringify([author, targetDefect]))[:16]` (an INJECTIVE encoding —
|
|
245
|
+
* see the inline note) — `dslSource` is DELIBERATELY EXCLUDED so an author can
|
|
246
|
+
* tighten/refactor the matcher without orphaning the rule's ledger history. On collision with an already-resolved id (two rules sharing the same
|
|
247
|
+
* `(author, targetDefect)`), a stable `-N` counter is appended. The RESOLVED id
|
|
248
|
+
* is what callers persist — never recompute the raw seed at read time, or a
|
|
249
|
+
* later sibling could shift the suffix (the gemini/agy break). The
|
|
250
|
+
* `never-remine` marker is keyed to `targetDefect`, handled by the accelerant
|
|
251
|
+
* miner, not here.
|
|
252
|
+
*/
|
|
253
|
+
export function mintAuthoredRuleId(author, targetDefect, existingIds) {
|
|
254
|
+
// Unambiguous seed encoding (GCA-high + CR-major, #2259): a bare `author·targetDefect`
|
|
255
|
+
// ALIASES distinct tuples — ('a·b','c') and ('a','b·c') collapse onto one seed. A JSON
|
|
256
|
+
// array of the two inputs is injective: distinct (author, targetDefect) pairs can never
|
|
257
|
+
// serialize to the same string, so a persisted id can't collide by encoding.
|
|
258
|
+
const seed = createHash('sha256')
|
|
259
|
+
.update(JSON.stringify([author, targetDefect]))
|
|
260
|
+
.digest('hex')
|
|
261
|
+
.slice(0, AUTHORED_RULE_ID_HEX_LEN);
|
|
262
|
+
if (!existingIds.has(seed))
|
|
263
|
+
return seed;
|
|
264
|
+
for (let n = 1;; n += 1) {
|
|
265
|
+
const candidate = `${seed}-${n}`;
|
|
266
|
+
if (!existingIds.has(candidate))
|
|
267
|
+
return candidate;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* ADR-112 §2/§8 — turn structurally-DECIDABLE authored rules into the input
|
|
272
|
+
* `runCompileStage` consumes, reusing the ONE G-series compiler (never a second).
|
|
273
|
+
* The disposition is set HERE to `'structural'` from the INDEPENDENT eligibility
|
|
274
|
+
* verdict (§3) — the author never sets it. A NON-decidable record is a contract
|
|
275
|
+
* violation → FAIL LOUD (the FM(d) backstop in code), never a silent skip.
|
|
276
|
+
* `classifierLedgerRef = authored:<authoringLedgerRef>` is unique per rule (the
|
|
277
|
+
* authoring ledger is 1:1 with the rule); a duplicate fails loud so the downstream
|
|
278
|
+
* 1:1 classifier-ledger join can't silently collapse.
|
|
279
|
+
*/
|
|
280
|
+
export function toCompileFeed(records) {
|
|
281
|
+
const candidates = [];
|
|
282
|
+
const entries = [];
|
|
283
|
+
const seen = new Set();
|
|
284
|
+
for (const record of records) {
|
|
285
|
+
if (!record.structuralEligibility.decidable) {
|
|
286
|
+
throw new Error(`[Totem Error] toCompileFeed: authored rule '${record.authoringLedgerRef}' is not structurally decidable — a non-decidable rule must never reach the compiler (ADR-112 §3 / FM(d))`);
|
|
287
|
+
}
|
|
288
|
+
const classifierLedgerRef = `authored:${record.authoringLedgerRef}`;
|
|
289
|
+
if (seen.has(classifierLedgerRef)) {
|
|
290
|
+
throw new Error(`[Totem Error] toCompileFeed: duplicate authoringLedgerRef '${record.authoringLedgerRef}' — each authored rule needs a unique ledger ref for the 1:1 compile join`);
|
|
291
|
+
}
|
|
292
|
+
seen.add(classifierLedgerRef);
|
|
293
|
+
candidates.push({
|
|
294
|
+
provenance: record.provenance,
|
|
295
|
+
classifierDisposition: 'structural',
|
|
296
|
+
classifierLedgerRef,
|
|
297
|
+
dslSource: record.dslSource,
|
|
298
|
+
// §3 (#7): carry the whitelist-judged engine so the compiler can assert it
|
|
299
|
+
// compiled under THAT engine — a regex-whitelisted rule whose dslSource parses
|
|
300
|
+
// as ast-grep must fail loud, not silently re-route to a different engine.
|
|
301
|
+
declaredEngine: record.declaredEngine,
|
|
302
|
+
unverified: true,
|
|
303
|
+
});
|
|
304
|
+
entries.push({
|
|
305
|
+
candidateRef: classifierLedgerRef,
|
|
306
|
+
disposition: 'structural',
|
|
307
|
+
stage4Confirmed: false,
|
|
308
|
+
dispositionSource: 'authored-whitelist',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return { candidates, classifierLedger: { entries } };
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=authored-rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authored-rule.js","sourceRoot":"","sources":["../../src/spine/authored-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authored-rule.test.d.ts","sourceRoot":"","sources":["../../src/spine/authored-rule.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { AuthoredRuleRecordSchema, evaluateStructuralEligibility, mintAuthoredRuleId, toCompileFeed, } from './authored-rule.js';
|
|
3
|
+
const WHITELIST = [
|
|
4
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
5
|
+
{ engine: 'ast-grep', structuralClass: 'divisor-le-zero' },
|
|
6
|
+
];
|
|
7
|
+
describe('evaluateStructuralEligibility (ADR-112 §3 — closed predicate)', () => {
|
|
8
|
+
it('decidable:true on EXACTLY ONE (engine,class) match', () => {
|
|
9
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'float-finite-assert' }, WHITELIST, 'static-whitelist@cert-1');
|
|
10
|
+
expect(r.decidable).toBe(true);
|
|
11
|
+
expect(r.basis).toBe('whitelist:float-finite-assert');
|
|
12
|
+
expect(r.judgedBy).toBe('static-whitelist@cert-1');
|
|
13
|
+
});
|
|
14
|
+
it('decidable:false on an UNKNOWN class (no default-to-structural)', () => {
|
|
15
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'unbounded-recursion-behavioral' }, WHITELIST, 'static-whitelist@cert-1');
|
|
16
|
+
expect(r.decidable).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
it('decidable:false when the engine cannot represent the class (no matching pair)', () => {
|
|
19
|
+
// class is whitelisted for ast-grep, not regex → no (regex, divisor-le-zero) entry.
|
|
20
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1');
|
|
21
|
+
expect(r.decidable).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it('decidable:false on MULTIPLE matches (ambiguous)', () => {
|
|
24
|
+
const dupes = [
|
|
25
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
26
|
+
{ engine: 'regex', structuralClass: 'float-finite-assert' },
|
|
27
|
+
];
|
|
28
|
+
const r = evaluateStructuralEligibility({ declaredEngine: 'regex', structuralClass: 'float-finite-assert' }, dupes, 'static-whitelist@cert-1');
|
|
29
|
+
expect(r.decidable).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it('is deterministic — 100 sequential iterations yield an identical verdict (LLM-free)', () => {
|
|
32
|
+
const first = JSON.stringify(evaluateStructuralEligibility({ declaredEngine: 'ast-grep', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1'));
|
|
33
|
+
for (let i = 0; i < 100; i += 1) {
|
|
34
|
+
const again = JSON.stringify(evaluateStructuralEligibility({ declaredEngine: 'ast-grep', structuralClass: 'divisor-le-zero' }, WHITELIST, 'static-whitelist@cert-1'));
|
|
35
|
+
expect(again).toBe(first);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('AuthoredRuleRecord schema (ADR-112 §3)', () => {
|
|
40
|
+
const base = {
|
|
41
|
+
ruleId: '0f1e2d3c4b5a6978',
|
|
42
|
+
provenance: {
|
|
43
|
+
kind: 'authored',
|
|
44
|
+
author: 'totem-claude',
|
|
45
|
+
authoredAt: '2026-06-27',
|
|
46
|
+
targetDefect: 'float equality compared with == instead of a finite-tolerance check',
|
|
47
|
+
positiveFixtures: [
|
|
48
|
+
{
|
|
49
|
+
pr: 100,
|
|
50
|
+
preimageSource: {
|
|
51
|
+
kind: 'commit',
|
|
52
|
+
preimageCommitSha: 'c'.repeat(40),
|
|
53
|
+
mergeCommitSha: 'b'.repeat(40),
|
|
54
|
+
},
|
|
55
|
+
filePath: 'src/physics/step.ts',
|
|
56
|
+
matchedSpan: 'L10-L12',
|
|
57
|
+
contentHash: 'deadbeefcafe',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
structuralEligibility: {
|
|
62
|
+
decidable: true,
|
|
63
|
+
basis: 'whitelist:float-finite-assert',
|
|
64
|
+
judgedBy: 's',
|
|
65
|
+
},
|
|
66
|
+
origin: { kind: 'from-scratch' },
|
|
67
|
+
declaredEngine: 'regex',
|
|
68
|
+
authoringLedgerRef: 'alr-0001',
|
|
69
|
+
dslSource: '**Pattern:** `== *\\d+\\.\\d+f?`',
|
|
70
|
+
unverified: true,
|
|
71
|
+
};
|
|
72
|
+
it('accepts a complete authored record', () => {
|
|
73
|
+
expect(() => AuthoredRuleRecordSchema.parse(base)).not.toThrow();
|
|
74
|
+
});
|
|
75
|
+
it('has NO author-settable disposition/routing field (the check owns eligibility — FM(d))', () => {
|
|
76
|
+
const parsed = AuthoredRuleRecordSchema.parse(base);
|
|
77
|
+
expect('classifierDisposition' in parsed).toBe(false);
|
|
78
|
+
expect('routing' in parsed).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
it('requires the independent structuralEligibility result', () => {
|
|
81
|
+
const { structuralEligibility: _omit, ...without } = base;
|
|
82
|
+
expect(() => AuthoredRuleRecordSchema.parse(without)).toThrow();
|
|
83
|
+
});
|
|
84
|
+
it('reserves the minted ruleId on the record (ADR-112 §3/§8 — persisted, never re-derived)', () => {
|
|
85
|
+
const { ruleId: _omit, ...without } = base;
|
|
86
|
+
expect(() => AuthoredRuleRecordSchema.parse(without)).toThrow();
|
|
87
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: ' ' })).toThrow();
|
|
88
|
+
expect(AuthoredRuleRecordSchema.parse(base).ruleId).toBe('0f1e2d3c4b5a6978');
|
|
89
|
+
});
|
|
90
|
+
it('enforces the minted ruleId SHAPE at the boundary — 16 hex + optional -<n> (#2259 CR-major)', () => {
|
|
91
|
+
for (const bad of [
|
|
92
|
+
'NOTHEXNOTHEXNOTH',
|
|
93
|
+
'0f1e2d3c',
|
|
94
|
+
'0f1e2d3c4b5a6978abcd',
|
|
95
|
+
'0F1E2D3C4B5A6978',
|
|
96
|
+
'rid-alr-1',
|
|
97
|
+
// non-canonical suffixes the mint never emits (n≥1, no zero-pad) — #2259 CR
|
|
98
|
+
'0f1e2d3c4b5a6978-0',
|
|
99
|
+
'0f1e2d3c4b5a6978-01',
|
|
100
|
+
]) {
|
|
101
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: bad })).toThrow();
|
|
102
|
+
}
|
|
103
|
+
for (const ok of ['0f1e2d3c4b5a6978', '0f1e2d3c4b5a6978-1', 'abcdef0123456789-42']) {
|
|
104
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, ruleId: ok })).not.toThrow();
|
|
105
|
+
}
|
|
106
|
+
// the mint always produces a schema-valid id (the shared shape constant binds both).
|
|
107
|
+
expect(() => AuthoredRuleRecordSchema.parse({
|
|
108
|
+
...base,
|
|
109
|
+
ruleId: mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set()),
|
|
110
|
+
})).not.toThrow();
|
|
111
|
+
});
|
|
112
|
+
it('forces unverified:true (zero blast radius — ADR-089/§1)', () => {
|
|
113
|
+
expect(() => AuthoredRuleRecordSchema.parse({ ...base, unverified: false })).toThrow();
|
|
114
|
+
});
|
|
115
|
+
it('constrains structuralEligibility.basis to the §3 forms — not free-form (strategy item 2, #2259)', () => {
|
|
116
|
+
const withBasis = (basis) => ({
|
|
117
|
+
...base,
|
|
118
|
+
structuralEligibility: { ...base.structuralEligibility, basis },
|
|
119
|
+
});
|
|
120
|
+
for (const bad of [
|
|
121
|
+
'',
|
|
122
|
+
'freeform',
|
|
123
|
+
'whitelist:',
|
|
124
|
+
'whitelisted',
|
|
125
|
+
'stage4',
|
|
126
|
+
' capability-check',
|
|
127
|
+
]) {
|
|
128
|
+
expect(() => AuthoredRuleRecordSchema.parse(withBasis(bad))).toThrow();
|
|
129
|
+
}
|
|
130
|
+
for (const ok of [
|
|
131
|
+
'whitelist:float-finite-assert',
|
|
132
|
+
'capability-check',
|
|
133
|
+
'draft-classifier+stage4',
|
|
134
|
+
]) {
|
|
135
|
+
expect(() => AuthoredRuleRecordSchema.parse(withBasis(ok))).not.toThrow();
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
describe('mintAuthoredRuleId (ADR-112 §8)', () => {
|
|
140
|
+
it('is deterministic for the same (author,targetDefect) and excludes dslSource', () => {
|
|
141
|
+
const a = mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set());
|
|
142
|
+
const b = mintAuthoredRuleId('totem-claude', 'float-finite-assert', new Set());
|
|
143
|
+
expect(a).toBe(b);
|
|
144
|
+
expect(a).toMatch(/^[0-9a-f]{16}$/);
|
|
145
|
+
});
|
|
146
|
+
it('encodes (author,targetDefect) injectively — delimiter-aliased tuples do NOT collide (#2259)', () => {
|
|
147
|
+
// A bare `author·targetDefect` seed would alias these two distinct tuples onto one id.
|
|
148
|
+
const a = mintAuthoredRuleId('a·b', 'c', new Set());
|
|
149
|
+
const b = mintAuthoredRuleId('a', 'b·c', new Set());
|
|
150
|
+
expect(a).not.toBe(b);
|
|
151
|
+
});
|
|
152
|
+
it('appends a stable counter on collision and yields distinct persisted ids', () => {
|
|
153
|
+
const first = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set());
|
|
154
|
+
const second = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set([first]));
|
|
155
|
+
const third = mintAuthoredRuleId('totem-claude', 'divisor-le-zero', new Set([first, second]));
|
|
156
|
+
expect(second).toBe(`${first}-1`);
|
|
157
|
+
expect(third).toBe(`${first}-2`);
|
|
158
|
+
expect(new Set([first, second, third]).size).toBe(3);
|
|
159
|
+
});
|
|
160
|
+
it('is stable across re-runs given the already-resolved id set', () => {
|
|
161
|
+
const resolved = mintAuthoredRuleId('a', 'd', new Set());
|
|
162
|
+
expect(mintAuthoredRuleId('a', 'd', new Set([resolved]))).toBe(`${resolved}-1`);
|
|
163
|
+
expect(mintAuthoredRuleId('a', 'd', new Set([resolved]))).toBe(`${resolved}-1`);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('toCompileFeed (ADR-112 §2/§8 — authored → compile-stage input)', () => {
|
|
167
|
+
const decidable = (ref) => ({
|
|
168
|
+
ruleId: mintAuthoredRuleId('totem-claude', ref, new Set()),
|
|
169
|
+
provenance: {
|
|
170
|
+
kind: 'authored',
|
|
171
|
+
author: 'totem-claude',
|
|
172
|
+
authoredAt: '2026-06-27',
|
|
173
|
+
targetDefect: 'float equality compared with == instead of a finite check',
|
|
174
|
+
positiveFixtures: [
|
|
175
|
+
{
|
|
176
|
+
pr: 1,
|
|
177
|
+
preimageSource: {
|
|
178
|
+
kind: 'commit',
|
|
179
|
+
preimageCommitSha: 'b'.repeat(40),
|
|
180
|
+
mergeCommitSha: 'a'.repeat(40),
|
|
181
|
+
},
|
|
182
|
+
filePath: 'src/a.ts',
|
|
183
|
+
matchedSpan: 'L1',
|
|
184
|
+
contentHash: 'h1',
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
structuralEligibility: {
|
|
189
|
+
decidable: true,
|
|
190
|
+
basis: 'whitelist:float-finite-assert',
|
|
191
|
+
judgedBy: 's',
|
|
192
|
+
},
|
|
193
|
+
origin: { kind: 'from-scratch' },
|
|
194
|
+
declaredEngine: 'regex',
|
|
195
|
+
authoringLedgerRef: ref,
|
|
196
|
+
dslSource: '**Pattern:** `== *\\d`',
|
|
197
|
+
unverified: true,
|
|
198
|
+
});
|
|
199
|
+
it('emits one structural candidate + a 1:1 authored-whitelist ledger entry per decidable rule', () => {
|
|
200
|
+
const feed = toCompileFeed([decidable('alr-1'), decidable('alr-2')]);
|
|
201
|
+
expect(feed.candidates).toHaveLength(2);
|
|
202
|
+
// the adapter — not the author — sets the disposition to structural.
|
|
203
|
+
expect(feed.candidates.every((c) => c.classifierDisposition === 'structural')).toBe(true);
|
|
204
|
+
// authored provenance is carried through, not flattened to a mined shape.
|
|
205
|
+
expect(feed.candidates[0].provenance.kind).toBe('authored');
|
|
206
|
+
expect(feed.candidates.map((c) => c.classifierLedgerRef)).toEqual([
|
|
207
|
+
'authored:alr-1',
|
|
208
|
+
'authored:alr-2',
|
|
209
|
+
]);
|
|
210
|
+
// the classifier ledger NEVER claims an LLM judged a human rule (Tenet-20).
|
|
211
|
+
expect(feed.classifierLedger.entries.every((e) => e.dispositionSource === 'authored-whitelist')).toBe(true);
|
|
212
|
+
// the join key is 1:1 between candidate and ledger entry (runCompileStage requires it).
|
|
213
|
+
expect(feed.classifierLedger.entries.map((e) => e.candidateRef)).toEqual(feed.candidates.map((c) => c.classifierLedgerRef));
|
|
214
|
+
});
|
|
215
|
+
it('FAILS LOUD on a non-decidable record (FM(d) — never reaches the compiler)', () => {
|
|
216
|
+
const nd = {
|
|
217
|
+
...decidable('alr-x'),
|
|
218
|
+
structuralEligibility: { decidable: false, basis: 'whitelist:foo', judgedBy: 's' },
|
|
219
|
+
};
|
|
220
|
+
expect(() => toCompileFeed([nd])).toThrow(/not structurally decidable/);
|
|
221
|
+
});
|
|
222
|
+
it('FAILS LOUD on a duplicate authoringLedgerRef (protects the 1:1 compile join)', () => {
|
|
223
|
+
expect(() => toCompileFeed([decidable('dup'), decidable('dup')])).toThrow(/duplicate authoringLedgerRef/);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
//# sourceMappingURL=authored-rule.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authored-rule.test.js","sourceRoot":"","sources":["../../src/spine/authored-rule.test.ts"],"names":[],"mappings":"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"}
|