@angelmsger/fx 0.18.1 → 0.19.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/README.md +1 -0
  3. package/dist/adapters/code-host/bitbucket-cli/provider.js +4 -3
  4. package/dist/adapters/code-host/bitbucket-cli/provider.js.map +1 -1
  5. package/dist/adapters/code-host/github/provider.js +4 -3
  6. package/dist/adapters/code-host/github/provider.js.map +1 -1
  7. package/dist/adapters/code-host/local-git/provider.js +39 -6
  8. package/dist/adapters/code-host/local-git/provider.js.map +1 -1
  9. package/dist/adapters/error-tracker/sentry/client.js +11 -8
  10. package/dist/adapters/error-tracker/sentry/client.js.map +1 -1
  11. package/dist/adapters/error-tracker/sentry/provider.js +2 -1
  12. package/dist/adapters/error-tracker/sentry/provider.js.map +1 -1
  13. package/dist/adapters/error-tracker/sentry/tracker.js +170 -39
  14. package/dist/adapters/error-tracker/sentry/tracker.js.map +1 -1
  15. package/dist/application/release/baseline.js +44 -0
  16. package/dist/application/release/baseline.js.map +1 -0
  17. package/dist/application/release/errors.js +144 -26
  18. package/dist/application/release/errors.js.map +1 -1
  19. package/dist/application/release/facts.js +2 -2
  20. package/dist/application/release/facts.js.map +1 -1
  21. package/dist/application/release/index.js +92 -11
  22. package/dist/application/release/index.js.map +1 -1
  23. package/dist/application/release/repo.js +118 -20
  24. package/dist/application/release/repo.js.map +1 -1
  25. package/dist/application/release/version-declaration.js +54 -0
  26. package/dist/application/release/version-declaration.js.map +1 -0
  27. package/dist/application/release/version-history.js +86 -0
  28. package/dist/application/release/version-history.js.map +1 -0
  29. package/dist/application/repo/show.js +9 -1
  30. package/dist/application/repo/show.js.map +1 -1
  31. package/dist/application/repo/version.js +83 -0
  32. package/dist/application/repo/version.js.map +1 -0
  33. package/dist/cli/commands/index.js +2 -0
  34. package/dist/cli/commands/index.js.map +1 -1
  35. package/dist/cli/commands/release/check.js +31 -0
  36. package/dist/cli/commands/release/check.js.map +1 -1
  37. package/dist/cli/commands/release/overrides.js +19 -0
  38. package/dist/cli/commands/release/overrides.js.map +1 -0
  39. package/dist/cli/commands/repo/show.js +12 -4
  40. package/dist/cli/commands/repo/show.js.map +1 -1
  41. package/dist/cli/commands/repo/version.js +36 -0
  42. package/dist/cli/commands/repo/version.js.map +1 -0
  43. package/dist/cli/release-view.js +27 -0
  44. package/dist/cli/release-view.js.map +1 -1
  45. package/dist/cli/render/report.js +5 -0
  46. package/dist/cli/render/report.js.map +1 -1
  47. package/dist/domain/members/classify.js +5 -2
  48. package/dist/domain/members/classify.js.map +1 -1
  49. package/dist/domain/members/ownership-evidence.js +63 -0
  50. package/dist/domain/members/ownership-evidence.js.map +1 -0
  51. package/dist/domain/release/errors.js +76 -12
  52. package/dist/domain/release/errors.js.map +1 -1
  53. package/dist/domain/release/types.js.map +1 -1
  54. package/dist/domain/release/version-evidence.js +6 -0
  55. package/dist/domain/release/version-evidence.js.map +1 -0
  56. package/dist/domain/release/version.js +44 -5
  57. package/dist/domain/release/version.js.map +1 -1
  58. package/dist/domain/release/window.js +67 -3
  59. package/dist/domain/release/window.js.map +1 -1
  60. package/dist/domain/report.js +1 -0
  61. package/dist/domain/report.js.map +1 -1
  62. package/package.json +1 -1
  63. package/skills/fx-workspace/SKILL.md +1 -1
  64. package/skills/fx-workspace/references/commands.md +112 -17
  65. package/skills/fx-workspace/references/workspace-tasks.md +34 -20
@@ -1,10 +1,12 @@
1
1
  // The version a repository declares for itself, from VERSION or a dependency file.
2
2
  // It finds the written declaration without running a build that might compute another.
3
3
  // VERSION is plain text; structured metadata uses the readers below.
4
+ import path from 'node:path';
4
5
  import { parse } from 'smol-toml';
5
6
  // A Gradle build often keeps its version beside the build file.
6
7
  export const GRADLE_PROPERTIES = 'gradle.properties';
7
8
  export const ROOT_VERSION = 'VERSION';
9
+ // Reader order is the automatic declaration discovery order.
8
10
  export const VERSION_READERS = {
9
11
  [ROOT_VERSION]: (text) => text,
10
12
  'package.json': packageVersion,
@@ -15,12 +17,49 @@ export const VERSION_READERS = {
15
17
  [GRADLE_PROPERTIES]: propertiesVersion,
16
18
  };
17
19
  export function declaredVersion(file, text) {
18
- const reader = VERSION_READERS[file];
20
+ const name = path.posix.basename(file);
21
+ if (!Object.hasOwn(VERSION_READERS, name))
22
+ return undefined;
23
+ const reader = VERSION_READERS[name];
19
24
  if (reader === undefined)
20
25
  return undefined;
21
26
  const version = reader(text)?.trim();
22
27
  return version === undefined || version === '' ? undefined : version;
23
28
  }
29
+ // Field names are structural paths, except plain text (text) and Gradle/properties
30
+ // assignments (version). A POM property records the field actually carrying the value.
31
+ export function versionDeclaration(file, text) {
32
+ const name = path.posix.basename(file);
33
+ const value = declaredVersion(file, text);
34
+ if (value === undefined)
35
+ return undefined;
36
+ if (name === 'package.json') {
37
+ const doc = JSON.parse(text);
38
+ return { file, field: '/version', value, package_name: stringAt(doc, ['name']) ?? null };
39
+ }
40
+ if (name === 'pyproject.toml') {
41
+ const doc = parse(text);
42
+ const table = stringAt(doc, ['project', 'version']) === undefined ? ['tool', 'poetry'] : ['project'];
43
+ return {
44
+ file,
45
+ field: `/${[...table, 'version'].join('/')}`,
46
+ value,
47
+ package_name: stringAt(doc, [...table, 'name']) ?? null,
48
+ };
49
+ }
50
+ if (name === 'pom.xml') {
51
+ const values = pomValues(text);
52
+ const field = values.has('project/version') ? 'project/version' : 'project/parent/version';
53
+ const property = /^\$\{([\w.-]+)\}$/.exec(values.get(field) ?? '')?.[1];
54
+ return {
55
+ file,
56
+ field: `/${property === undefined ? field : `project/properties/${property}`}`,
57
+ value,
58
+ package_name: values.get('project/artifactId') ?? null,
59
+ };
60
+ }
61
+ return { file, field: name === ROOT_VERSION ? 'text' : 'version', value, package_name: null };
62
+ }
24
63
  function packageVersion(text) {
25
64
  try {
26
65
  const doc = JSON.parse(text);
@@ -53,14 +92,14 @@ function stringAt(doc, path) {
53
92
  return typeof at === 'string' ? at : undefined;
54
93
  }
55
94
  // The project's own <version>, else the one it inherits from <parent>; a single
56
- // ${property} is resolved from the project's <properties>, as CI-friendly versions use.
95
+ // ${property} is resolved from the project's <properties>. Composite and recursive
96
+ // expressions are unreadable because fx does not run Maven's expression evaluator.
57
97
  function pomVersion(text) {
58
98
  const values = pomValues(text);
59
99
  const version = values.get('project/version') ?? values.get('project/parent/version');
60
100
  const property = version === undefined ? undefined : /^\$\{([\w.-]+)\}$/.exec(version)?.[1];
61
- if (property === undefined)
62
- return version;
63
- return values.get(`project/properties/${property}`) ?? version;
101
+ const resolved = property === undefined ? version : values.get(`project/properties/${property}`);
102
+ return resolved === undefined || resolved.includes('${') ? undefined : resolved;
64
103
  }
65
104
  // The text of every element, keyed by its path from the root.
66
105
  function pomValues(text) {
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/domain/release/version.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/domain/release/version.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- // A look-back window as people write it (`14d`, `48h`, `2w`), in milliseconds.
1
+ // Relative look-back syntax and reproducible, timezone-qualified half-open ranges.
2
2
  import { DevkitError } from '../errors.js';
3
3
  const UNIT_MS = {
4
4
  h: 60 * 60 * 1000,
@@ -6,12 +6,13 @@ const UNIT_MS = {
6
6
  w: 7 * 24 * 60 * 60 * 1000,
7
7
  };
8
8
  const PATTERN = /^(\d+)([hdw])$/;
9
+ const INSTANT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})$/;
9
10
  export function parseWindow(text) {
10
11
  const m = PATTERN.exec(text.trim());
11
12
  if (m === null || m[1] === undefined || m[2] === undefined)
12
13
  return undefined;
13
- const amount = Number(m[1]);
14
- return amount === 0 ? undefined : amount * (UNIT_MS[m[2]] ?? 0);
14
+ const ms = Number(m[1]) * (UNIT_MS[m[2]] ?? 0);
15
+ return ms > 0 && Number.isSafeInteger(ms) ? ms : undefined;
15
16
  }
16
17
  export function isWindow(text) {
17
18
  return parseWindow(text) !== undefined;
@@ -25,4 +26,67 @@ export function windowMs(text) {
25
26
  nextSteps: ['fx release check --since 14d'],
26
27
  });
27
28
  }
29
+ // Check calendar components before parsing. Provider timestamps may carry microseconds;
30
+ // comparisons truncate fractional seconds to milliseconds and never round into the next bound.
31
+ export function instantMs(text) {
32
+ const match = INSTANT.exec(text);
33
+ if (match === null)
34
+ return undefined;
35
+ const [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number);
36
+ if (year === undefined || month === undefined || day === undefined)
37
+ return undefined;
38
+ const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
39
+ const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
40
+ if (days === undefined ||
41
+ day < 1 ||
42
+ day > days ||
43
+ (hour ?? 24) > 23 ||
44
+ (minute ?? 60) > 59 ||
45
+ (second ?? 60) > 59)
46
+ return undefined;
47
+ const zone = match[8] ?? '';
48
+ if (zone !== 'Z' && (Number(zone.slice(1, 3)) > 23 || Number(zone.slice(4)) > 59))
49
+ return undefined;
50
+ const fraction = match[7];
51
+ const millis = fraction === undefined ? '' : `.${fraction.slice(0, 3).padEnd(3, '0')}`;
52
+ const ms = Date.parse(`${text.slice(0, 19)}${millis}${zone}`);
53
+ return Number.isFinite(ms) ? ms : undefined;
54
+ }
55
+ export function resolveRange(input, now) {
56
+ if (input.start !== undefined || input.end !== undefined) {
57
+ if (input.since !== undefined)
58
+ throw badRange('Use either since or start/end, not both');
59
+ if (input.start === undefined || input.end === undefined)
60
+ throw badRange('Both start and end are required');
61
+ return absoluteRange(input.start, input.end);
62
+ }
63
+ const end = now.getTime();
64
+ const start = end - windowMs(input.since ?? '14d');
65
+ if (!Number.isFinite(end) || !Number.isFinite(new Date(start).getTime()))
66
+ throw badRange('The relative window is outside the supported date range');
67
+ return absoluteRange(new Date(start).toISOString(), now.toISOString());
68
+ }
69
+ export function absoluteRange(start, end) {
70
+ const floor = instantMs(start);
71
+ const ceiling = instantMs(end);
72
+ if (floor === undefined || ceiling === undefined)
73
+ throw badRange('Start and end must be ISO timestamps with an explicit timezone');
74
+ if (floor >= ceiling)
75
+ throw badRange('Start must be earlier than end');
76
+ return {
77
+ start: new Date(floor).toISOString(),
78
+ end: new Date(ceiling).toISOString(),
79
+ bounds: '[start,end)',
80
+ };
81
+ }
82
+ export function isWithinRange(date, range) {
83
+ const at = date === null ? undefined : instantMs(date);
84
+ return at !== undefined && at >= Date.parse(range.start) && at < Date.parse(range.end);
85
+ }
86
+ function badRange(message) {
87
+ return new DevkitError('usage', 'BAD_TIME_RANGE', message, {
88
+ hint: 'Use a positive relative window or two timezone-qualified ISO timestamps.',
89
+ nextSteps: ['fx release check --help'],
90
+ });
91
+ }
28
92
  //# sourceMappingURL=window.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"window.js","sourceRoot":"","sources":["../../../src/domain/release/window.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,OAAO,GAAqC;IAChD,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACjB,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IACtB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;CAC3B,CAAC;AAEF,MAAM,OAAO,GAAG,gBAAgB,CAAC;AAEjC,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7E,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,IAAI,mBAAmB,EAAE;QACvE,IAAI,EAAE,2CAA2C;QACjD,SAAS,EAAE,CAAC,8BAA8B,CAAC;KAC5C,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"window.js","sourceRoot":"","sources":["../../../src/domain/release/window.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ export function finding(group, id, level, message, extra = {}) {
11
11
  ...(extra.handoff === undefined ? {} : { handoff: extra.handoff }),
12
12
  ...(extra.evidence === undefined ? {} : { evidence: extra.evidence }),
13
13
  ...(extra.failure === undefined ? {} : { failure: extra.failure }),
14
+ ...(extra.failures === undefined ? {} : { failures: extra.failures }),
14
15
  ...(extra.required === undefined ? {} : { required: extra.required }),
15
16
  ...(extra.actions === undefined ? {} : { actions: extra.actions }),
16
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AA4C7E,MAAM,UAAU,OAAO,CACrB,KAAQ,EACR,EAAU,EACV,KAAY,EACZ,OAAe,EACf,QAAsB,EAAE;IAExB,OAAO;QACL,KAAK;QACL,EAAE;QACF,KAAK;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;QACrC,OAAO;QACP,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;QACtD,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAClE,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrE,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAClE,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrE,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAA4B;IACpD,MAAM,OAAO,GAA0B,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,+DAA+D;AAC/D,SAAS,OAAO,CACd,MAAoB,EACpB,QAA+B;IAE/B,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,MAAoB,EACpB,QAA+B;IAE/B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC;QAC5C,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC;QAC3D,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;QAC3B,QAAQ,EAAE,OAAO;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,MAAwB;IAC5C,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angelmsger/fx",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "description": "Manifest-driven multi-repository workspaces for people and coding agents",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fx-workspace
3
- version: 0.18.1
3
+ version: 0.19.0
4
4
  description: 'Use only when the user explicitly asks for the fx workspace CLI or manifest, or the current task is inside an fx-managed workspace or routed by its fx-derived AGENTS.md. Drive workspace init and sync, repository status and selection, manifest validation and editing, companion tools and login, doctor, agent Skills, repository ownership, environment coordinates and readiness through can/where, and release checks across dependencies, branches, builds and errors. Do not use for generic Sentry, OpenObserve, Jenkins, Kubernetes, logs, errors or builds outside an fx-managed workspace.'
5
5
  metadata:
6
6
  requires:
@@ -163,6 +163,38 @@ returns the corresponding explicit queries instead of an unrelated fuzzy area.
163
163
 
164
164
  `fx repo show <repo>` — the resolved entry, disk state and URLs, plus `owners`: `[]` when the members document names nobody, `null` when the workspace has no members document at all, else items of `area`, `lead`, `scenario`, `devLead`, `roles`, every person as `{id, name, email}` (name and email `null` when the id is not in the document, `all` included); `contact` is the project's contact. Its `next_steps` use the canonical repository name and explicit workspace to select an unpicked repository and synchronize missing shared checkouts; inspection itself never changes selection or downloads files.
165
165
 
166
+ `ownership_evidence` is an additional scope-aware projection. It carries `as_of`,
167
+ `basis: current_members_document`, `historical_snapshot: false`, `coverage`,
168
+ `items` and `has_more: false`. Each item retains the repository-linked area/scenario,
169
+ context, named people, responsibility teams and collective assignments. A person's
170
+ status, mentor and leader remain explicit current facts. `--as-of YYYY-MM-DD`
171
+ filters declared relationship intervals, defaulting to today in UTC; it does not
172
+ reconstruct old membership documents. `not_configured` means no members document,
173
+ `not_covered` means no linked scope, and a checked scope can still say
174
+ `no_relationships`. Do not expand collective `all` or infer an assignee from Git
175
+ authors. A team workflow selects an owner from applicable responsibility evidence.
176
+
177
+ `fx repo version <repo>` reads pinned version history for any known repository,
178
+ even one excluded from the release checklist. `version_evidence` carries
179
+ `requested_ref`, `resolved_sha`, `declaration`, `last_change`, `coverage`,
180
+ `commits_read`, `termination`, `next_sha` and structured `failures`.
181
+ `declaration` is `{file, field, package_name, value}`. `last_change` identifies the
182
+ commit, committer time, old/new values, `history_mode: first_parent` and whether
183
+ this is a field change or actual root declaration. A dependency edit is not a
184
+ version-field change. Source path, field and package identity stay fixed during
185
+ the walk; renamed files, shallow/missing parents and exhausted budgets remain
186
+ incomplete. `next_sha` describes a stop point, not an automatic resume mechanism.
187
+ The optional `baseline_evidence` pins both refs and compares their declarations
188
+ and complete commit range. `evidence_complete` covers both requested facets.
189
+ Use the command's help for ref, path, baseline and history-budget options.
190
+
191
+ Automatic declaration discovery skips dependency-only files such as
192
+ `requirements.txt`. A present but unreadable supported source remains incomplete;
193
+ only the documented Gradle fallback selects adjacent `gradle.properties`.
194
+ Maven versions must be literals or one project property resolved to a literal.
195
+ Composite, nested or unresolved expressions retain
196
+ `VERSION_DECLARATION_UNREADABLE`; they are not concrete versions.
197
+
166
198
  ### Diagnostic reports
167
199
 
168
200
  Login and doctor reject unknown explicit tool/environment selectors before setup
@@ -174,7 +206,7 @@ same ambiguous setup. Doctor marks its missing verification as incomplete.
174
206
  `fx doctor` returns `preparation`, diagnostic `coverage` (`complete` or `incomplete`),
175
207
  `summary {ok, warn, fail}` and `findings[]`. The preparation verdict owns task completion;
176
208
  optional host activation can remain unverified. An incomplete verdict exits 12.
177
- `fx release check` returns `ok`, `complete`, summary and findings and exits zero when its
209
+ `fx release check` returns `ok`, `complete`, `evidence_complete`, summary and findings and exits zero when its
178
210
  checklist was produced. Findings carry group, id, level, coverage, message, fix and
179
211
  handoff; caught query errors also carry a structured `failure` with recovery, retained
180
212
  in compact JSON. Full results also carry evidence. Incomplete checks are not passes:
@@ -198,33 +230,59 @@ repair rows; use `--details` to inspect all attempts. Each attempt is
198
230
  structured recovery errors before post-repair findings are collected.
199
231
  `completed` means the repair ran, not that the subsequent check passed.
200
232
 
201
- `fx release check [<repo>...] [--tag] [--only deps,merge,ci,errors] [--env] [--since]
202
- [--jobs]` covers repositories selected by manifest release policy; `fx release` is its
233
+ `fx release check` covers repositories selected by manifest release policy; `fx release` is its
203
234
  compatibility name. It is read-only: it never merges, tags, publishes or deploys.
235
+ Use `--help` for selection, absolute/relative error windows and optional version
236
+ history, historical baseline and version-path overrides. Override keys must name
237
+ selected repositories; use a separate invocation for multiple packages in one repo.
204
238
 
205
- Each `repos[]` entry is `{name, source, target, version_file, unmerged, note,
206
- unanswered}`. `source`
239
+ Each `repos[]` entry includes `name`, `source`, `target`, `version_file`, `unmerged`,
240
+ `note` and `unanswered`, plus `range`, `version_evidence`, `baseline_evidence` and
241
+ `facet_coverage`. `source`
207
242
  and `target` are the branch heads `{branch, sha, date, message, version}`; `version` is
208
- what the repository's dependency file declares at that commit, null when it declares
209
- none. `target` is null for a repository releasing from one branch, and both are null
243
+ what the selected root `VERSION` or package metadata declares at that commit, null
244
+ when unknown. `target` is null for a repository releasing from one branch, and both are null
210
245
  when the code host was not asked or did not answer, which the findings explain.
211
246
  `unmerged` is `{commits, authors}`: how many people's commits the source has that the
212
247
  target lacks, and how many people wrote them; null when not compared. To read those
213
248
  commits, ask the code host's own CLI for the range from `target.sha` to `source.sha`;
214
249
  `fx repo show <repo>` gives where the repository lives on the host. `unanswered[]` lists
215
- each question to the code host that failed as `{field, reason}`, where `field` is the
250
+ each question to the code host that failed as `{field, reason, error}`, where `error`
251
+ retains structured recovery and `field` is the
216
252
  value left null (`version_file`, `source.commit`, `source.version`, `target.commit`,
217
253
  `target.version`, `unmerged`); a null without an entry means the repository declares
218
254
  none.
219
255
 
256
+ `version_evidence` uses the standalone version contract above. `baseline_evidence`
257
+ is `{baseline, head, commits, coverage, failures}`. The default JSON summary replaces
258
+ the commit array with `commits_count` and an omitted count; `--details` or explicit
259
+ `--fields` retains the full array. Failures remain visible. Each snapshot has
260
+ `requested_ref`, `resolved_sha` and `declaration`. Its commits include bots and
261
+ merges since the caller's baseline, independently of `unmerged`. A version-field
262
+ change, tag or source declaration does not establish an artifact build, publication
263
+ or deployment. fx does not infer a next minor version.
264
+
265
+ `facet_coverage` distinguishes `checked`, `incomplete`, `not_requested` and
266
+ `not_applicable` for `declaration`, `version_history`, `baseline` and `errors`.
267
+ Error findings also retain a top-level `failures` array in summary output, with
268
+ structured error codes, retryability and recovery steps. Detailed error candidates
269
+ keep the latest metadata observation per ID; a resolved/ignored detail can follow
270
+ an unresolved list result and is excluded from the fresh-issue verdict.
271
+
272
+ `evidence_complete` additionally covers requested facts and unanswered questions;
273
+ it does not redefine `ok` or check coverage `complete`. The report's `observed_at`
274
+ is one command-start timestamp. Absolute ranges normalize to UTC and use
275
+ `[start,end)`; relative policies share this observation time but can use different
276
+ durations. The top-level `range` is null when per-repository ranges differ.
277
+
220
278
  Evidence is grouped by check:
221
279
 
222
- | Group | Evidence |
223
- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
224
- | `merge` | `source`, `target`, `ahead[]`, `behind[]`, `filtered`, `unknown[]` directions; commits have `sha`, `author {id, name}`, `date`, `message` |
225
- | `deps` | `file`, `offending[] {name, version, section, runtime}` |
226
- | `ci` | `builds[] {side, env, branch, path, number, status, started_at, url, commit, head, current}`; null `path` means no declared job |
227
- | `errors` | `env`, `slug`, `since`, `capped`, `undated`, `issues[] {short_id, title, level, first_seen, last_seen, count, url}` |
280
+ | Group | Evidence |
281
+ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
282
+ | `merge` | `source`, `target`, `ahead[]`, `behind[]`, `filtered`, `unknown[]` directions; commits have `sha`, `author {id, name}`, `date`, `message` |
283
+ | `deps` | `file`, `offending[] {name, version, section, runtime}` |
284
+ | `ci` | `builds[] {side, env, branch, path, number, status, started_at, url, commit, head, current}`; null `path` means no declared job |
285
+ | `errors` | `query_context`, `env`, `slug`, `since`, `capped`, `undated`, legacy fresh `issues[]`, and complete candidate metadata in `error_evidence` |
228
286
 
229
287
  CI `current` compares the commit the build checked out, `commit`, with the branch head
230
288
  `head` when the platform names it. A null `commit` (Jenkins before jenkins-cli 0.12.0)
@@ -233,13 +291,50 @@ freshness heuristic, not revision verification; use the companion's build detail
233
291
  when the task requires an exact commit match.
234
292
  The full report's merge/dependency/issue evidence is available with `--details`.
235
293
 
294
+ Every errors finding includes `evidence.query_context`, even when authentication
295
+ or collection fails or the check is not applicable. It is
296
+ `{repository, environment, range, observed_at, source}`; `source` is
297
+ `{platform, provider, coordinate_fingerprint}` or null for an unavailable or
298
+ explicitly uncovered coordinate. The fingerprint preserves the provider's query
299
+ identity before authentication without exposing arbitrary vars.
300
+
301
+ Sentry query fingerprints identify the configured endpoint, organization and
302
+ project selector, so repository aliases for one project retain the same source
303
+ identity. Repository and environment are bound separately in `query_context`.
304
+ Other tracker providers may supply their own query fingerprint; without it, the
305
+ full canonical coordinate fingerprint is retained conservatively.
306
+
307
+ For an audited retry, match the repository, environment, normalized range and
308
+ non-null source identity before superseding an earlier failure; keep both
309
+ observation times. A different server, organization, project or period is another
310
+ query. Each attempt remains separate and is not an atomic remote snapshot.
311
+
312
+ `error_evidence` retains every collected candidate returned by an unresolved
313
+ query and active in the range, including older issues. It carries `items`, `range`, `observed_at`,
314
+ `pages_read`, `has_more`, optional `next`, `coverage`, `failures` and
315
+ `truncation_reason`. Inspect these before treating a query as complete. fx follows
316
+ pagination internally; there is no public cursor-resume flag. Keep the same
317
+ absolute bounds when retrying or investigating a continuation with the companion.
318
+ Lifetime first-seen comes from issue detail; `lifetime_first_seen` and
319
+ `first_seen_scope` never use window/list dates as a fallback. Missing details
320
+ remain unknown. `list_first_seen` has unknown scope and `window_first_seen` stays
321
+ separate. `count_scope: unknown` prevents treating counts as newly occurring
322
+ events. `status_scope: current` describes each item's actual `status_observed_at`,
323
+ not state at the historical window; the aggregate status time is null. Assignee
324
+ is read metadata, not a selected or newly assigned owner. The legacy verdict
325
+ counts lifetime first appearances only; old regressions require separate review.
326
+
236
327
  Uncovered explicit repositories yield `REPO_NOT_COVERED`, unmatched tags
237
328
  `TAG_NOT_FOUND`, unknown environments `ENV_NOT_FOUND`, and an empty checklist
238
329
  `CHECKLIST_EMPTY`. `--since` accepts windows such as `14d`, `48h` or `2w`;
239
- invalid windows yield `BAD_SINCE`. Missing platform responses/jobs, undated
330
+ invalid windows yield `BAD_SINCE`. Mixing relative and absolute bounds, missing a
331
+ bound or invalid timezone-qualified timestamps yields `BAD_TIME_RANGE`.
332
+ Missing platform responses/jobs, undated
240
333
  issues and builds that cannot be dated against the branch head warn rather
241
- than prove readiness. `RELEASE_OK` / `RELEASE_FAILURES` are closing notices;
242
- inspect report coverage even when the notice says OK.
334
+ than prove readiness. Closing notices distinguish `RELEASE_FAILURES` for confirmed
335
+ failures, `RELEASE_INCOMPLETE` for missing check coverage without confirmed failures,
336
+ and `RELEASE_OK` for complete checks without failures. Inspect `evidence_complete`
337
+ separately for requested repository facts.
243
338
 
244
339
  ### Update notices
245
340
 
@@ -36,7 +36,9 @@ covered by the [Skill reference](commands.md#standalone-companion-skill).
36
36
  Optional activation stays separate. Doctor's `coverage` describes diagnostics.
37
37
  - For `release check`, inspect `ok`, coverage `complete`, warning/failure findings and
38
38
  `repos[]`, what each repository would ship. It can exit zero with failures and does
39
- not publish anything.
39
+ not publish anything. `evidence_complete` also covers requested declaration,
40
+ version-history and baseline facts; inspect per-repository `facet_coverage` and
41
+ structured failures before relying on missing data.
40
42
  - For `login`, retain `summary`, `problems` and step recovery fields. `handoff`
41
43
  needs input; `blocked` has an unfinished prerequisite; `not_started` was not attempted.
42
44
  - Read partial stdout after a nonzero exit. It preserves completed effects and
@@ -130,25 +132,26 @@ do not use a similarly named area as a substitute. Missing account keys are unkn
130
132
  not confirmed accounts. Responsibility evidence supports a proposal; changing an
131
133
  existing work-item owner must still follow the user's requested scope.
132
134
 
133
- | Task | Entry |
134
- | ------------------------------------------ | ---------------------------------------------------------------------------------------- |
135
- | Discover or repair workspace identity | `fx workspace list/show`; `workspace relocate/rebind/unregister --dry-run` |
136
- | Choose an exact repository/environment set | `fx repo select <names...>`; `fx env select <names...>`; `--all` or `--none` |
137
- | Inspect checkouts | `fx status`; `--fetch` refreshes remote comparisons |
138
- | Update selected repositories/resources | `fx sync --dry-run`; use `--only` to narrow stages |
139
- | Select repositories or environments | `fx repo pick/unpick`; `fx env pick/unpick` |
140
- | Inspect one repository and owners | `fx repo show <repo>`; `fx member show <name>` |
141
- | Find service diagnostics | `fx where <repo> --env <env>` |
142
- | Check tools/access | `fx can <capability-or-tool>`; `fx doctor --tool <tool>` |
143
- | Inspect repository release criteria | `fx release check <repo> --only merge --details` |
144
- | Install/update a companion and its Skill | `fx tool install <tool> --dry-run`; `fx tool update <tool>\|--all --dry-run` |
145
- | Review tool provenance | `fx tool history [tool]`; `fx tool inventory` |
146
- | Inspect host resources | `fx agent skills`; `fx hook list`; `fx mcp list/show` |
147
- | Inspect declarations | `fx manifest validate --strict`; `fx manifest explain '<path>'`; `fx manifest providers` |
148
- | Edit/render shared facts | `fx manifest repo-set`; `fx manifest record-probe`; `fx manifest render --check` |
149
- | Import existing checkouts | `fx manifest import <dir> --format json` |
150
- | Contribute selected source files | `fx source push <paths...> --issue <id> --title <title> --dry-run` |
151
- | Inspect personal settings | `fx config list`; `fx config get <key> --explain` |
135
+ | Task | Entry |
136
+ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
137
+ | Discover or repair workspace identity | `fx workspace list/show`; `workspace relocate/rebind/unregister --dry-run` |
138
+ | Choose an exact repository/environment set | `fx repo select <names...>`; `fx env select <names...>`; `--all` or `--none` |
139
+ | Inspect checkouts | `fx status`; `--fetch` refreshes remote comparisons |
140
+ | Update selected repositories/resources | `fx sync --dry-run`; use `--only` to narrow stages |
141
+ | Select repositories or environments | `fx repo pick/unpick`; `fx env pick/unpick` |
142
+ | Inspect one repository and owners | `fx repo show <repo>`; `fx member show <name>` |
143
+ | Find service diagnostics | `fx where <repo> --env <env>` |
144
+ | Check tools/access | `fx can <capability-or-tool>`; `fx doctor --tool <tool>` |
145
+ | Inspect repository release criteria | `fx release check <repo> --only merge --details` |
146
+ | Inspect a written version and its last field change | `fx repo version <repo>`; use `--help` for pinned refs, nested packages and historical baselines |
147
+ | Install/update a companion and its Skill | `fx tool install <tool> --dry-run`; `fx tool update <tool>\|--all --dry-run` |
148
+ | Review tool provenance | `fx tool history [tool]`; `fx tool inventory` |
149
+ | Inspect host resources | `fx agent skills`; `fx hook list`; `fx mcp list/show` |
150
+ | Inspect declarations | `fx manifest validate --strict`; `fx manifest explain '<path>'`; `fx manifest providers` |
151
+ | Edit/render shared facts | `fx manifest repo-set`; `fx manifest record-probe`; `fx manifest render --check` |
152
+ | Import existing checkouts | `fx manifest import <dir> --format json` |
153
+ | Contribute selected source files | `fx source push <paths...> --issue <id> --title <title> --dry-run` |
154
+ | Inspect personal settings | `fx config list`; `fx config get <key> --explain` |
152
155
 
153
156
  Match the returned row by `capability`, not by a platform name from another manifest.
154
157
  `fx can` without a target lists every capability with its scope, what it is for and
@@ -171,6 +174,17 @@ Use `--format json` for results and `--help` for exact arguments. The table's
171
174
  help and completion prefer canonical names while preserving compatibility aliases.
172
175
  `release check` evaluates a checklist; it does not publish packages or deploy services.
173
176
 
177
+ For release preparation, set the error window explicitly when dates matter and
178
+ keep the normalized `[start,end)` range from the report. Request version history
179
+ or a historical baseline when deciding whether the written version changed;
180
+ current-branch `unmerged` is not the range since the last release. Read all error
181
+ candidates from `error_evidence`, not only the legacy fresh-issue list. Distinguish
182
+ lifetime first-seen from window dates, and current status from historical state.
183
+ Do not turn unknown count scope into new-event counts or partial pagination into
184
+ absence. Use `repo show` responsibility evidence and scoped member queries when
185
+ a team workflow needs an assignee. Team policy decides final ownership, release
186
+ intent and the next version; generic evidence does not make those decisions.
187
+
174
188
  ## What sync will and will not do
175
189
 
176
190
  Sync clones missing repositories and fast-forwards eligible clean branches. When