rcf-lite 0.32.3 → 0.32.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/CHANGELOG.md CHANGED
@@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.32.5] - 2026-10-07
10
+
11
+ 0.32.5 ships two chain-shape fixes surfaced by Dex on branch `dex/discovery-viewer-command-page` (reporter), closing issues 321 and 322. The dogfood walker in `test/rcf-tree.test.js` now mirrors the sidecar-ledger carve-out from `src/define/ledgers.js` and ignores `rcf/define/`, so the first `pnpm rcf define ledger brief add` on a fresh tree no longer blows up three dogfood assertions. A new `packages/rcf-lite/guidance/discovery/` (and companion `packages/rcf-lite/docs/discovery/`) subdir gives project discovery artefacts a predictable home outside the locked methodology inventories. The three locked slug lists in `test/guidance/inventory.test.js`, `test/mcp/resources.test.js` and `test/docs/links.test.js` are untouched and `guidance/manifest.json` is untouched, so an in-package methodology addition still requires a coordinated test-code change. breaking: false; the 0.32.1 through 0.32.4 fixes carry forward unchanged. minAgentAction: null.
12
+
13
+ ### Fixed
14
+
15
+ - **Dogfood walker ignores `rcf/define/` ledgers (issue 321, reporter Dex, w-2026-10-07-dave-006).** `src/define/ledgers.js` exports the new `DEFINE_RELATIVE_DIR` constant; `test/rcf-tree.test.js:walk()` imports it and skips the directory the exact same way the ledger module writes to it, so the four sidecar ledgers (`brief-ledger.json`, `decisions-ledger.json`, `concern-ledger.json`, `probe-ledger.json`) plus the freeze record never surface to `classify()` or `loadAll()`. `loadAll()` additionally takes an optional project-root override so the carve-out works regardless of where the caller rooted the walk. Regression fixture seeds the four ledgers plus a bug-bait REQ-shaped file under `rcf/define/` and proves none of them surface, while a real chain document outside the carve-out does.
16
+ - **Project discovery home carved out of the locked inventories (issue 322, reporter Dex, w-2026-10-07-dave-006).** `packages/rcf-lite/guidance/discovery/` and `packages/rcf-lite/docs/discovery/` are the new home for DISCOVERY-stage artefacts: discovery briefs, prototype notes, exploratory write-ups, infographic sketches. The subdirs sit outside the top-level non-recursive readdir enumerations the methodology locks use, so a first-time contributor can land a discovery brief without touching the methodology lock or the pack manifest. The guidance posture (no em-dash, no non-canonical external URLs, filename stem is a well-formed slug) still runs over the subdir via a new `test/guidance/discovery-home.test.js`. CONTRIBUTING.md documents the home under chain-first discipline.
17
+
18
+ ## [0.32.4] - 2026-10-07
19
+
20
+ 0.32.4 is the stop-word follow-up to 0.32.3 after Dex's second-consumer check of PR 318 on WESPA main 34ebceba (2026-10-07T10:38Z, issue 319). 0.32.3 moved the English stop-word skip onto the pattern 4 (dot-notation) branch but left patterns 2 and 3 (prose `<name> field` and `fields: <name>`) with no stop-word filter at all; the AC-130-1 then-clause `declares NO join-shaped fields: the earlier jurisdiction ...` fed the word `the` to the extractor and false-failed D6 on WESPA (Ready-to-build no on 0.32.3 against yes on 0.31.0). breaking: false; the 0.32.1, 0.32.2 and 0.32.3 fixes carry forward unchanged. minAgentAction: null.
21
+
22
+ ### Fixed
23
+
24
+ - **D6 consistency:unsatisfiable stops reading English stop words out of prose `fields:` lists and `<name> field` phrases (issue 319, w-2026-10-07-dave-003).** `extractThenFieldTokens` in `src/query/gates.js` now shares a broader English stop-word set (`STOP_PATTERN_23`: the, a, an, and, or, of, to, in, on, for, with, by, from, at, as, is, are, be, this, that, these, those, it, its, not, no, all, any, each, per, via, into, than, then, when, which, who, whom, where, while) across patterns 2 and 3, and reuses pattern 4's file-extension skip (md, json, jsonl, ...) and two-character path-context lookbehind on both branches. Pattern 3 additionally walks a comma-separated identifier list after `fields:` so a prose field list such as `required fields: userID, email, createdAt` yields every token it names (one for each missing field), not only the first after the colon. The AC-130-1 WESPA then-clause (sentence-ending `fields: the ...`) is silent on the gate; the AC-060-3 shape (`required fields: userID, email`) is retained and now surfaces every real missing field, not only the first. Pattern 1 is untouched; pattern 4 keeps its 0.32.3 behaviour; the issue 311 and issue 315 fixtures stay green. Regression fixtures in `test/query/gates.test.js` cover a negative control on the AC-130-1 shape, a positive control that both `userID` and `createdAt` fire, and a pattern 2 file-extension / path-context control.
25
+
9
26
  ## [0.32.3] - 2026-10-07
10
27
 
11
28
  0.32.3 is a hotfix for the 0.32.2 D6 consistency:unsatisfiable regression discovered by Barry on ai-on-record (define/kickoff, head 974b4c1) and second-sourced by Dex on WESPA (26 green-to-red findings in three classes, 2026-10-06 20:05Z). The regression came from pattern 4 of `extractThenFieldTokens` in `src/query/gates.js`, added in PR 313 as part of the issue 311 fix. breaking: false; the 0.32.1 and 0.32.2 fixes carry forward unchanged. minAgentAction: null.
@@ -2,8 +2,8 @@
2
2
  "registerCanary": [
3
3
  {
4
4
  "id": "rc-2026-10-07-001",
5
- "createdAt": "2026-10-07T10:44:10.684Z",
6
- "buildVersion": "0.32.3-mockdriver",
5
+ "createdAt": "2026-10-07T13:01:30.849Z",
6
+ "buildVersion": "0.32.5-mockdriver",
7
7
  "fixturePromptId": "canary-prompt-01",
8
8
  "responseWordCount": 55,
9
9
  "grades": {
@@ -35,8 +35,8 @@
35
35
  },
36
36
  {
37
37
  "id": "rc-2026-10-07-002",
38
- "createdAt": "2026-10-07T10:44:10.684Z",
39
- "buildVersion": "0.32.3-mockdriver",
38
+ "createdAt": "2026-10-07T13:01:30.850Z",
39
+ "buildVersion": "0.32.5-mockdriver",
40
40
  "fixturePromptId": "canary-prompt-02",
41
41
  "responseWordCount": 55,
42
42
  "grades": {
@@ -68,8 +68,8 @@
68
68
  },
69
69
  {
70
70
  "id": "rc-2026-10-07-003",
71
- "createdAt": "2026-10-07T10:44:10.684Z",
72
- "buildVersion": "0.32.3-mockdriver",
71
+ "createdAt": "2026-10-07T13:01:30.850Z",
72
+ "buildVersion": "0.32.5-mockdriver",
73
73
  "fixturePromptId": "canary-prompt-03",
74
74
  "responseWordCount": 55,
75
75
  "grades": {
@@ -0,0 +1,22 @@
1
+ # guidance/discovery/
2
+
3
+ Home for project discovery artefacts: discovery briefs, prototype
4
+ notes, exploratory write-ups, and anything else that belongs to a
5
+ specific DISCOVERY-stage effort rather than the methodology pack
6
+ itself.
7
+
8
+ Files directly under `guidance/` are the methodology inventory,
9
+ locked by `test/guidance/inventory.test.js` and `test/mcp/resources.test.js`
10
+ and reachable through `rcf://docs/<slug>`. New additions there require a
11
+ coordinated test-code change and a manifest update.
12
+
13
+ Files here, under `guidance/discovery/<slug>.md`, do NOT need a manifest
14
+ update and are not served through the methodology-doc URIs. They still
15
+ carry the guidance posture (no em-dash, no non-canonical external URLs,
16
+ filename stem is a well-formed slug of lowercase letters, digits and
17
+ hyphens); `test/guidance/discovery-home.test.js` enforces that.
18
+
19
+ Companion home for engineer-facing docs: `docs/discovery/`.
20
+
21
+ Issue 322 carved out this subdir so a first-time contributor can land a
22
+ discovery brief without touching the methodology lock.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rcf-lite",
3
- "version": "0.32.3",
3
+ "version": "0.32.5",
4
4
  "type": "module",
5
5
  "description": "One-install tooling for the Requirements Confidence Framework (RCF): the unified `rcf` CLI grouped into the five RCF tool groups (discover, define, build, verify, audit) plus a small core set (init, doctor, guidance, mcp), an MCP server, the live tree viewer and the fresh-context adversarial ship-gate verifier. Consumes @stravica-ai/rcf-schemas.",
6
6
  "license": "Apache-2.0",
@@ -40,8 +40,24 @@
40
40
  # `npm install rcf-lite`.
41
41
 
42
42
  feedVersion: 1
43
- latest: "0.32.3"
43
+ latest: "0.32.5"
44
44
  releases:
45
+ - version: "0.32.5"
46
+ date: "2026-10-07"
47
+ breaking: false
48
+ headlines:
49
+ - "rcf-lite 0.32.5 ships two chain-shape fixes surfaced by Dex on the discovery-viewer-command-page branch (reporter). The dogfood walker in test/rcf-tree.test.js now mirrors the sidecar-ledger carve-out from src/define/ledgers.js by importing the new DEFINE_RELATIVE_DIR constant and ignoring rcf/define/, so the first `pnpm rcf define ledger brief add` on a fresh tree no longer blows up three dogfood assertions (issue 321). A new guidance/discovery/ (and companion docs/discovery/) subdir gives project discovery artefacts a predictable home outside the three locked methodology inventories; a first-time contributor can now land a discovery brief without touching the methodology lock or the pack manifest (issue 322). The 0.32.1 through 0.32.4 fixes carry forward unchanged."
50
+ minAgentAction: null
51
+ notesUrl: "https://stravica.ai/docs/rcf/changelog/"
52
+
53
+ - version: "0.32.4"
54
+ date: "2026-10-07"
55
+ breaking: false
56
+ headlines:
57
+ - "rcf-lite 0.32.4 is the stop-word follow-up to 0.32.3 after Dex's second-consumer check of PR 318 on WESPA (issue 319). Patterns 2 and 3 of extractThenFieldTokens (prose `<name> field` and `fields: <name>`) now share a broader English stop-word set and reuse pattern 4's file-extension and path-context skips, so the AC-130-1 WESPA then-clause `declares NO join-shaped fields: the earlier jurisdiction ...` stops reading `the` as a record field. Pattern 3 additionally walks a comma-separated list after `fields:` so a real prose field list such as `required fields: userID, email, createdAt` yields every token it names. The 0.32.1, 0.32.2 and 0.32.3 fixes carry forward unchanged."
58
+ minAgentAction: null
59
+ notesUrl: "https://stravica.ai/docs/rcf/changelog/"
60
+
45
61
  - version: "0.32.3"
46
62
  date: "2026-10-07"
47
63
  breaking: false
@@ -55,7 +55,15 @@ export const LEDGER_NAMES = /** @type {const} */ (['brief', 'decisions', 'concer
55
55
 
56
56
  /** @typedef {(typeof LEDGER_NAMES)[number]} LedgerName */
57
57
 
58
- const RELATIVE_DIR = 'rcf/define';
58
+ /**
59
+ * Project-root-relative directory the ledgers (and the freeze record) live in.
60
+ * Exported so any walker that enumerates `rcf/` can mirror the carve-out
61
+ * without a second hard-coded copy (issue 321).
62
+ */
63
+ export const DEFINE_RELATIVE_DIR = 'rcf/define';
64
+
65
+ // Legacy alias kept until all internal references migrate.
66
+ const RELATIVE_DIR = DEFINE_RELATIVE_DIR;
59
67
 
60
68
  /** Per-ledger config: filename, array key on the body, entry schema. */
61
69
  const LEDGER_CONFIG = /** @type {const} */ ({
@@ -2065,6 +2065,26 @@ const PATTERN_4_FILE_EXTENSION_SKIP = new Set([
2065
2065
  'mp4', 'mov', 'log',
2066
2066
  ]);
2067
2067
 
2068
+ // English stop-word skip for patterns 2 and 3 (prose field lists).
2069
+ // Issue 319 (0.32.4): 0.32.3 moved pattern 4's stop-word skip onto the
2070
+ // dot-notation branch but left the pattern 2/3 regex (`<name> field`
2071
+ // and `field: <name>` prose) with no stop-word filter at all, so a
2072
+ // then-clause like `declares NO join-shaped fields: the earlier
2073
+ // jurisdiction ...` fed `the` to the extractor as a field name. The
2074
+ // list below is the superset the issue brief named: subject/object
2075
+ // stop words, articles, prepositions, demonstratives, auxiliaries and
2076
+ // WH-words that have ever been observed sitting next to `field` or
2077
+ // after `fields:` in a plain English sentence. Patterns 2 and 3 skip a
2078
+ // token drawn from this set unconditionally; pattern 4 keeps its own
2079
+ // small stop-word guard as belt-and-braces behind the shape-name gate.
2080
+ const STOP_PATTERN_23 = new Set([
2081
+ 'the', 'a', 'an', 'and', 'or', 'of', 'to', 'in', 'on', 'for', 'with',
2082
+ 'by', 'from', 'at', 'as', 'is', 'are', 'be', 'this', 'that', 'these',
2083
+ 'those', 'it', 'its', 'not', 'no', 'all', 'any', 'each', 'per', 'via',
2084
+ 'into', 'than', 'then', 'when', 'which', 'who', 'whom', 'where',
2085
+ 'while',
2086
+ ]);
2087
+
2068
2088
  /**
2069
2089
  * Pull field tokens out of a `then` clause. A field token is a word
2070
2090
  * that follows a verb like `set`, `write`, `include`, `return`,
@@ -2099,22 +2119,56 @@ function extractThenFieldTokens(thenClause, shapeNames = new Set()) {
2099
2119
  const text = stripQuotedSubstrings(thenClause);
2100
2120
  /** @type {Set<string>} */
2101
2121
  const tokens = new Set();
2122
+ // Pattern 4's local stop set is the small guard it has carried since
2123
+ // 0.32.3; the broader pattern 2/3 list lives at module scope as
2124
+ // STOP_PATTERN_23 (issue 319).
2102
2125
  const STOP = new Set(['the', 'a', 'an', 'this', 'that', 'its', 'our', 'their', 'any', 'no', 'some', 'each', 'every', 'another']);
2103
2126
 
2104
- // Pattern 2 (preserved): `<name> field` (adjective-form naming). The
2105
- // backtick around the name is optional; the stop-word skip keeps
2106
- // "the field", "a field" and "its field" from tripping the check.
2127
+ // Pattern 2 (narrowed, issue 319): `<name> field` (adjective-form
2128
+ // naming). The backtick around the name is optional. 0.32.3 and
2129
+ // earlier only skipped a short set of articles and demonstratives,
2130
+ // and never skipped file-extension tokens or path-context contexts
2131
+ // on this branch. Pattern 2 now shares the broader STOP_PATTERN_23
2132
+ // list and reuses pattern 4's file-extension and path-context
2133
+ // skips so a prose phrase like `report.json field` or `/path/x
2134
+ // field` does not read a filename stem or path fragment as a
2135
+ // record field.
2107
2136
  for (const m of text.matchAll(/`?\b([A-Za-z_][A-Za-z0-9_]*)`?\s+field\b/g)) {
2108
2137
  const token = m[1];
2109
2138
  if (!token) continue;
2110
- if (STOP.has(token.toLowerCase())) continue;
2139
+ if (STOP_PATTERN_23.has(token.toLowerCase())) continue;
2140
+ if (PATTERN_4_FILE_EXTENSION_SKIP.has(token.toLowerCase())) continue;
2141
+ const start = m.index ?? 0;
2142
+ const beforeHead = text.slice(Math.max(0, start - 2), start);
2143
+ if (/\//.test(beforeHead)) continue;
2111
2144
  tokens.add(token);
2112
2145
  }
2113
- // Pattern 3 (preserved): `field: <name>` or `field = <name>`
2114
- // (schema-like notation inside a then clause). The name's backtick
2115
- // is optional.
2116
- for (const m of text.matchAll(/\bfields?\s*[:=]\s*`?([A-Za-z_][A-Za-z0-9_]*)`?/g)) {
2117
- if (m[1]) tokens.add(m[1]);
2146
+ // Pattern 3 (narrowed, issue 319): `fields: <name>` or `fields =
2147
+ // <name>` (schema-like notation inside a then clause). Walks a
2148
+ // comma-separated list after the colon so prose like `required
2149
+ // fields: userID, email, createdAt` yields all three candidates,
2150
+ // not just the first. Three skips apply to every candidate:
2151
+ // - STOP_PATTERN_23 (English stop words such as `the` from
2152
+ // `declares NO join-shaped fields: the earlier jurisdiction
2153
+ // ...`, the AC-130-1 WESPA shape in issue 319);
2154
+ // - PATTERN_4_FILE_EXTENSION_SKIP (file-extension tokens such
2155
+ // as `md`, `json`, `yaml`);
2156
+ // - path context (two characters before `fields:` contain `/`),
2157
+ // mirroring pattern 4's path-context guard so a prose line
2158
+ // inside a path reference does not read as a field list.
2159
+ for (const m of text.matchAll(/\bfields?\s*[:=]\s*(`?[A-Za-z_][A-Za-z0-9_]*`?(?:\s*,\s*`?[A-Za-z_][A-Za-z0-9_]*`?)*)/g)) {
2160
+ const start = m.index ?? 0;
2161
+ const beforeHead = text.slice(Math.max(0, start - 2), start);
2162
+ if (/\//.test(beforeHead)) continue;
2163
+ const list = m[1];
2164
+ if (!list) continue;
2165
+ for (const raw of list.split(/\s*,\s*/)) {
2166
+ const name = raw.replace(/^`/, '').replace(/`$/, '');
2167
+ if (!name) continue;
2168
+ if (STOP_PATTERN_23.has(name.toLowerCase())) continue;
2169
+ if (PATTERN_4_FILE_EXTENSION_SKIP.has(name.toLowerCase())) continue;
2170
+ tokens.add(name);
2171
+ }
2118
2172
  }
2119
2173
  // Pattern 4 (narrowed, issue 315): `<ShapeName>.<fieldName>` dot
2120
2174
  // notation. Shape names are PascalCase. 0.32.2 emitted a field