@oscharko-dev/keiko-evidence 0.2.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/.tsbuildinfo +1 -0
- package/dist/aggregate.d.ts +4 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +21 -0
- package/dist/build.d.ts +3 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +227 -0
- package/dist/connected-context-evidence.d.ts +47 -0
- package/dist/connected-context-evidence.d.ts.map +1 -0
- package/dist/connected-context-evidence.js +197 -0
- package/dist/errors.d.ts +3 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +4 -0
- package/dist/index-api.d.ts +15 -0
- package/dist/index-api.d.ts.map +1 -0
- package/dist/index-api.js +136 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/persist.d.ts +9 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +40 -0
- package/dist/promptEnhancement/index.d.ts +7 -0
- package/dist/promptEnhancement/index.d.ts.map +1 -0
- package/dist/promptEnhancement/index.js +10 -0
- package/dist/promptEnhancement/manifestSchema.d.ts +71 -0
- package/dist/promptEnhancement/manifestSchema.d.ts.map +1 -0
- package/dist/promptEnhancement/manifestSchema.js +307 -0
- package/dist/promptEnhancement/redaction.d.ts +17 -0
- package/dist/promptEnhancement/redaction.d.ts.map +1 -0
- package/dist/promptEnhancement/redaction.js +66 -0
- package/dist/promptEnhancement/store.d.ts +64 -0
- package/dist/promptEnhancement/store.d.ts.map +1 -0
- package/dist/promptEnhancement/store.js +409 -0
- package/dist/qualityIntelligence/candidatesArtifact.d.ts +74 -0
- package/dist/qualityIntelligence/candidatesArtifact.d.ts.map +1 -0
- package/dist/qualityIntelligence/candidatesArtifact.js +258 -0
- package/dist/qualityIntelligence/companionStore.d.ts +37 -0
- package/dist/qualityIntelligence/companionStore.d.ts.map +1 -0
- package/dist/qualityIntelligence/companionStore.js +158 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.d.ts +123 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshot/schema.js +163 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.d.ts +144 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshot/store.js +898 -0
- package/dist/qualityIntelligence/index.d.ts +18 -0
- package/dist/qualityIntelligence/index.d.ts.map +1 -0
- package/dist/qualityIntelligence/index.js +21 -0
- package/dist/qualityIntelligence/manifestSchema.d.ts +154 -0
- package/dist/qualityIntelligence/manifestSchema.d.ts.map +1 -0
- package/dist/qualityIntelligence/manifestSchema.js +70 -0
- package/dist/qualityIntelligence/redaction.d.ts +10 -0
- package/dist/qualityIntelligence/redaction.d.ts.map +1 -0
- package/dist/qualityIntelligence/redaction.js +103 -0
- package/dist/qualityIntelligence/retention.d.ts +71 -0
- package/dist/qualityIntelligence/retention.d.ts.map +1 -0
- package/dist/qualityIntelligence/retention.js +287 -0
- package/dist/qualityIntelligence/retentionPolicy.d.ts +10 -0
- package/dist/qualityIntelligence/retentionPolicy.d.ts.map +1 -0
- package/dist/qualityIntelligence/retentionPolicy.js +38 -0
- package/dist/qualityIntelligence/store.d.ts +95 -0
- package/dist/qualityIntelligence/store.d.ts.map +1 -0
- package/dist/qualityIntelligence/store.js +483 -0
- package/dist/redaction.d.ts +2 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +4 -0
- package/dist/report.d.ts +17 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +50 -0
- package/dist/retention.d.ts +4 -0
- package/dist/retention.d.ts.map +1 -0
- package/dist/retention.js +95 -0
- package/dist/runid.d.ts +2 -0
- package/dist/runid.d.ts.map +1 -0
- package/dist/runid.js +4 -0
- package/dist/side-file.d.ts +9 -0
- package/dist/side-file.d.ts.map +1 -0
- package/dist/side-file.js +102 -0
- package/dist/store.d.ts +8 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +332 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +1 -0
- package/dist/workflow-evidence.d.ts +36 -0
- package/dist/workflow-evidence.d.ts.map +1 -0
- package/dist/workflow-evidence.js +158 -0
- package/package.json +32 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Persisted Figma Snapshot evidence record (Epic #750, Issue #753, ADR-0023 evidence discipline).
|
|
2
|
+
//
|
|
3
|
+
// The immutable, redaction-safe on-disk shape of a Figma Snapshot. It mirrors the QI evidence
|
|
4
|
+
// manifest posture: a breaking change introduces a NEW `figmaSnapshotSchemaVersion` literal rather
|
|
5
|
+
// than mutating this one; every string leaf has passed through redaction before persist; NO token,
|
|
6
|
+
// NO secret, NO outbound Figma/render URL, NO header reaches this shape.
|
|
7
|
+
//
|
|
8
|
+
// The rendered PNG bytes do NOT live inline — they are written as binary side-files and referenced
|
|
9
|
+
// here by relative path + sha256 (the same tamper-evidence pattern as ADR-0017 side-files). The
|
|
10
|
+
// integrity hashes follow the server builder's deterministic hash projection but are recomputed by
|
|
11
|
+
// the evidence store after redaction so they describe the exact persisted artifact. A loaded record
|
|
12
|
+
// can then be drift-checked against #735. Optional #752 metadata (`links`, `tokens`) keeps separate
|
|
13
|
+
// artifact hashes: they are not drift identity, but downstream consumers must not trust a tampered
|
|
14
|
+
// artifact under an otherwise-valid drift hash.
|
|
15
|
+
//
|
|
16
|
+
// `irJson` is the structural Screen-IR (#752) serialised as an opaque JSON value. It is design
|
|
17
|
+
// CONTENT — the artifact's purpose — and is kept (not redacted away); only secrets are stripped.
|
|
18
|
+
export const FIGMA_SNAPSHOT_SCHEMA_VERSION = 1;
|
|
19
|
+
const ALLOWED_TOP_LEVEL_KEYS = new Set([
|
|
20
|
+
"figmaSnapshotSchemaVersion",
|
|
21
|
+
"runId",
|
|
22
|
+
"provenance",
|
|
23
|
+
"screens",
|
|
24
|
+
"skippedScreens",
|
|
25
|
+
"structuralScreens",
|
|
26
|
+
"links",
|
|
27
|
+
"tokens",
|
|
28
|
+
"metrics",
|
|
29
|
+
"artifactHashes",
|
|
30
|
+
"integrityHash",
|
|
31
|
+
"redactionSummary",
|
|
32
|
+
]);
|
|
33
|
+
const ALLOWED_ARTIFACT_HASH_KEYS = new Set([
|
|
34
|
+
"links",
|
|
35
|
+
"tokens",
|
|
36
|
+
"metrics",
|
|
37
|
+
]);
|
|
38
|
+
const ALLOWED_METRICS_KEYS = new Set([
|
|
39
|
+
"reductionRatio",
|
|
40
|
+
"screenCount",
|
|
41
|
+
"renderCount",
|
|
42
|
+
"designTokenCount",
|
|
43
|
+
"augmentation",
|
|
44
|
+
"navGraph",
|
|
45
|
+
"a11y",
|
|
46
|
+
]);
|
|
47
|
+
const ALLOWED_AUGMENTATION_KEYS = new Set([
|
|
48
|
+
"deterministic",
|
|
49
|
+
"modelAugmented",
|
|
50
|
+
"modelAugmentedShare",
|
|
51
|
+
]);
|
|
52
|
+
const ALLOWED_NAV_GRAPH_KEYS = new Set(["screens", "transitions"]);
|
|
53
|
+
const ALLOWED_A11Y_KEYS = new Set(["findings"]);
|
|
54
|
+
const REQUIRED_METRIC_KEYS = [
|
|
55
|
+
"reductionRatio",
|
|
56
|
+
"screenCount",
|
|
57
|
+
"renderCount",
|
|
58
|
+
"designTokenCount",
|
|
59
|
+
];
|
|
60
|
+
function validateArtifactHashes(value) {
|
|
61
|
+
if (value === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
64
|
+
return { ok: false, reason: "artifactHashes must be an object" };
|
|
65
|
+
}
|
|
66
|
+
for (const key of Object.keys(value)) {
|
|
67
|
+
if (!ALLOWED_ARTIFACT_HASH_KEYS.has(key)) {
|
|
68
|
+
return { ok: false, reason: `unknown artifactHashes key: ${key}` };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
function finiteNumber(value) {
|
|
74
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
75
|
+
}
|
|
76
|
+
function keysAllowed(value, allowed) {
|
|
77
|
+
return Object.keys(value).every((key) => allowed.has(key));
|
|
78
|
+
}
|
|
79
|
+
function validateObjectNumbers(value, allowed, required, label) {
|
|
80
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
81
|
+
return { ok: false, reason: `${label} must be an object` };
|
|
82
|
+
}
|
|
83
|
+
const record = value;
|
|
84
|
+
if (!keysAllowed(record, allowed)) {
|
|
85
|
+
return { ok: false, reason: `${label} has unknown keys` };
|
|
86
|
+
}
|
|
87
|
+
for (const key of required) {
|
|
88
|
+
if (!finiteNumber(record[key]))
|
|
89
|
+
return { ok: false, reason: `${label}.${key} must be a number` };
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
function validateRequiredNumbers(record, keys, label) {
|
|
94
|
+
for (const key of keys) {
|
|
95
|
+
if (!finiteNumber(record[key]))
|
|
96
|
+
return { ok: false, reason: `${label}.${key} must be a number` };
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
function validateOptionalNumberObject(record, key, allowed, required) {
|
|
101
|
+
if (record[key] === undefined)
|
|
102
|
+
return undefined;
|
|
103
|
+
return validateObjectNumbers(record[key], allowed, required, `metrics.${key}`);
|
|
104
|
+
}
|
|
105
|
+
function validateMetrics(value) {
|
|
106
|
+
if (value === undefined)
|
|
107
|
+
return undefined;
|
|
108
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
109
|
+
return { ok: false, reason: "metrics must be an object" };
|
|
110
|
+
}
|
|
111
|
+
const metrics = value;
|
|
112
|
+
if (!keysAllowed(metrics, ALLOWED_METRICS_KEYS)) {
|
|
113
|
+
return { ok: false, reason: "metrics has unknown keys" };
|
|
114
|
+
}
|
|
115
|
+
const required = validateRequiredNumbers(metrics, REQUIRED_METRIC_KEYS, "metrics");
|
|
116
|
+
if (required !== undefined)
|
|
117
|
+
return required;
|
|
118
|
+
const aug = validateObjectNumbers(metrics.augmentation, ALLOWED_AUGMENTATION_KEYS, ["deterministic", "modelAugmented", "modelAugmentedShare"], "metrics.augmentation");
|
|
119
|
+
if (aug !== undefined)
|
|
120
|
+
return aug;
|
|
121
|
+
return (validateOptionalNumberObject(metrics, "navGraph", ALLOWED_NAV_GRAPH_KEYS, [
|
|
122
|
+
"screens",
|
|
123
|
+
"transitions",
|
|
124
|
+
]) ?? validateOptionalNumberObject(metrics, "a11y", ALLOWED_A11Y_KEYS, ["findings"]));
|
|
125
|
+
}
|
|
126
|
+
function validateScreenCollections(record) {
|
|
127
|
+
if (!Array.isArray(record.screens) || !Array.isArray(record.skippedScreens)) {
|
|
128
|
+
return { ok: false, reason: "screens and skippedScreens must be arrays" };
|
|
129
|
+
}
|
|
130
|
+
if (record.structuralScreens !== undefined && !Array.isArray(record.structuralScreens)) {
|
|
131
|
+
return { ok: false, reason: "structuralScreens must be an array" };
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
// Strict-schema gate for a deserialised snapshot record: schema-version literal + closed key set.
|
|
136
|
+
// Structural correctness of the integrity hashes is the builder's responsibility, not this gate's.
|
|
137
|
+
export function validateFigmaSnapshotRecord(value) {
|
|
138
|
+
if (typeof value !== "object" || value === null) {
|
|
139
|
+
return { ok: false, reason: "record is not an object" };
|
|
140
|
+
}
|
|
141
|
+
const record = value;
|
|
142
|
+
if (record.figmaSnapshotSchemaVersion !== FIGMA_SNAPSHOT_SCHEMA_VERSION) {
|
|
143
|
+
return {
|
|
144
|
+
ok: false,
|
|
145
|
+
reason: `unexpected figmaSnapshotSchemaVersion (expected ${String(FIGMA_SNAPSHOT_SCHEMA_VERSION)})`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
for (const key of Object.keys(record)) {
|
|
149
|
+
if (!ALLOWED_TOP_LEVEL_KEYS.has(key)) {
|
|
150
|
+
return { ok: false, reason: `unknown record key: ${key}` };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const screenCollectionsValidation = validateScreenCollections(record);
|
|
154
|
+
if (screenCollectionsValidation !== undefined)
|
|
155
|
+
return screenCollectionsValidation;
|
|
156
|
+
const artifactHashesValidation = validateArtifactHashes(record.artifactHashes);
|
|
157
|
+
if (artifactHashesValidation !== undefined)
|
|
158
|
+
return artifactHashesValidation;
|
|
159
|
+
const metricsValidation = validateMetrics(record.metrics);
|
|
160
|
+
if (metricsValidation !== undefined)
|
|
161
|
+
return metricsValidation;
|
|
162
|
+
return { ok: true, reason: undefined };
|
|
163
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type WorkspaceFs } from "@oscharko-dev/keiko-workspace";
|
|
2
|
+
import { type FigmaSnapshotImageRef, type FigmaSnapshotLinkRow, type FigmaSnapshotMetrics, type FigmaSnapshotRecord } from "./schema.js";
|
|
3
|
+
export interface RecordFigmaSnapshotScreenInput {
|
|
4
|
+
readonly screenId: string;
|
|
5
|
+
readonly irJson: unknown;
|
|
6
|
+
readonly integrityHash: string;
|
|
7
|
+
readonly image: {
|
|
8
|
+
readonly mimeType: "image/png";
|
|
9
|
+
readonly bytes: Uint8Array;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface RecordFigmaSnapshotStructuralScreenInput {
|
|
13
|
+
readonly screenId: string;
|
|
14
|
+
readonly reason: string;
|
|
15
|
+
readonly irJson: unknown;
|
|
16
|
+
readonly integrityHash: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RecordFigmaSnapshotInput {
|
|
19
|
+
readonly runId: string;
|
|
20
|
+
readonly provenance: {
|
|
21
|
+
readonly fileKey: string;
|
|
22
|
+
readonly nodeId: string;
|
|
23
|
+
readonly version: string | undefined;
|
|
24
|
+
readonly fetchedAt: string;
|
|
25
|
+
};
|
|
26
|
+
readonly integrityHash: string;
|
|
27
|
+
readonly screens: readonly RecordFigmaSnapshotScreenInput[];
|
|
28
|
+
/** Structural Screen-IR for skipped/non-rendered screens. Optional for callers predating this. */
|
|
29
|
+
readonly structuralScreens?: readonly RecordFigmaSnapshotStructuralScreenInput[];
|
|
30
|
+
readonly skippedScreens: readonly {
|
|
31
|
+
readonly screenId: string;
|
|
32
|
+
readonly reason: string;
|
|
33
|
+
}[];
|
|
34
|
+
/** Raw inter-screen transitions for the navigation/flow graph (#811). Optional + additive. */
|
|
35
|
+
readonly links?: readonly FigmaSnapshotLinkRow[];
|
|
36
|
+
/** Deterministic design-tokens artifact (#752), opaque, for design-to-code (#755). Optional. */
|
|
37
|
+
readonly tokens?: unknown;
|
|
38
|
+
/** Numeric operational metrics (#760). Optional for older snapshots. */
|
|
39
|
+
readonly metrics?: FigmaSnapshotMetrics;
|
|
40
|
+
}
|
|
41
|
+
export interface RecordFigmaSnapshotResult {
|
|
42
|
+
readonly recordPath: string;
|
|
43
|
+
readonly sideFileDir: string;
|
|
44
|
+
}
|
|
45
|
+
/** Summary entry returned by {@link FigmaSnapshotStore.listByScope}. */
|
|
46
|
+
export interface FigmaSnapshotScopeEntry {
|
|
47
|
+
readonly runId: string;
|
|
48
|
+
readonly fetchedAt: string;
|
|
49
|
+
readonly integrityHash: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mutable operator-facing management metadata for a write-once snapshot record.
|
|
53
|
+
*
|
|
54
|
+
* Stored separately from `<runId>.figma-snapshot.json` so a human rename never mutates the
|
|
55
|
+
* immutable evidence artifact or its integrity hash graph.
|
|
56
|
+
*/
|
|
57
|
+
export interface FigmaSnapshotUserMetadata {
|
|
58
|
+
readonly displayName?: string;
|
|
59
|
+
readonly updatedAt: string;
|
|
60
|
+
}
|
|
61
|
+
export interface UpdateFigmaSnapshotUserMetadataInput {
|
|
62
|
+
/** Empty string or null clears the display name. */
|
|
63
|
+
readonly displayName?: string | null | undefined;
|
|
64
|
+
/** Injectable for tests and audited routes; defaults to the current time. */
|
|
65
|
+
readonly updatedAt?: string | undefined;
|
|
66
|
+
}
|
|
67
|
+
export interface DeleteFigmaSnapshotResult {
|
|
68
|
+
readonly runId: string;
|
|
69
|
+
readonly recordDeleted: boolean;
|
|
70
|
+
readonly sideFileDirDeleted: boolean;
|
|
71
|
+
readonly metadataDeleted: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface FigmaSnapshotImageBytes {
|
|
74
|
+
readonly mimeType: "image/png";
|
|
75
|
+
readonly bytes: Uint8Array;
|
|
76
|
+
readonly sha256: string;
|
|
77
|
+
readonly byteLength: number;
|
|
78
|
+
}
|
|
79
|
+
export interface FigmaSnapshotStore {
|
|
80
|
+
readonly record: (input: RecordFigmaSnapshotInput) => RecordFigmaSnapshotResult;
|
|
81
|
+
readonly load: (runId: string) => FigmaSnapshotRecord | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Loads and verifies the JSON snapshot record and hash graph without reading every image side-file.
|
|
84
|
+
* Callers that stream one image must then verify that requested side-file with loadImage().
|
|
85
|
+
*/
|
|
86
|
+
readonly loadMetadata: (runId: string) => FigmaSnapshotRecord | undefined;
|
|
87
|
+
readonly loadImage: (runId: string, image: FigmaSnapshotImageRef) => FigmaSnapshotImageBytes;
|
|
88
|
+
/** Loads mutable user metadata without touching the immutable evidence record. */
|
|
89
|
+
readonly loadUserMetadata: (runId: string) => FigmaSnapshotUserMetadata | undefined;
|
|
90
|
+
/** Upserts mutable user metadata next to the immutable record. */
|
|
91
|
+
readonly updateUserMetadata: (runId: string, input: UpdateFigmaSnapshotUserMetadataInput) => FigmaSnapshotUserMetadata;
|
|
92
|
+
/** Deletes the immutable record, rendered side-files, and mutable management metadata together. */
|
|
93
|
+
readonly deleteSnapshot: (runId: string) => DeleteFigmaSnapshotResult;
|
|
94
|
+
readonly location: (runId: string) => string;
|
|
95
|
+
/**
|
|
96
|
+
* List all snapshot records for a specific Figma scope, sorted by `fetchedAt` descending
|
|
97
|
+
* (most-recent first). Reads only the record headers — cheap scan. Unparseable files are
|
|
98
|
+
* skipped silently. Used by drift work (#735) to find existing snapshots for re-comparison.
|
|
99
|
+
*/
|
|
100
|
+
readonly listByScope: (fileKey: string, nodeId: string) => readonly FigmaSnapshotScopeEntry[];
|
|
101
|
+
/**
|
|
102
|
+
* List the most recent snapshot run ids across all scopes, sorted by `fetchedAt` descending.
|
|
103
|
+
* Reads only the record headers and skips unparseable files silently.
|
|
104
|
+
*/
|
|
105
|
+
readonly listRecent: (limit?: number) => readonly string[];
|
|
106
|
+
}
|
|
107
|
+
export interface FigmaSnapshotStoreOptions {
|
|
108
|
+
readonly fs?: WorkspaceFs;
|
|
109
|
+
readonly randomSuffix?: () => string;
|
|
110
|
+
/**
|
|
111
|
+
* Count-based retention applied ONCE per store instance from the lazy sweep seam (Issue #1323
|
|
112
|
+
* AC4 — make retention operational). Figma snapshot records carry no retention policy id; they
|
|
113
|
+
* are evicted oldest-first by `fetchedAt` beyond `maxRecords`. Omitted → the conservative default
|
|
114
|
+
* cap ({@link DEFAULT_FIGMA_SNAPSHOT_MAX_RECORDS}) is used so a normal local set is never silently
|
|
115
|
+
* purged. A non-positive `maxRecords` disables retention entirely.
|
|
116
|
+
*/
|
|
117
|
+
readonly retention?: {
|
|
118
|
+
readonly maxRecords?: number;
|
|
119
|
+
} | undefined;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Conservative default Figma-snapshot retention cap. Chosen to match the QI `qi:standard-90d`
|
|
123
|
+
* profile's `maxRunArtifacts` (500) — the least-destructive value that still bounds growth, so
|
|
124
|
+
* wiring retention on by default does NOT surprise an operator with an aggressive small cap (ADR-0048).
|
|
125
|
+
* Deployments raise/lower it via `FigmaSnapshotStoreOptions.retention.maxRecords`.
|
|
126
|
+
*/
|
|
127
|
+
export declare const DEFAULT_FIGMA_SNAPSHOT_MAX_RECORDS = 500;
|
|
128
|
+
export interface FigmaSnapshotRetentionProfile {
|
|
129
|
+
/** Maximum number of snapshots to keep (newest first by fetchedAt). */
|
|
130
|
+
readonly maxRecords: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Enforce store-level retention for Figma snapshot records. Deletes the RECORD first, then the
|
|
134
|
+
* side-file dir, so a partially-retained snapshot is never in a state where the record is gone
|
|
135
|
+
* but the side-files remain (the side-files are unreachable without the record). A retained
|
|
136
|
+
* record's side-dir is never touched.
|
|
137
|
+
*
|
|
138
|
+
* Wiring: call this alongside `deleteQualityIntelligenceRun` in the QI retention orchestrator
|
|
139
|
+
* (#274). The profiles are intentionally separate because snapshot retention may differ from
|
|
140
|
+
* run-manifest retention (snapshots are larger, longer-lived evidence artifacts).
|
|
141
|
+
*/
|
|
142
|
+
export declare function enforceFigmaSnapshotRetention(evidenceDir: string, profile: FigmaSnapshotRetentionProfile): void;
|
|
143
|
+
export declare function createNodeFigmaSnapshotStore(evidenceDir: string, options?: FigmaSnapshotStoreOptions): FigmaSnapshotStore;
|
|
144
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/qualityIntelligence/figmaSnapshot/store.ts"],"names":[],"mappings":"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"}
|