@stacknext/regression 0.9.0 → 0.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.
@@ -2,7 +2,7 @@ export declare const STACKNEXT_RUN_FORMAT = "stacknext-test-run";
2
2
  export declare const STACKNEXT_BASELINE_FORMAT = "stacknext-baseline";
3
3
  export declare const STACKNEXT_COMPARISON_FORMAT = "stacknext-comparison";
4
4
  export declare const STACKNEXT_REGRESSION_FORMAT_VERSION = 1;
5
- export declare const STACKNEXT_REGRESSION_ENGINE_VERSION = "0.9.0";
5
+ export declare const STACKNEXT_REGRESSION_ENGINE_VERSION = "0.10.0";
6
6
  export declare const RUN_STATUSES: readonly ["running", "completed", "failed", "interrupted", "incomplete"];
7
7
  export type RunStatus = (typeof RUN_STATUSES)[number];
8
8
  export declare const SAMPLE_STATUSES: readonly ["passed", "failed", "timedOut", "skipped", "interrupted"];
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AACxD,eAAO,MAAM,yBAAyB,uBAAuB,CAAA;AAC7D,eAAO,MAAM,2BAA2B,yBAAyB,CAAA;AACjE,eAAO,MAAM,mCAAmC,IAAI,CAAA;AACpD,eAAO,MAAM,mCAAmC,UAAU,CAAA;AAE1D,eAAO,MAAM,YAAY,0EAMf,CAAA;AACV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAErD,eAAO,MAAM,eAAe,qEAMlB,CAAA;AACV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,eAAO,MAAM,wBAAwB,0CAA2C,CAAA;AAChF,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE5E,eAAO,MAAM,oBAAoB,qCAAsC,CAAA;AACvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErE,eAAO,MAAM,mBAAmB,iEAKtB,CAAA;AACV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,eAAO,MAAM,qBAAqB,4CAA6C,CAAA;AAC/E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvE,eAAO,MAAM,uBAAuB,mEAM1B,CAAA;AACV,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3E,eAAO,MAAM,qBAAqB,QAAkC,CAAA;AACpE,eAAO,MAAM,mBAAmB,QAAuB,CAAA;AACvD,eAAO,MAAM,iBAAiB,QAAuB,CAAA;AAErD,eAAO,MAAM,0BAA0B;;;;;;;;CAQ7B,CAAA;AAEV,eAAO,MAAM,sBAAsB,krBAOzB,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AACxD,eAAO,MAAM,yBAAyB,uBAAuB,CAAA;AAC7D,eAAO,MAAM,2BAA2B,yBAAyB,CAAA;AACjE,eAAO,MAAM,mCAAmC,IAAI,CAAA;AACpD,eAAO,MAAM,mCAAmC,WAAW,CAAA;AAE3D,eAAO,MAAM,YAAY,0EAMf,CAAA;AACV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAA;AAErD,eAAO,MAAM,eAAe,qEAMlB,CAAA;AACV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,eAAO,MAAM,wBAAwB,0CAA2C,CAAA;AAChF,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE5E,eAAO,MAAM,oBAAoB,qCAAsC,CAAA;AACvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErE,eAAO,MAAM,mBAAmB,iEAKtB,CAAA;AACV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,eAAO,MAAM,qBAAqB,4CAA6C,CAAA;AAC/E,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvE,eAAO,MAAM,uBAAuB,mEAM1B,CAAA;AACV,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3E,eAAO,MAAM,qBAAqB,QAAkC,CAAA;AACpE,eAAO,MAAM,mBAAmB,QAAuB,CAAA;AACvD,eAAO,MAAM,iBAAiB,QAAuB,CAAA;AAErD,eAAO,MAAM,0BAA0B;;;;;;;;CAQ7B,CAAA;AAEV,eAAO,MAAM,sBAAsB,krBAOzB,CAAA"}
package/dist/constants.js CHANGED
@@ -2,7 +2,7 @@ export const STACKNEXT_RUN_FORMAT = 'stacknext-test-run';
2
2
  export const STACKNEXT_BASELINE_FORMAT = 'stacknext-baseline';
3
3
  export const STACKNEXT_COMPARISON_FORMAT = 'stacknext-comparison';
4
4
  export const STACKNEXT_REGRESSION_FORMAT_VERSION = 1;
5
- export const STACKNEXT_REGRESSION_ENGINE_VERSION = '0.9.0';
5
+ export const STACKNEXT_REGRESSION_ENGINE_VERSION = '0.10.0';
6
6
  export const RUN_STATUSES = [
7
7
  'running',
8
8
  'completed',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAA;AACxD,MAAM,CAAC,MAAM,yBAAyB,GAAG,oBAAoB,CAAA;AAC7D,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAAA;AACjE,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,mCAAmC,GAAG,OAAO,CAAA;AAE1D,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,WAAW;IACX,QAAQ;IACR,aAAa;IACb,YAAY;CACJ,CAAA;AAGV,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,SAAS;IACT,aAAa;CACL,CAAA;AAGV,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAA;AAGhF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,YAAY,CAAU,CAAA;AAGvE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU;IACV,WAAW;IACX,WAAW;IACX,cAAc;CACN,CAAA;AAGV,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA;AAG/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,UAAU;IACV,OAAO;IACP,aAAa;IACb,OAAO;IACP,SAAS;CACD,CAAA;AAGV,MAAM,CAAC,MAAM,qBAAqB,GAAG,+BAA+B,CAAA;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,oBAAoB,CAAA;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAA;AAErD,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,UAAU,EAAE,CAAC;IACb,qBAAqB,EAAE,EAAE;IACzB,oBAAoB,EAAE,EAAE;IACxB,sBAAsB,EAAE,EAAE;IAC1B,qBAAqB,EAAE,EAAE;IACzB,kBAAkB,EAAE,CAAC;IACrB,iBAAiB,EAAE,KAAK;CAChB,CAAA;AAEV,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,+FAA+F;IAC/F,oGAAoG;IACpG,0GAA0G;IAC1G,yEAAyE;IACzE,2HAA2H;IAC3H,0KAA0K;CAClK,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAA;AACxD,MAAM,CAAC,MAAM,yBAAyB,GAAG,oBAAoB,CAAA;AAC7D,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAAA;AACjE,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAA;AACpD,MAAM,CAAC,MAAM,mCAAmC,GAAG,QAAQ,CAAA;AAE3D,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,WAAW;IACX,QAAQ;IACR,aAAa;IACb,YAAY;CACJ,CAAA;AAGV,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,SAAS;IACT,aAAa;CACL,CAAA;AAGV,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAA;AAGhF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,YAAY,CAAU,CAAA;AAGvE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU;IACV,WAAW;IACX,WAAW;IACX,cAAc;CACN,CAAA;AAGV,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA;AAG/E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,UAAU;IACV,OAAO;IACP,aAAa;IACb,OAAO;IACP,SAAS;CACD,CAAA;AAGV,MAAM,CAAC,MAAM,qBAAqB,GAAG,+BAA+B,CAAA;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,oBAAoB,CAAA;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAA;AAErD,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,UAAU,EAAE,CAAC;IACb,qBAAqB,EAAE,EAAE;IACzB,oBAAoB,EAAE,EAAE;IACxB,sBAAsB,EAAE,EAAE;IAC1B,qBAAqB,EAAE,EAAE;IACzB,kBAAkB,EAAE,CAAC;IACrB,iBAAiB,EAAE,KAAK;CAChB,CAAA;AAEV,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,+FAA+F;IAC/F,oGAAoG;IACpG,0GAA0G;IAC1G,yEAAyE;IACzE,2HAA2H;IAC3H,0KAA0K;CAClK,CAAA"}
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Captures and baselines
3
+ description: Test run, scenario and sample correlation model, statuses and baseline rules.
4
+ ---
5
+
6
+ # Captures and baselines
7
+
8
+ ## Test run lifecycle
9
+
10
+ A run is created by the collector when `stacknext capture` starts a child test
11
+ command. The CLI passes the collector URL, token, run id and capture flag to the
12
+ child environment. The Playwright fixture submits each scenario sample. On exit,
13
+ the CLI completes the run and saves it under `.stacknext/runs`.
14
+
15
+ `TestRun` statuses:
16
+
17
+ | Status | Meaning |
18
+ | --- | --- |
19
+ | `running` | Registry record is still live. |
20
+ | `completed` | The child exited successfully and telemetry is complete. |
21
+ | `failed` | The child command failed. |
22
+ | `interrupted` | The child received a signal. |
23
+ | `incomplete` | Finalization failed or required telemetry is missing. |
24
+
25
+ Only a `completed` run with verified samples can become a baseline. A failed or
26
+ incomplete run remains readable but supports no regression verdict.
27
+
28
+ ## Scenario identity
29
+
30
+ `scenarioIdentity()` prefers, in order:
31
+
32
+ 1. an explicit `stacknext.scenario` annotation;
33
+ 2. the Playwright `testId`;
34
+ 3. file + title + project.
35
+
36
+ Changing the annotation creates a new scenario with no matching baseline.
37
+
38
+ Captured runs use one Playwright worker. Parallel correlation is not verified.
39
+
40
+ ## Samples and correlation
41
+
42
+ Each sample records the Playwright status, expected status, retry index, repeat
43
+ index, duration and capture time.
44
+
45
+ A trace reference is `verified` only when the collector:
46
+
47
+ 1. finds the injected trace id; and
48
+ 2. finds a server span whose parent is the injected span id.
49
+
50
+ There is no time-window, nearest-request or synthetic fallback. If correlation
51
+ is ambiguous, the sample is `incomplete` with a reason such as
52
+ `trace-not-found`, `injected-parent-not-found` or `no-request-trace-recorded`.
53
+ Incomplete samples make the affected comparison inconclusive.
54
+
55
+ Samples are capped at 100 per scenario, 20 traces per sample, and 500 spans,
56
+ 200 queries and 100 errors per captured trace.
57
+
58
+ ## Baselines
59
+
60
+ <!-- coderabbit-ai-generated:v1 -->
61
+
62
+ <!-- coderabbit-ai-generated-section:v1:82f70de6927a543f3381425f6ccfd4279d9449b3dc78859c33e5b620c80a7527 -->
63
+
64
+ Convert a completed run with `baselineFromRun(run, { name })`, then pass the
65
+ resulting `Baseline` to `saveBaseline(projectDir, baseline)` to persist the
66
+ immutable record. A baseline contains:
67
+
68
+ <!-- /coderabbit-ai-generated:v1 -->
69
+
70
+ - `sourceRunId`, project name, scenario identities and samples;
71
+ - verified trace/query/error evidence;
72
+ - deterministic diagnostic finding references;
73
+ - environment snapshot;
74
+ - stats, notes and limitations.
75
+
76
+ A baseline does not follow later telemetry or application changes. It is never
77
+ auto-deleted. `stacknext baseline remove <id> --yes` is the explicit removal
78
+ path.
79
+
80
+ ## Commands
81
+
82
+ ```bash
83
+ stacknext capture --name baseline --quiet --json \
84
+ -- pnpm exec playwright test --workers=1 --repeat-each=3 > baseline.json
85
+ stacknext baseline save <run-id> --name baseline
86
+ stacknext capture --name candidate --quiet --json \
87
+ -- pnpm exec playwright test --workers=1 --repeat-each=3 > candidate.json
88
+ stacknext compare <baseline-id> <candidate-run-id> --fail-on regression
89
+ ```
90
+
91
+ See the repository `docs/regression-testing.md` and
92
+ `@stacknext/playwright/docs/index.md`.
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: Comparisons
3
+ description: Deterministic median and threshold comparison, environment compatibility and inconclusive rules.
4
+ ---
5
+
6
+ # Comparisons
7
+
8
+ ## API
9
+
10
+ ```ts
11
+ import { compareBaseline } from '@stacknext/regression'
12
+
13
+ const comparison = compareBaseline(baseline, candidateRun, {
14
+ minSamples: 3,
15
+ durationRegressionPct: 20,
16
+ durationRegressionMs: 25,
17
+ durationImprovementPct: 20,
18
+ durationImprovementMs: 25,
19
+ countRegressionMin: 1,
20
+ ignoreEnvironment: false,
21
+ })
22
+ ```
23
+
24
+ `compareBaseline(baseline, candidate, options?, meta?)` returns a
25
+ `Comparison`. Ids and timestamps are never used to match scenarios or traces;
26
+ matching uses stored stable keys.
27
+
28
+ ## Defaults
29
+
30
+ `DEFAULT_COMPARISON_OPTIONS`:
31
+
32
+ | Option | Default |
33
+ | --- | --- |
34
+ | `minSamples` | 3 |
35
+ | `durationRegressionPct` | 20 |
36
+ | `durationRegressionMs` | 25 |
37
+ | `durationImprovementPct` | 20 |
38
+ | `durationImprovementMs` | 25 |
39
+ | `countRegressionMin` | 1 |
40
+ | `ignoreEnvironment` | false |
41
+
42
+ A duration change must cross both the percent and absolute threshold to be
43
+ classified. Medians reduce noise.
44
+
45
+ ## Status and severity
46
+
47
+ Statuses: `improved`, `regressed`, `unchanged`, `inconclusive`.
48
+
49
+ Severity: `high`, `medium`, `low`, `none`, reported separately from status.
50
+
51
+ `inconclusive` is not a pass. It means the evidence cannot support a verdict.
52
+ `unchanged` means no configured threshold was crossed in this sample, not proof
53
+ that nothing changed. `improved` is not automatically good: fewer spans or
54
+ queries can mean missing instrumentation or skipped work.
55
+
56
+ ## Why a comparison becomes inconclusive
57
+
58
+ - environment differences, unless `ignoreEnvironment` is set (a warning is still
59
+ recorded);
60
+ - a candidate run that did not complete;
61
+ - incomplete or missing scenario correlation;
62
+ - fewer than `minSamples` verified samples per side;
63
+ - missing scenarios;
64
+ - variable trace shapes within one side or a changed trace key set;
65
+ - changed diagnostic rule-set versions;
66
+ - null database durations for a query-duration metric (unmeasured, not zero).
67
+
68
+ Environment facts include Node.js, Next.js, platform, architecture, runtime,
69
+ database adapters, instrumentation flags, verbose tracing, SDK version, rule-set
70
+ version and Playwright version.
71
+
72
+ ## Metrics
73
+
74
+ Comparison metrics can be `duration`, `count`, `test-status`, `error` or
75
+ `finding` kinds. Evidence is bounded to 50 trace keys, 200 span keys, 100 query
76
+ keys, 100 finding keys and 1,000 metrics per scenario.
77
+
78
+ ## What comparisons do not claim
79
+
80
+ - No statistical significance, confidence intervals, p-values or effect sizes.
81
+ - No causality.
82
+ - No source, SQL or index analysis.
83
+ - No automatic pass/fail unless the CLI `--fail-on` flag matches.
84
+
85
+ The full methodology is in
86
+ the repository `docs/comparison-methodology.md`.
package/docs/index.md ADDED
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: "@stacknext/regression"
3
+ description: Capture, baseline, comparison schemas and deterministic local storage for StackNext runtime regression testing.
4
+ ---
5
+
6
+ # @stacknext/regression
7
+
8
+ `@stacknext/regression` owns the data model behind `stacknext capture`,
9
+ `stacknext baseline`, `stacknext compare`, the Playwright fixture, the dashboard
10
+ regression views and the MCP regression tools.
11
+
12
+ ## Who should read this
13
+
14
+ Maintainers and advanced users building on the regression records. This is an
15
+ **internal implementation package**; applications use the CLI and the optional
16
+ `@stacknext/playwright` fixture instead of importing it directly.
17
+
18
+ ## Package boundary
19
+
20
+ `regression` depends on `@stacknext/core` and `@stacknext/diagnostics`. It does
21
+ not run Playwright itself, start a collector, serve HTTP or contact a remote
22
+ service. Storage is local and report-only.
23
+
24
+ ## Public API
25
+
26
+ <!-- coderabbit-ai-generated:v1 -->
27
+
28
+ <!-- coderabbit-ai-generated-section:v1:27de812198c94ba1d63f3e6f4ab6e1cc83191a39d69ae91a0151c6ea756a7c51 -->
29
+
30
+ ```ts
31
+ import {
32
+ compareBaseline,
33
+ verifyTraceCorrelation,
34
+ capturedSampleFromSubmission,
35
+ buildEnvironmentSnapshot,
36
+ compareEnvironments,
37
+ saveRun,
38
+ loadRun,
39
+ listRuns,
40
+ saveBaseline,
41
+ loadBaseline,
42
+ listBaselines,
43
+ saveComparison,
44
+ loadComparison,
45
+ listComparisons,
46
+ createRunId,
47
+ createBaselineId,
48
+ createComparisonId,
49
+ createSampleId,
50
+ scenarioIdentity,
51
+ DEFAULT_COMPARISON_OPTIONS,
52
+ } from '@stacknext/regression'
53
+ ```
54
+
55
+ <!-- /coderabbit-ai-generated:v1 -->
56
+
57
+ See the installed declarations for every helper. The main concepts:
58
+
59
+ | Concept | Purpose |
60
+ | --- | --- |
61
+ | `scenarioIdentity` | Stable `scn-...` id from an explicit annotation, test id or file/title/project fallback. |
62
+ | `verifyTraceCorrelation` | Accepts a sample only when the injected trace and a server span parented to the injected span exist. |
63
+ | `buildEnvironmentSnapshot` | Records Node.js, Next.js, OS, runtime, adapters, instrumentation, rule set and Playwright versions. |
64
+ | `compareEnvironments` | Lists environment differences before a comparison. |
65
+ | `compareBaseline` | Deterministic median/threshold comparison of a baseline and candidate. |
66
+ | `saveRun` / `saveBaseline` / `saveComparison` | Atomic local writes under `.stacknext`. |
67
+
68
+ ## Formats
69
+
70
+ | Constant | Value |
71
+ | --- | --- |
72
+ | `STACKNEXT_RUN_FORMAT` | `stacknext-test-run` |
73
+ | `STACKNEXT_BASELINE_FORMAT` | `stacknext-baseline` |
74
+ | `STACKNEXT_COMPARISON_FORMAT` | `stacknext-comparison` |
75
+ | `STACKNEXT_REGRESSION_FORMAT_VERSION` | `1` |
76
+ | `STACKNEXT_REGRESSION_ENGINE_VERSION` | The installed package version |
77
+
78
+ Ids are strict: `run-<16 hex>`, `base-<16 hex>`, `cmp-<16 hex>`,
79
+ `scn-<16 hex>` and `smp-<16 hex>`.
80
+
81
+ ## Documentation map
82
+
83
+ - [Captures](captures.md) — run and baseline lifecycle, correlation and statuses.
84
+ - [Comparisons](comparisons.md) — metrics, thresholds and inconclusive rules.
85
+ - [Storage](storage.md) — directories, permissions, atomic writes and retention.
86
+
87
+ ## Related packages
88
+
89
+ - `@stacknext/playwright` submits correlated samples during `stacknext capture`.
90
+ - `@stacknext/cli` orchestrates capture, baseline and compare commands.
91
+ - `@stacknext/mcp` reads saved runs, baselines and comparisons.
92
+ - `@stacknext/dashboard` renders the same records.
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: Storage
3
+ description: Regression record directories, permissions, atomic writes, validation and retention rules.
4
+ ---
5
+
6
+ # Storage
7
+
8
+ ## Directories
9
+
10
+ Regression records live under the application's `.stacknext` directory:
11
+
12
+ ```text
13
+ .stacknext/
14
+ ├── runs/ # run-<16 hex>.json
15
+ ├── baselines/ # base-<16 hex>.json
16
+ └── comparisons/ # cmp-<16 hex>.json
17
+ ```
18
+
19
+ The directory is created with mode `0700`; record files use mode `0600`.
20
+ `.stacknext/.gitignore` ignores runtime state, but saved records remain local
21
+ debugging artifacts and should be reviewed before sharing.
22
+
23
+ ## API
24
+
25
+ ```ts
26
+ import {
27
+ saveRun,
28
+ loadRun,
29
+ listRuns,
30
+ listAllRuns,
31
+ saveBaseline,
32
+ loadBaseline,
33
+ listBaselines,
34
+ saveComparison,
35
+ loadComparison,
36
+ listComparisons,
37
+ regressionDir,
38
+ runsDir,
39
+ baselinesDir,
40
+ comparisonsDir,
41
+ } from '@stacknext/regression'
42
+ ```
43
+
44
+ Writes validate the full record with its versioned Zod schema before touching
45
+ disk. Writes are atomic. A record is never overwritten unless the caller passes
46
+ `overwrite: true`; the CLI only does that on an explicit `--overwrite` request.
47
+
48
+ ## Listing
49
+
50
+ List functions return `{ items, total, limit, offset, invalid }`. `limit` is
51
+ clamped to 1–200 with a default of 50. Invalid ids and stale records are counted
52
+ in `invalid` and left visible; they are not repaired or silently deleted.
53
+
54
+ ## Size and retention
55
+
56
+ - Each record is capped at 16 MiB.
57
+ - Runs, baselines and comparisons are **never pruned automatically**.
58
+ - StackNext never uploads records.
59
+ - `stacknext uninstall --remove-data` requires explicit confirmation and refuses
60
+ while a StackNext process is running.
61
+
62
+ ## Invalid records
63
+
64
+ `RegressionStorageError` carries a code used by callers to distinguish
65
+ `invalid`, `not-found`, `exists` and storage failures. Invalid ids are rejected
66
+ before the filesystem is read. A malformed file is counted, not rewritten.
67
+
68
+ ## Privacy
69
+
70
+ Records contain redacted scenario identity, trace/span/query/error evidence,
71
+ diagnostic references, environment facts and a sanitized command snapshot.
72
+ They never contain request/response bodies, headers, cookies, URL query values,
73
+ SQL bind parameters, Playwright screenshots/video/trace archives or the
74
+ collector token. The full boundary is in
75
+ the repository `docs/privacy.md`.
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@stacknext/regression",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Deterministic Playwright-linked runtime regression capture for StackNext",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "files": [
8
- "dist"
8
+ "dist",
9
+ "docs"
9
10
  ],
10
11
  "main": "./dist/index.js",
11
12
  "types": "./dist/index.d.ts",
@@ -18,8 +19,8 @@
18
19
  "./package.json": "./package.json"
19
20
  },
20
21
  "dependencies": {
21
- "@stacknext/core": "0.9.0",
22
- "@stacknext/diagnostics": "0.9.0",
22
+ "@stacknext/core": "0.10.0",
23
+ "@stacknext/diagnostics": "0.10.0",
23
24
  "zod": "4.6.7"
24
25
  },
25
26
  "engines": {