@stsepelin/checktrail 0.1.0-alpha.4 → 0.1.0-alpha.5

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
@@ -4,7 +4,7 @@ Local code validation with a CLI, MCP tools, and evidence of what actually ran.
4
4
 
5
5
  Formerly Repo Verifier. See the [rename guide](docs/RENAMING.md) for existing source checkouts.
6
6
 
7
- **Published preview: 0.1.0-alpha.3.** Public source is available at
7
+ **Published preview: 0.1.0-alpha.4.** Public source is available at
8
8
  [stsepelin/checktrail](https://github.com/stsepelin/checktrail).
9
9
  See [implementation status](docs/STATUS.md), the [plan](docs/PLAN.md) and the
10
10
  [language matrix](docs/LANGUAGES.md) before relying on an adapter.
@@ -20,13 +20,14 @@ acceptance work; [client checks](docs/CLIENTS.md) record actual application cove
20
20
  pinned libraries, including setup friction and compatibility gaps.
21
21
  Alpha.3 fixes the recorded [TypeScript 4.9.5 incompatibility](docs/TYPESCRIPT.md).
22
22
  The [setup scope guide](docs/SETUP-SCOPES.md) explains language, documentation and workflow coverage.
23
- The local checkout prepares **0.1.0-alpha.4**, adding explicit [Go scope exclusions](docs/GO-SCOPE.md)
24
- and matching race-test package discovery. Alpha.4 is not published yet.
23
+ Alpha.4 adds explicit [Go scope exclusions](docs/GO-SCOPE.md) and matching
24
+ race-test package discovery. Its [release record](docs/measurements/release-alpha4.json)
25
+ includes package, client and upgrade/rollback verification.
25
26
 
26
- The [hosted matrix](https://github.com/stsepelin/checktrail/actions/runs/35597877167)
27
- passed at release commit `b0b447d` on Linux and macOS. The exact npm tarball and
27
+ The [hosted matrix](https://github.com/stsepelin/checktrail/actions/runs/35603451711)
28
+ passed at release commit `ebe7f5c` on Linux and macOS. The exact npm tarball and
28
29
  fresh CLI/MCP installations were verified. The
29
- [MCP Registry entry](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.stsepelin%2Fchecktrail/versions/0.1.0-alpha.3)
30
+ [MCP Registry entry](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.stsepelin%2Fchecktrail/versions/0.1.0-alpha.4)
30
31
  is active; execution remains disabled by default.
31
32
 
32
33
  Checktrail discovers projects, plans registered checks, invokes native tools
@@ -188,6 +189,9 @@ selection with inventoried source; `go.staticcheck` adds explicit all-rule analy
188
189
  and normalized findings. See [Go scope](docs/GO-SCOPE.md). The constrained
189
190
  [`go.golangci-lint` profile](docs/GOLANGCI-LINT.md) accepts explicit native linter
190
191
  selection while disabling hidden issue filters and fixes.
192
+ The alpha.5 source candidate adds [Go build-tag profiles](docs/GO-BUILD.md)
193
+ with one explicit configuration per selected native check. Alpha.4 does not
194
+ include this capability; a runnable example is in `examples/go-build`.
191
195
 
192
196
  `php.phpstan` combines per-file analysis accounting with native JSON diagnostics.
193
197
  See the [PHPStan contract](docs/PHPSTAN.md).
@@ -1,3 +1,4 @@
1
+ import { applyGoBuildPolicy } from "./go-build.js";
1
2
  import { applyGoScopePolicy } from "./go-scope-policy.js";
2
3
  import { actionlintCheck, workflowRoot } from "./actionlint.js";
3
4
  import { clangCheck } from "./clang.js";
@@ -356,6 +357,7 @@ export async function checksFor(source, project, requested) {
356
357
  if (explicit)
357
358
  checks.push(await golangciCheck(source, project));
358
359
  await applyGoScopePolicy(source, project, checks);
360
+ await applyGoBuildPolicy(source, project, checks);
359
361
  return checks;
360
362
  }
361
363
  if (project.adapter === "infrastructure") {
@@ -173,6 +173,7 @@ function goTests(text, allowPackageFailures = false) {
173
173
  export function evaluate(check, processes, root) {
174
174
  const result = {
175
175
  ...(check.goScope ? { goScope: check.goScope } : {}),
176
+ ...(check.goBuild ? { goBuild: check.goBuild } : {}),
176
177
  ...(check.external ? { external: check.external } : {}),
177
178
  id: check.id,
178
179
  adapter: check.adapter,
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ import type { Check, Inventory, Project } from "./types.js";
3
+ export declare const goBuildTagsSchema: z.ZodArray<z.ZodString>;
4
+ export declare const goBuildSelectionSchema: z.ZodObject<{
5
+ profile: z.ZodString;
6
+ tags: z.ZodArray<z.ZodString>;
7
+ }, z.core.$strict>;
8
+ export declare const goBuildPolicySchema: z.ZodObject<{
9
+ schemaVersion: z.ZodLiteral<1>;
10
+ profiles: z.ZodArray<z.ZodObject<{
11
+ name: z.ZodString;
12
+ tags: z.ZodArray<z.ZodString>;
13
+ checks: z.ZodArray<z.ZodEnum<{
14
+ "go.vet": "go.vet";
15
+ "go.test": "go.test";
16
+ "go.test-race": "go.test-race";
17
+ "go.staticcheck": "go.staticcheck";
18
+ "go.golangci-lint": "go.golangci-lint";
19
+ }>>;
20
+ excludedFiles: z.ZodArray<z.ZodObject<{
21
+ path: z.ZodString;
22
+ reason: z.ZodString;
23
+ }, z.core.$strict>>;
24
+ }, z.core.$strict>>;
25
+ }, z.core.$strict>;
26
+ export type GoBuildSelection = z.infer<typeof goBuildSelectionSchema>;
27
+ export declare function applyGoBuildPolicy(source: Inventory, project: Project, checks: Check[]): Promise<void>;
@@ -0,0 +1,113 @@
1
+ import { lstat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { goScopePolicySchema } from "./go-scope-policy.js";
5
+ import { readProjectFile } from "./inventory.js";
6
+ const nativeCheck = z.enum([
7
+ "go.vet",
8
+ "go.test",
9
+ "go.test-race",
10
+ "go.staticcheck",
11
+ "go.golangci-lint",
12
+ ]);
13
+ export const goBuildTagsSchema = z
14
+ .array(z
15
+ .string()
16
+ .max(64)
17
+ .regex(/^[A-Za-z_][A-Za-z0-9_]*$/))
18
+ .max(32);
19
+ export const goBuildSelectionSchema = z.strictObject({
20
+ profile: z
21
+ .string()
22
+ .max(64)
23
+ .regex(/^[A-Za-z][A-Za-z0-9_-]*$/),
24
+ tags: goBuildTagsSchema,
25
+ });
26
+ export const goBuildPolicySchema = z.strictObject({
27
+ schemaVersion: z.literal(1),
28
+ profiles: z
29
+ .array(z.strictObject({
30
+ name: goBuildSelectionSchema.shape.profile,
31
+ tags: goBuildTagsSchema,
32
+ checks: z.array(nativeCheck).min(1).max(5),
33
+ excludedFiles: goScopePolicySchema.shape.excludedFiles,
34
+ }))
35
+ .min(1)
36
+ .max(5),
37
+ });
38
+ export async function applyGoBuildPolicy(source, project, checks) {
39
+ const file = path.posix.join(project.path, "checktrail.go-build.json");
40
+ const scoped = checks.filter((check) => check.id !== "go.format");
41
+ try {
42
+ let entry;
43
+ try {
44
+ entry = await lstat(path.join(source.root, file));
45
+ }
46
+ catch (error) {
47
+ if (error.code === "ENOENT")
48
+ return;
49
+ throw error;
50
+ }
51
+ if (!entry.isFile() || !source.files.includes(file))
52
+ throw new Error("Go build policy must be an inventoried regular file");
53
+ try {
54
+ await lstat(path.join(source.root, project.path, "checktrail.go-scope.json"));
55
+ throw new Error("Use either Go build profiles or the module scope policy, not both");
56
+ }
57
+ catch (error) {
58
+ if (error.code !== "ENOENT")
59
+ throw error;
60
+ }
61
+ const policy = goBuildPolicySchema.parse(JSON.parse(await readProjectFile(source.root, file)));
62
+ const profiles = new Map();
63
+ const names = new Set();
64
+ for (const profile of policy.profiles) {
65
+ if (names.has(profile.name))
66
+ throw new Error("Duplicate Go build profile name");
67
+ names.add(profile.name);
68
+ if (new Set(profile.tags).size !== profile.tags.length)
69
+ throw new Error("Duplicate Go build tag");
70
+ const paths = profile.excludedFiles.map((item) => item.path);
71
+ if (new Set(paths).size !== paths.length ||
72
+ paths.some((p) => !project.files.includes(p)))
73
+ throw new Error("Go build exclusions must name unique inventoried project files");
74
+ for (const id of profile.checks) {
75
+ if (profiles.has(id))
76
+ throw new Error("A Go check can select only one build profile");
77
+ profiles.set(id, profile);
78
+ }
79
+ }
80
+ for (const check of scoped) {
81
+ const profile = profiles.get(check.id);
82
+ if (!profile) {
83
+ check.unavailableReason = "Selected Go check has no build profile";
84
+ continue;
85
+ }
86
+ check.goBuild = { profile: profile.name, tags: [...profile.tags] };
87
+ check.goScope = {
88
+ schemaVersion: 1,
89
+ excludedFiles: profile.excludedFiles,
90
+ };
91
+ for (const command of check.commands) {
92
+ if (command.executable === "go" ||
93
+ command.executable === "staticcheck") {
94
+ const index = command.args.indexOf("./...");
95
+ if (index < 0)
96
+ throw new Error("Unsupported Go build command");
97
+ if (profile.tags.length)
98
+ command.args.splice(index, 0, `-tags=${profile.tags.join(",")}`);
99
+ }
100
+ else if (check.id === "go.golangci-lint") {
101
+ command.args[3] = JSON.stringify(profile.tags);
102
+ }
103
+ else
104
+ throw new Error("Unsupported Go build command");
105
+ }
106
+ }
107
+ }
108
+ catch (error) {
109
+ for (const check of scoped)
110
+ check.unavailableReason =
111
+ error instanceof Error ? error.message : "Invalid Go build policy";
112
+ }
113
+ }
@@ -1,3 +1,4 @@
1
+ import { goBuildTagsSchema } from "./go-build.js";
1
2
  import { spawnSync } from "node:child_process";
2
3
  import { mkdtemp, writeFile, rm } from "node:fs/promises";
3
4
  import { tmpdir } from "node:os";
@@ -31,9 +32,10 @@ const configuration = z.strictObject({
31
32
  formatters: z.record(z.string(), z.unknown()).optional(),
32
33
  });
33
34
  async function main() {
34
- const [root, configFile, ...files] = process.argv.slice(2);
35
- if (!root || !configFile || !files.length)
35
+ const [root, configFile, encodedTags, ...files] = process.argv.slice(2);
36
+ if (!root || !configFile || !encodedTags || !files.length)
36
37
  throw new Error("Invalid golangci-lint arguments");
38
+ const tags = goBuildTagsSchema.parse(JSON.parse(encodedTags));
37
39
  const version = spawnSync("golangci-lint", ["version", "--short"], {
38
40
  encoding: "utf8",
39
41
  maxBuffer: 8192,
@@ -63,6 +65,7 @@ async function main() {
63
65
  version: "2",
64
66
  run: {
65
67
  tests: true,
68
+ "build-tags": tags,
66
69
  "modules-download-mode": "readonly",
67
70
  "relative-path-mode": "wd",
68
71
  "issues-exit-code": 1,
@@ -19,6 +19,7 @@ export async function golangciCheck(source, project) {
19
19
  fileURLToPath(new URL("./golangci-runner.js", import.meta.url)),
20
20
  source.root,
21
21
  configs[0] ?? "",
22
+ "[]",
22
23
  ...files,
23
24
  ],
24
25
  cwd: project.path,
@@ -22,6 +22,7 @@ export function projectPlan(plan, detailed) {
22
22
  excludedCount: plan.excluded.length,
23
23
  checks: plan.checks.map((check) => ({
24
24
  id: check.id,
25
+ ...(check.goBuild ? { goBuildTagCount: check.goBuild.tags.length } : {}),
25
26
  ...(check.goScope
26
27
  ? { goExcludedFileCount: check.goScope.excludedFiles.length }
27
28
  : {}),
@@ -44,6 +45,7 @@ export function projectReport(report, detailed) {
44
45
  sourceError: report.sourceError,
45
46
  checks: report.checks.map((check) => ({
46
47
  id: check.id,
48
+ ...(check.goBuild ? { goBuildTagCount: check.goBuild.tags.length } : {}),
47
49
  ...(check.goScope
48
50
  ? { goExcludedFileCount: check.goScope.excludedFiles.length }
49
51
  : {}),
@@ -46,6 +46,10 @@ export declare function validatedReport(input: unknown): {
46
46
  reason: string;
47
47
  }[];
48
48
  } | undefined;
49
+ goBuild?: {
50
+ profile: string;
51
+ tags: string[];
52
+ } | undefined;
49
53
  tests?: {
50
54
  total: number;
51
55
  passed: number;
@@ -1,3 +1,4 @@
1
+ export { goBuildPolicySchema } from "./go-build.js";
1
2
  export { goScopePolicySchema } from "./go-scope-policy.js";
2
3
  export { externalManifestSchema, externalReferenceSchema, externalRequestSchema, externalResultSchema, } from "./external-adapter.js";
3
4
  export { actionlintConfigSchema } from "./actionlint.js";
@@ -58,6 +59,10 @@ export declare const reportSchema: z.ZodObject<{
58
59
  reason: z.ZodString;
59
60
  }, z.core.$strict>>;
60
61
  }, z.core.$strict>>;
62
+ goBuild: z.ZodOptional<z.ZodObject<{
63
+ profile: z.ZodString;
64
+ tags: z.ZodArray<z.ZodString>;
65
+ }, z.core.$strict>>;
61
66
  status: z.ZodEnum<{
62
67
  error: "error";
63
68
  passed: "passed";
@@ -209,6 +214,7 @@ export declare const reportSummarySchema: z.ZodObject<{
209
214
  skipped: z.ZodNumber;
210
215
  }, z.core.$strict>>;
211
216
  goExcludedFileCount: z.ZodOptional<z.ZodNumber>;
217
+ goBuildTagCount: z.ZodOptional<z.ZodNumber>;
212
218
  }, z.core.$strict>>;
213
219
  runId: z.ZodString;
214
220
  outcome: z.ZodEnum<{
@@ -272,6 +278,10 @@ export declare const planSchema: z.ZodObject<{
272
278
  reason: z.ZodString;
273
279
  }, z.core.$strict>>;
274
280
  }, z.core.$strict>>;
281
+ goBuild: z.ZodOptional<z.ZodObject<{
282
+ profile: z.ZodString;
283
+ tags: z.ZodArray<z.ZodString>;
284
+ }, z.core.$strict>>;
275
285
  kind: z.ZodEnum<{
276
286
  format: "format";
277
287
  analysis: "analysis";
@@ -371,6 +381,7 @@ export declare const planSummarySchema: z.ZodObject<{
371
381
  }>;
372
382
  ready: z.ZodBoolean;
373
383
  goExcludedFileCount: z.ZodOptional<z.ZodNumber>;
384
+ goBuildTagCount: z.ZodOptional<z.ZodNumber>;
374
385
  }, z.core.$strict>>;
375
386
  schemaVersion: z.ZodLiteral<1>;
376
387
  engineVersion: z.ZodString;
@@ -1,3 +1,5 @@
1
+ import { goBuildSelectionSchema } from "./go-build.js";
2
+ export { goBuildPolicySchema } from "./go-build.js";
1
3
  import { goScopePolicySchema } from "./go-scope-policy.js";
2
4
  export { goScopePolicySchema } from "./go-scope-policy.js";
3
5
  import { externalIdentitySchema } from "./external-adapter.js";
@@ -127,6 +129,7 @@ export const reportSchema = z.strictObject({
127
129
  project: z.string(),
128
130
  scope: strings,
129
131
  goScope: goScopePolicySchema.optional(),
132
+ goBuild: goBuildSelectionSchema.optional(),
130
133
  status,
131
134
  reason: z.string(),
132
135
  processes: z.array(processResult),
@@ -169,6 +172,7 @@ export const reportSummarySchema = z.strictObject({
169
172
  status,
170
173
  tests: tests.optional(),
171
174
  goExcludedFileCount: count.optional(),
175
+ goBuildTagCount: count.optional(),
172
176
  })),
173
177
  });
174
178
  export const planSchema = z.strictObject({
@@ -191,6 +195,7 @@ export const planSchema = z.strictObject({
191
195
  project: z.string(),
192
196
  scope: strings,
193
197
  goScope: goScopePolicySchema.optional(),
198
+ goBuild: goBuildSelectionSchema.optional(),
194
199
  kind,
195
200
  parser: z.enum(PARSERS),
196
201
  commands: z.array(command),
@@ -211,6 +216,7 @@ export const planSummarySchema = z.strictObject({
211
216
  kind,
212
217
  ready: z.boolean(),
213
218
  goExcludedFileCount: count.optional(),
219
+ goBuildTagCount: count.optional(),
214
220
  })),
215
221
  });
216
222
  export const junitImportSchema = z.strictObject({
@@ -1,7 +1,8 @@
1
+ import type { GoBuildSelection } from "./go-build.js";
1
2
  import type { GoScopePolicy } from "./go-scope-policy.js";
2
3
  import type { ExternalIdentity } from "./external-adapter.js";
3
4
  import type { RuntimeInventory } from "./runtime-inventory.js";
4
- export declare const VERSION = "0.1.0-alpha.4";
5
+ export declare const VERSION = "0.1.0-alpha.5";
5
6
  export declare const PARSERS: readonly ["vue-router-json", "nuxt-json", "exit", "empty", "node-events", "unittest", "go-scope-test", "go-scope-analysis", "golangci-json", "staticcheck-json", "go-json", "typescript-build-json", "tsc-files", "eslint-json", "vitest-json", "playwright-json", "jest-json", "pytest-json", "fastapi-json", "django-json", "laravel-json", "rust-json", "clang-json", "java-json", "dotnet-json", "actionlint-json", "external-json", "ruby-syntax", "silent-syntax", "ruff-json", "mypy-json", "phpstan-json", "phpunit-junit", "pint-json"];
6
7
  export type Status = "passed" | "failed" | "unavailable" | "skipped" | "error" | "inconclusive";
7
8
  export type Outcome = "passed" | "failed" | "incomplete";
@@ -46,6 +47,7 @@ export interface ToolEvidence {
46
47
  }
47
48
  export interface Check {
48
49
  goScope?: GoScopePolicy;
50
+ goBuild?: GoBuildSelection;
49
51
  external?: ExternalIdentity;
50
52
  id: string;
51
53
  adapter: string;
@@ -118,6 +120,7 @@ export interface Finding {
118
120
  }
119
121
  export interface CheckResult {
120
122
  goScope?: GoScopePolicy;
123
+ goBuild?: GoBuildSelection;
121
124
  external?: ExternalIdentity & {
122
125
  tools?: {
123
126
  name: string;
package/dist/src/types.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "0.1.0-alpha.4";
1
+ export const VERSION = "0.1.0-alpha.5";
2
2
  export const PARSERS = [
3
3
  "vue-router-json",
4
4
  "nuxt-json",
@@ -7,7 +7,7 @@ separate states. Follow the linked evidence for tested versions and limits.
7
7
 
8
8
  | Milestone | Implemented scope and evidence | Open acceptance work |
9
9
  | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
10
- | M0: public contracts | Original public fixtures, MIT license, security/contribution guidance, schemas, explicit package allowlist, dependency notices and CI definitions. `STATUS.md`, `SECURITY.md`, `RELEASE.md`. | Public source, npm alpha.3 and its MCP Registry entry are published. Hosted CI passed at `b0b447d`; fresh registry installation was verified. |
10
+ | M0: public contracts | Original public fixtures, MIT license, security/contribution guidance, schemas, explicit package allowlist, dependency notices and CI definitions. `STATUS.md`, `SECURITY.md`, `RELEASE.md`. | Public source, npm alpha.4 and its MCP Registry entry are published. Hosted CI passed at `ebe7f5c`; fresh registry installation was verified. |
11
11
  | M1: executable foundation | Shared CLI/library/MCP engine, bounded inventory/runner, startup trust, native Node/Python/Go/PHP profiles, protocol and lifecycle regressions. `ARCHITECTURE.md`, `STATUS.md`, `MCP-COMPATIBILITY.md`. Fresh installed application-client profiles now have evidence in `CLIENTS.md`. | Application-client coverage beyond the named profiles. PHP remains unavailable when the consumer has no prepared runtime. |
12
12
  | M2: practical language validation | Explicit JS/TS, Python, Go and PHP native tool profiles, structured diagnostics/test evidence, versions, environments, workspace selection, scope accounting, SARIF/JUnit and finding ratchets. `LANGUAGES.md`, adapter documents, `WORKSPACES.md`, `FINDING-POLICY.md`, `NATIVE-CI.md`. | Hosted toolchain profiles passed at `52ba415`. Wider tool versions/framework configurations must be promoted separately; detection is not execution support. |
13
13
  | M3: framework/contracts | Native Laravel, Vue Router/Nuxt, Django/FastAPI assembly projections; imported runtime comparison, explicit architecture boundaries, producer/consumer schemas and a built package consumer. `RUNTIME-INVENTORY.md`, framework documents, `CONTRACTS.md`, `ARCHITECTURE-POLICY.md`, `examples/package-contract/README.md`. | Broader native semantics/import collection and live service integration are not implemented. Synthetic evidence does not establish equivalent results in a private application; private integration feedback must remain private. |
@@ -21,9 +21,9 @@ JavaScript, TypeScript, Python, Go and PHP libraries. They expose an older
21
21
  TypeScript compiler-option incompatibility and workflow/documentation/platform
22
22
  coverage friction. The [alpha.3 compiler fix](TYPESCRIPT.md) now passes the
23
23
  known TypeScript 4.9.5 case. [Setup guidance](SETUP-SCOPES.md) distinguishes
24
- workflow/documentation coverage; an unreleased [Go scope policy](GO-SCOPE.md)
25
- accounts for explicitly acknowledged native exclusions. Broader target coverage
26
- remains follow-up work. The observations do not establish full upstream CI coverage or
24
+ workflow/documentation coverage; the alpha.4 [Go scope policy](GO-SCOPE.md)
25
+ accounts for explicitly acknowledged native exclusions. Unreleased [per-check build-tag profiles](GO-BUILD.md)
26
+ add explicit tag selection; broader target coverage remains follow-up work. The observations do not establish full upstream CI coverage or
27
27
  general review effectiveness.
28
28
 
29
29
  1. Extend independently authored evaluation cohorts to additional implemented
@@ -53,10 +53,11 @@ run. The local worker/store are available independently; standard Tasks must sta
53
53
  unadvertised until routing and the integrated wire/lifecycle suite pass. See
54
54
  `MCP-COMPATIBILITY.md` for the reproduction and upstream issue.
55
55
 
56
- The public repository, npm preview `0.1.0-alpha.3` and its MCP Registry entry are
57
- published. The [hosted run at b0b447d](https://github.com/stsepelin/checktrail/actions/runs/35597877167)
58
- passed all jobs, and fresh public installation was verified. Alpha.3 adds
59
- [legacy compiler compatibility](TYPESCRIPT.md) to the existing [setup commands](ONBOARDING.md). The [GitHub prerelease](https://github.com/stsepelin/checktrail/releases/tag/v0.1.0-alpha.3)
56
+ The public repository, npm preview `0.1.0-alpha.4` and its MCP Registry entry are
57
+ published. The [hosted run at ebe7f5c](https://github.com/stsepelin/checktrail/actions/runs/35603451711)
58
+ passed all jobs, and fresh public installation was verified. Alpha.4 adds
59
+ [explicit Go exclusions](GO-SCOPE.md) alongside [legacy compiler compatibility](TYPESCRIPT.md)
60
+ and the [setup commands](ONBOARDING.md). The [GitHub prerelease](https://github.com/stsepelin/checktrail/releases/tag/v0.1.0-alpha.4)
60
61
  is also published with the verified tarball and checksum. npm tag cleanup remains
61
62
  unresolved. The repository's explicit-action requirements still apply.
62
63
  `RELEASE.md` defines the concrete
package/docs/CLIENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Application client compatibility
2
2
 
3
- The [alpha.3 release record](measurements/release-alpha3.json) repeats the named
3
+ The [alpha.4 release record](measurements/release-alpha4.json) repeats the named
4
4
  profiles below against the exact published artifact. The original standalone
5
5
  snapshots predate the Checktrail rename and retain their original identities.
6
6
  A future release needs its own checks; see [RENAMING.md](RENAMING.md).
@@ -108,4 +108,4 @@ The runtime digest identifies the installed `dist/src` tree independently.
108
108
  These local checks satisfy only the named client profiles. Claude Desktop,
109
109
  Cursor, VS Code integrations, other client versions and target operating systems
110
110
  remain unverified. These original snapshots do not establish public installation or hosted CI;
111
- alpha.3 publication and hosted evidence are recorded separately in [RELEASE.md](RELEASE.md).
111
+ alpha.4 publication and hosted evidence are recorded separately in [RELEASE.md](RELEASE.md).
package/docs/EXECUTION.md CHANGED
@@ -21,6 +21,13 @@ an unavailable runtime or external service does not count as verification.
21
21
 
22
22
  ## M2
23
23
 
24
+ - Alpha.5 candidate, unpublished: named per-check Go build-tag profiles with independent
25
+ exclusions, matching listing/execution settings, unchanged formatting scope,
26
+ strict missing/ambiguous assignment handling and summary privacy. Native
27
+ Go/Staticcheck/golangci-lint cases and CLI/library/MCP replay cover the selected
28
+ configuration; repeated-check and cross-target matrices remain pending.
29
+ See `GO-BUILD.md` and `examples/go-build`.
30
+
24
31
  - Implemented: explicit local TypeScript and ESLint adapters with file accounting.
25
32
  - Implemented: TypeScript project-reference solution validation using fresh
26
33
  in-memory declarations, source accounting and normalized compiler diagnostics.
@@ -0,0 +1,106 @@
1
+ # Go build-tag profiles (alpha.5 candidate)
2
+
3
+ The source checkout supports named build-tag profiles in module-local
4
+ `checktrail.go-build.json`. Published alpha.4 does not support this file. It
5
+ selects additional Go build constraints for each check and keeps that check's
6
+ exclusions explicit. It does not introduce cross-compilation or a target matrix.
7
+
8
+ ## Configure
9
+
10
+ Continue selecting checks in `checktrail.json`. A build profile does not enable
11
+ checks: `go.test-race`, Staticcheck and golangci-lint still need explicit selection.
12
+ Use the [runnable synthetic example](../examples/go-build/checktrail.go-build.json)
13
+ with [its check selection](../examples/go-build/checktrail.json), or configure:
14
+
15
+ ```json
16
+ {
17
+ "schemaVersion": 1,
18
+ "profiles": [
19
+ {
20
+ "name": "integration",
21
+ "tags": ["integration"],
22
+ "checks": ["go.vet", "go.test"],
23
+ "excludedFiles": []
24
+ }
25
+ ]
26
+ }
27
+ ```
28
+
29
+ Every selected native Go check must be assigned exactly one profile. Missing
30
+ assignments are unavailable; they never silently fall back to an untagged run.
31
+ Profile names and check assignments must be unique. A profile may share its tags
32
+ and exclusions across several checks; other profiles can use different settings.
33
+ Unselected checks are not executed, even if a profile names them. Each check runs
34
+ once. Repeating one check across several profiles is not implemented.
35
+
36
+ Tags are an array of distinct ASCII identifiers matching
37
+ `[A-Za-z_][A-Za-z0-9_]*`, each at most 64 characters, with at most 32 tags.
38
+ An empty array adds no tags. Profile names start with an ASCII letter and allow
39
+ letters, digits, underscores and hyphens, up to 64 characters. Up to five profiles
40
+ can assign the five supported native checks. Unknown fields, malformed JSON,
41
+ nonregular policy files and invalid exclusions make native checks unavailable.
42
+
43
+ Each profile has its own `excludedFiles`, using the exact paths and nonblank
44
+ reasons described in [Go scope](GO-SCOPE.md). Excluded files must still be
45
+ inventoried and confirmed by native `IgnoredGoFiles`. An active or stale exclusion
46
+ cannot pass. Listing a source file as excluded never suppresses an actual finding.
47
+ Do not combine this file with `checktrail.go-scope.json`; their overlapping policy
48
+ is rejected. To migrate, move exclusions into each applicable profile and remove
49
+ the old scope policy after reviewing the complete configuration.
50
+
51
+ ## Execution and evidence
52
+
53
+ Go listing, vet, tests and Staticcheck receive identical `-tags` settings within
54
+ each check. Race tests also keep `-race` in listing and execution. Golangci-lint
55
+ receives the profile tags in its generated configuration; its project's own
56
+ `run.build-tags` remains unsupported to avoid a second source of settings.
57
+ Existing protected Go settings, version checks and tool requirements still apply.
58
+
59
+ Formatting checks the full inventory once and ignores build profiles. Native
60
+ checks retain their whole inventory and reconcile selected and excluded files
61
+ separately. Tests still need a passing test in each package; test counts and
62
+ failures come from native events. A passing ordinary test does not cover a file
63
+ selected only by the race profile. An exclusion's reason is an operator statement,
64
+ not independent evidence that another check ran or covered it.
65
+
66
+ Detailed plans/reports add `goBuild` with the profile name and tags alongside
67
+ `goScope` with that profile's exclusions. Summary plans/reports expose only
68
+ `goBuildTagCount` and `goExcludedFileCount`; names, tags and reasons remain private
69
+ unless detailed output is enabled. Counts describe declarations, not proof of
70
+ execution. Older strict report-schema consumers must update before accepting the
71
+ new optional fields. The [policy schema](../schemas/go-build-policy.schema.json)
72
+ defines the data shape; planning also checks duplicate assignments and inventoried
73
+ file membership.
74
+
75
+ Planning reads data only. Execution still requires CLI/library/operator startup
76
+ trust. Policy files cannot set environment values or arbitrary command arguments.
77
+ Tags do not set `GOOS`, `GOARCH`, the compiler version or enable race instrumentation;
78
+ only the selected race check adds instrumentation. No unselected tag combinations
79
+ or other operating systems are claimed as validated.
80
+
81
+ ## Reproduce
82
+
83
+ From a built source checkout with Go and a supported race toolchain prepared:
84
+
85
+ ```sh
86
+ node dist/src/cli.js plan --root examples/go-build --detailed
87
+ node dist/src/cli.js run --root examples/go-build --trust-project --detailed --timeout-ms 120000
88
+ node --test dist/test/go-build.test.js
89
+ node scripts/verify-required-native-tests.mjs go
90
+ ```
91
+
92
+ The example's ordinary profile selects the integration test and acknowledges the
93
+ race-only test. The instrumented profile selects both. This demonstrates source
94
+ selection; the arithmetic example does not itself demonstrate race detection.
95
+ The separate [race regression](GO-RACE.md) exercises an actual data race.
96
+
97
+ The native regression suite exercises tagged compiler errors and assertions,
98
+ valid near misses, undeclared omissions, stale exclusions, missing assignments,
99
+ independent ordinary/race settings, analyzer diagnostics, nonexecuting planning,
100
+ summary privacy and CLI/MCP agreement. Standard schema checks cover the exported
101
+ policy and report shapes. Prepared CI requires these named cases to run; unavailable
102
+ native tools cannot satisfy the required profile.
103
+
104
+ References: [Go build constraints](https://pkg.go.dev/cmd/go#hdr-Build_constraints),
105
+ [Staticcheck CLI](https://staticcheck.dev/docs/running-staticcheck/cli/),
106
+ [golangci-lint configuration](https://golangci-lint.run/docs/configuration/file/).
package/docs/GO-RACE.md CHANGED
@@ -11,9 +11,11 @@ The native fixture runs two workers repeatedly updating one shared counter. The
11
11
  unprotected version must fail with an actual `DATA RACE` diagnostic; atomic
12
12
  updates must pass and yield the exact combined count. A passing run cannot
13
13
  establish freedom from races on paths it did not execute. Native package/file evidence makes undeclared excluded source and untested packages
14
- incomplete; see [Go scope](GO-SCOPE.md) for the unreleased explicit exclusion policy.
15
- The source checkout also passes `-race` to package listing so it uses the same build
16
- constraints as the tests. A build/OS matrix is not implemented.
14
+ incomplete; see [Go scope](GO-SCOPE.md) for the explicit exclusion policy available since alpha.4.
15
+ Alpha.4 also passes `-race` to package listing so it uses the same build
16
+ constraints as the tests. The unpublished alpha.5 source candidate adds
17
+ [per-check build-tag profiles](GO-BUILD.md), allowing race and ordinary tests to
18
+ use different tags and exclusions. A build/OS matrix is not implemented.
17
19
 
18
20
  A supported Go race platform and C compiler are required. Compilation and runtime
19
21
  errors are retained in detailed output; no compiler, library or toolchain is
package/docs/GO-SCOPE.md CHANGED
@@ -27,10 +27,10 @@ programs. Cross-module workspace builds need a separate explicit profile. Native
27
27
  compiler/analyzer caches may be used; test result caching remains disabled.
28
28
  Dependencies and toolchains must be prepared separately.
29
29
 
30
- ## Explicit exclusions in the source checkout (unreleased)
30
+ ## Explicit exclusions (alpha.4 and later)
31
31
 
32
- The source checkout adds `checktrail.go-scope.json` at each Go module root.
33
- Published alpha.3 does not support this policy yet. Opt in only after reviewing
32
+ Alpha.4 adds `checktrail.go-scope.json` at each Go module root. Earlier releases
33
+ do not support this policy. Opt in only after reviewing
34
34
  which files the intended native run leaves unverified:
35
35
 
36
36
  ```json
@@ -78,6 +78,10 @@ This policy does not introduce build-tag flags, cross-compilation, cross-target
78
78
  test execution or a build matrix. Use separately prepared native target runs for
79
79
  coverage outside the selected profile. Existing protected Go settings stay intact.
80
80
 
81
+ The source checkout separately adds [per-check build-tag profiles](GO-BUILD.md).
82
+ They use their own per-profile exclusions and cannot coexist with this module-wide
83
+ policy. That capability is in the unpublished alpha.5 candidate; alpha.4 retains the behavior above.
84
+
81
85
  ## Known-case replay
82
86
 
83
87
  The [pinned public UUID replay](measurements/go-scope-policy-replay.json) uses the
@@ -91,6 +95,11 @@ The upstream tracked files and original policy were preserved; temporary scope
91
95
  policy and failing control were removed. The record identifies the tested tarball
92
96
  and runtime source hashes; adding this record changes later package bytes.
93
97
 
98
+ The exact alpha.4 release candidate repeated this replay before publication; see
99
+ the [release record](measurements/release-alpha4.json). Its synthetic upgrade test
100
+ also confirms that rolling back to alpha.3 preserves the policy file but restores
101
+ strict scope accounting: a project relying on exclusions becomes incomplete.
102
+
94
103
  ## Staticcheck
95
104
 
96
105
  Select `go.staticcheck` explicitly. It requires the installed `staticcheck`
@@ -14,8 +14,8 @@ linters:
14
14
  enable: [govet, staticcheck, unused]
15
15
  ```
16
16
 
17
- Other linters, nonempty custom settings, formatters and Go build-version/tag
18
- profiles are incomplete until separately verified. This is deliberately a
17
+ Other linters, nonempty custom settings, formatters and Go version/tag overrides
18
+ in `.golangci.*` are incomplete until separately verified. This is deliberately a
19
19
  constrained profile, not support for every golangci-lint configuration. YAML
20
20
  duplicates, unsupported tags and excessive aliases are rejected. Planning only
21
21
  discovers the local config and source; parsing/native execution occurs with trust.
@@ -27,6 +27,9 @@ read-only module resolution, absolute JSON locations and no extra output files.
27
27
  Output and native analyzer cache use a fresh temporary directory, removed after
28
28
  normal completion. Existing project config and output paths are not rewritten.
29
29
  Native Go source accounting follows [the shared contract](GO-SCOPE.md).
30
+ The alpha.5 source candidate adds [Checktrail build-tag profiles](GO-BUILD.md).
31
+ Those tags are passed to both package listing and the generated native config;
32
+ `.golangci.*` still cannot supply a separate `run.build-tags` setting.
30
33
 
31
34
  Native `nolint` and Staticcheck ignore directives are currently unsupported and
32
35
  make the check incomplete. The wrapper scans Go comment boundaries, including