rcf-lite 0.32.3 → 0.32.4
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 +8 -0
- package/fixtures/canary-manifest.json +6 -6
- package/package.json +1 -1
- package/releases/releases.yaml +9 -1
- package/src/query/gates.js +63 -9
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,14 @@ 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.4] - 2026-10-07
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **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.
|
|
16
|
+
|
|
9
17
|
## [0.32.3] - 2026-10-07
|
|
10
18
|
|
|
11
19
|
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-
|
|
6
|
-
"buildVersion": "0.32.
|
|
5
|
+
"createdAt": "2026-10-07T11:27:52.587Z",
|
|
6
|
+
"buildVersion": "0.32.4-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-
|
|
39
|
-
"buildVersion": "0.32.
|
|
38
|
+
"createdAt": "2026-10-07T11:27:52.588Z",
|
|
39
|
+
"buildVersion": "0.32.4-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-
|
|
72
|
-
"buildVersion": "0.32.
|
|
71
|
+
"createdAt": "2026-10-07T11:27:52.588Z",
|
|
72
|
+
"buildVersion": "0.32.4-mockdriver",
|
|
73
73
|
"fixturePromptId": "canary-prompt-03",
|
|
74
74
|
"responseWordCount": 55,
|
|
75
75
|
"grades": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rcf-lite",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.4",
|
|
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",
|
package/releases/releases.yaml
CHANGED
|
@@ -40,8 +40,16 @@
|
|
|
40
40
|
# `npm install rcf-lite`.
|
|
41
41
|
|
|
42
42
|
feedVersion: 1
|
|
43
|
-
latest: "0.32.
|
|
43
|
+
latest: "0.32.4"
|
|
44
44
|
releases:
|
|
45
|
+
- version: "0.32.4"
|
|
46
|
+
date: "2026-10-07"
|
|
47
|
+
breaking: false
|
|
48
|
+
headlines:
|
|
49
|
+
- "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."
|
|
50
|
+
minAgentAction: null
|
|
51
|
+
notesUrl: "https://stravica.ai/docs/rcf/changelog/"
|
|
52
|
+
|
|
45
53
|
- version: "0.32.3"
|
|
46
54
|
date: "2026-10-07"
|
|
47
55
|
breaking: false
|
package/src/query/gates.js
CHANGED
|
@@ -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 (
|
|
2105
|
-
// backtick around the name is optional
|
|
2106
|
-
//
|
|
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 (
|
|
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 (
|
|
2114
|
-
// (schema-like notation inside a then clause).
|
|
2115
|
-
//
|
|
2116
|
-
|
|
2117
|
-
|
|
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
|