@sigloch/graphcode-client 0.6.0 → 0.8.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.
@@ -68,9 +68,32 @@ export type IncoseScope = 'lean' | 'full';
68
68
  /** graphcode's declared scope — see the module header for the rationale. */
69
69
  export declare const GRAPHCODE_INCOSE_SCOPE: IncoseScope;
70
70
  /**
71
- * Phase-Readiness gates (INCOSE technical reviews) → the element-level V3_RULES
72
- * each gate owns. DISJOINT + EXHAUSTIVE over the 15 element rules; verified by
73
- * TEST-readiness-model against SE_DESCRIPTOR at runtime (never hardcoded count).
71
+ * Which rules the impl gates own: the milestone- and change-level family. The impl
72
+ * gates ARE the milestone/CR burndown (SAR/FCA/SVR/FRR ↔ MS-1..MS-4), so a rule about
73
+ * a milestone or a change request belongs there and not on a design review.
74
+ *
75
+ * Derived from the prefix over the contracts catalog (CR-GC-312) — a new `MS-`/`CR-R`
76
+ * rule lands here without an edit. Before, this was `['MS-01','MS-02']` written out,
77
+ * frozen at the two rules that existed when it was authored.
78
+ */
79
+ export declare const IMPL_GATE_RULES: readonly string[];
80
+ /**
81
+ * Phase-Readiness gates (INCOSE technical reviews) → the rules each gate owns.
82
+ * DISJOINT + EXHAUSTIVE over the rule catalog; asserted by TEST-readiness-model
83
+ * against SE_DESCRIPTOR at runtime, never a hardcoded count.
84
+ *
85
+ * DERIVED from `RULE_TO_PHASE` (CR-GC-312). This used to be a hand-written literal —
86
+ * and contracts had already replaced it: CR-SM-226 removed `emergentPhase`/`phaseScore`
87
+ * as "a third, undocumented phase construct next to RULE_TO_DIMENSION and the (then
88
+ * still ad-hoc) phase-gate grouping", introducing `RULE_TO_PHASE` as the one
89
+ * replacement, "exported so no consumer reinvents it". That ad-hoc grouping was THIS
90
+ * object, and the replacement was never carried through here.
91
+ *
92
+ * The cost of leaving it: the literal and `RULE_TO_PHASE` had drifted apart on 21 of
93
+ * 33 shared rules — R-01 SRR vs TRR, R-08 TRR vs PDR, RD-01..03 CDR vs SRR, and so on.
94
+ * Two live gate assignments for the same rules, and readiness was scored against the
95
+ * frozen one. Deriving moves those rules onto the assignment contracts declares; gate
96
+ * scores change accordingly, which is the correction, not a side effect.
74
97
  */
75
98
  export declare const PHASE_GATE_RULES: Record<string, readonly string[]>;
76
99
  /** Human labels for the phase gates. */
@@ -108,12 +131,6 @@ export declare const IMPL_GATE_MILESTONES: Record<string, {
108
131
  ms: string;
109
132
  label: string;
110
133
  }>;
111
- /**
112
- * The 2 milestone-level V3_RULES the impl gates embody (MS-01 empty scope,
113
- * MS-02 dangling dependency). Together with the phase-gate rules these span
114
- * V3_RULES exhaustively — so the model covers it with nothing left over.
115
- */
116
- export declare const IMPL_GATE_RULES: readonly string[];
117
134
  /**
118
135
  * A single readiness gate outcome.
119
136
  * `passed` is the hard verdict (no blocking/error item); `score` ∈ [0,1] is a
package/dist/readiness.js CHANGED
@@ -1,39 +1,81 @@
1
1
  import { SE_DESCRIPTOR } from '@sigloch/graph-api-core';
2
- import { CODE_CONFORMANCE_RULES } from '@sigloch/contracts/se';
2
+ import { CODE_CONFORMANCE_RULES, RULE_TO_PHASE } from '@sigloch/contracts/se';
3
3
  import { scoreCompleteness, NEUTRAL_COMPLETENESS, } from './readiness-completeness.js';
4
4
  /** graphcode's declared scope — see the module header for the rationale. */
5
5
  export const GRAPHCODE_INCOSE_SCOPE = 'lean';
6
6
  /**
7
- * Phase-Readiness gates (INCOSE technical reviews) → the element-level V3_RULES
8
- * each gate owns. DISJOINT + EXHAUSTIVE over the 15 element rules; verified by
9
- * TEST-readiness-model against SE_DESCRIPTOR at runtime (never hardcoded count).
7
+ * Which rules the impl gates own: the milestone- and change-level family. The impl
8
+ * gates ARE the milestone/CR burndown (SAR/FCA/SVR/FRR ↔ MS-1..MS-4), so a rule about
9
+ * a milestone or a change request belongs there and not on a design review.
10
+ *
11
+ * Derived from the prefix over the contracts catalog (CR-GC-312) — a new `MS-`/`CR-R`
12
+ * rule lands here without an edit. Before, this was `['MS-01','MS-02']` written out,
13
+ * frozen at the two rules that existed when it was authored.
14
+ */
15
+ export const IMPL_GATE_RULES = Object.keys(RULE_TO_PHASE)
16
+ .filter((id) => /^(MS-|CR-R)/.test(id))
17
+ .sort();
18
+ /**
19
+ * `RULE_TO_PHASE` covers the whole catalog including the CODING profile (`BQ-` and
20
+ * `ND-` prefixes). The readiness model is the SE profile only — `SE_DESCRIPTOR.rules`
21
+ * deliberately excludes those, so a gate must not claim one and then never see it fire.
10
22
  */
11
- export const PHASE_GATE_RULES = {
12
- // System + use-case structure exists; every requirement is verifiable.
13
- SRR: ['R-17', 'R-14', 'R-01'],
14
- // Functional architecture: chains, actors, flows; functions trace to REQs.
15
- PDR: ['R-15', 'R-16', 'R-10', 'R-02'],
16
- // Detailed design: ASIL isolation, module size, no cycles, sound decomposition,
17
- // valid trace patterns (R-18: every trace's element-type pair is legal — now also
18
- // flags any residual REQ→MOD allocate edge, CR-228), module allocation (R-22
19
- // FUNC→MOD, R-23 MOD→FUNC — CR-202/208), and FUNC→code binding — presence (R-20: every non-concept
20
- // FUNC carries a realRef, CR-GC-205 Item 5) AND resolution (RC-01: the realRef
21
- // points at a declared symbol on disk — CR-GC-253 conformance, with CodeFacts).
22
- // SCHEMA realRef binding (R-26 presence, RC-03 resolution, RC-04 parsed-at-interface —
23
- // CR-211) and physical-MOD realRef presence (R-27, CR-228) join the realRef family
24
- // (R-20/RC-01) here: interfaces + parts are detailed design.
25
- // RC-05 (cross-module import drift — CR-212) is module-coupling: also detailed design.
26
- // RD-04 (decomposition breadth > 11 children per level, CR-SM-221) is a structural
27
- // property of the detailed design, next to RD-01..03.
28
- // MT-01/MT-02 (instability, LCOM4 — CR-SM-222) are architecture metrics over the
29
- // module structure: detailed design too. Their severities are warning/info, so they
30
- // surface the gate as 'open', never 'blocked'. MT-03 is NOT here — allocation
31
- // cohesion became a measurement rather than a rule (CR-SM-223).
32
- CDR: ['R-03', 'R-04', 'R-12', 'R-18', 'R-20', 'R-22', 'R-23', 'R-26', 'R-27', 'RC-01', 'RC-03', 'RC-04', 'RC-05', 'RD-01', 'RD-02', 'RD-03', 'RD-04', 'MT-01', 'MT-02'],
33
- // Verification wired (TEST→REQ) + referential trace consistency + runnable test
34
- // bindings — presence (R-19) AND resolution (RC-02: file + case exist, CR-GC-253).
35
- TRR: ['R-05', 'R-08', 'R-19', 'R-21', 'RC-02'],
23
+ const isCodingProfile = (id) => /^(BQ-|ND-)/.test(id);
24
+ /**
25
+ * Which conformance rule sits on which gate. RC-* are deliberately outside
26
+ * `ALL_RULE_DEFS` (they need `CodeFacts` from a repo checkout, which contracts has no
27
+ * access to), so `RULE_TO_PHASE` cannot carry them and this is the one legitimate
28
+ * local addition.
29
+ *
30
+ * Still not hand-picked: each RC rule inherits the gate of the PRESENCE rule it
31
+ * resolves — the Presence/Resolution split contracts documents (R-19/R-20/R-26 declare
32
+ * a binding, RC-01/02/03/04 check it actually resolves on disk). RC-05 (cross-module
33
+ * import drift) has no presence partner; it is module coupling, so it follows R-23.
34
+ */
35
+ const RC_PRESENCE_PARTNER = {
36
+ 'RC-01': 'R-20', // FUNC realRef → declared symbol
37
+ 'RC-02': 'R-19', // testRef → runnable test case
38
+ 'RC-03': 'R-26', // SCHEMA realRef → declared export
39
+ 'RC-04': 'R-26', // SCHEMA realRef parsed at its interface
40
+ 'RC-05': 'R-23', // cross-module import the graph does not document
36
41
  };
42
+ /**
43
+ * Phase-Readiness gates (INCOSE technical reviews) → the rules each gate owns.
44
+ * DISJOINT + EXHAUSTIVE over the rule catalog; asserted by TEST-readiness-model
45
+ * against SE_DESCRIPTOR at runtime, never a hardcoded count.
46
+ *
47
+ * DERIVED from `RULE_TO_PHASE` (CR-GC-312). This used to be a hand-written literal —
48
+ * and contracts had already replaced it: CR-SM-226 removed `emergentPhase`/`phaseScore`
49
+ * as "a third, undocumented phase construct next to RULE_TO_DIMENSION and the (then
50
+ * still ad-hoc) phase-gate grouping", introducing `RULE_TO_PHASE` as the one
51
+ * replacement, "exported so no consumer reinvents it". That ad-hoc grouping was THIS
52
+ * object, and the replacement was never carried through here.
53
+ *
54
+ * The cost of leaving it: the literal and `RULE_TO_PHASE` had drifted apart on 21 of
55
+ * 33 shared rules — R-01 SRR vs TRR, R-08 TRR vs PDR, RD-01..03 CDR vs SRR, and so on.
56
+ * Two live gate assignments for the same rules, and readiness was scored against the
57
+ * frozen one. Deriving moves those rules onto the assignment contracts declares; gate
58
+ * scores change accordingly, which is the correction, not a side effect.
59
+ */
60
+ export const PHASE_GATE_RULES = (() => {
61
+ const implOwned = new Set(IMPL_GATE_RULES);
62
+ const gates = { SRR: [], PDR: [], CDR: [], TRR: [] };
63
+ for (const [ruleId, gate] of Object.entries(RULE_TO_PHASE)) {
64
+ if (implOwned.has(ruleId))
65
+ continue; // the impl axis owns these
66
+ if (isCodingProfile(ruleId))
67
+ continue; // not part of the SE readiness model
68
+ gates[gate]?.push(ruleId);
69
+ }
70
+ for (const [rcId, partner] of Object.entries(RC_PRESENCE_PARTNER)) {
71
+ const gate = RULE_TO_PHASE[partner];
72
+ if (gate)
73
+ gates[gate].push(rcId);
74
+ }
75
+ for (const ids of Object.values(gates))
76
+ ids.sort();
77
+ return gates;
78
+ })();
37
79
  /** Human labels for the phase gates. */
38
80
  export const PHASE_GATE_LABELS = {
39
81
  SRR: 'System Requirements Review',
@@ -86,12 +128,6 @@ export const IMPL_GATE_MILESTONES = {
86
128
  SVR: { ms: 'MS-3-mvp-readiness', label: 'System Verification Review' },
87
129
  FRR: { ms: 'MS-4-mvp2', label: 'Functional Readiness Review' },
88
130
  };
89
- /**
90
- * The 2 milestone-level V3_RULES the impl gates embody (MS-01 empty scope,
91
- * MS-02 dangling dependency). Together with the phase-gate rules these span
92
- * V3_RULES exhaustively — so the model covers it with nothing left over.
93
- */
94
- export const IMPL_GATE_RULES = ['MS-01', 'MS-02'];
95
131
  /**
96
132
  * Summary projection of a ReadinessReport (CR-GC-203 item 2): drops the heavy
97
133
  * per-element lists — `violations` and every gate's `blocking`/`open` — while
@@ -15,8 +15,14 @@
15
15
  *
16
16
  * @author andreas@siglochconsulting
17
17
  */
18
- /** All supported views, in deterministic order. */
19
- export declare const MARKDOWN_VIEWS: readonly ["spec", "architecture", "cr-list", "references", "srs", "nfr", "rtm", "icd", "testconcept", "testmatrix", "intplan", "changelog", "fmea", "conops", "trade", "implplan"];
18
+ /**
19
+ * All supported views, in deterministic order.
20
+ *
21
+ * CR-GC-305 removed `spec` (0.7.0, breaking): it was a raw dump of every element
22
+ * grouped by type and answered the same question as `srs` (the ISO-29148 narrative)
23
+ * with different completeness — two requirements documents, one truth. `srs` stays.
24
+ */
25
+ export declare const MARKDOWN_VIEWS: readonly ["architecture", "cr-list", "references", "srs", "nfr", "rtm", "icd", "testconcept", "testmatrix", "intplan", "changelog", "fmea", "conops", "trade", "implplan"];
20
26
  export type MarkdownView = (typeof MARKDOWN_VIEWS)[number];
21
27
  /** Default file name for each view (under docs/views/). */
22
28
  export declare const VIEW_FILENAMES: Record<MarkdownView, string>;
@@ -15,10 +15,15 @@
15
15
  *
16
16
  * @author andreas@siglochconsulting
17
17
  */
18
- /** All supported views, in deterministic order. */
18
+ /**
19
+ * All supported views, in deterministic order.
20
+ *
21
+ * CR-GC-305 removed `spec` (0.7.0, breaking): it was a raw dump of every element
22
+ * grouped by type and answered the same question as `srs` (the ISO-29148 narrative)
23
+ * with different completeness — two requirements documents, one truth. `srs` stays.
24
+ */
19
25
  export const MARKDOWN_VIEWS = [
20
26
  // foundation (CR-GC-113)
21
- 'spec',
22
27
  'architecture',
23
28
  'cr-list',
24
29
  'references',
@@ -38,7 +43,6 @@ export const MARKDOWN_VIEWS = [
38
43
  ];
39
44
  /** Default file name for each view (under docs/views/). */
40
45
  export const VIEW_FILENAMES = {
41
- spec: 'spec.md',
42
46
  architecture: 'architecture.md',
43
47
  'cr-list': 'cr-list.md',
44
48
  references: 'references.md',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigloch/graphcode-client",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,8 +17,8 @@
17
17
  "prepublishOnly": "npm run build && npm run test"
18
18
  },
19
19
  "dependencies": {
20
- "@sigloch/contracts": "^3.0.0",
21
- "@sigloch/graph-api-core": "^2.0.0"
20
+ "@sigloch/contracts": "^3.2.0",
21
+ "@sigloch/graph-api-core": "^2.1.0"
22
22
  },
23
23
  "license": "MIT",
24
24
  "description": "Read-side client for a running @sigloch/graphcode host — host-socket calls, dashboard panels, readiness projection and the markdown view catalog. Deliberately free of Kuzu and the MCP SDK so a viewer can depend on it without pulling an embedded graph database.",