speclock 5.2.4 → 5.2.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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  "name": "speclock",
4
4
 
5
- "version": "5.2.4",
5
+ "version": "5.2.5",
6
6
 
7
7
  "description": "AI Constraint Engine — AI Patch Firewall. Diff-native review (interface breaks, protected symbols, dependency drift, schema changes, API impact), Patch Gateway (ALLOW/WARN/BLOCK verdicts), Spec Compiler (NL→constraints), Code Graph (blast radius, lock-to-file mapping), Typed constraints, REST API v2, Python SDK, ROS2 integration. 42 MCP tools, Gemini LLM hybrid, HMAC audit chain, RBAC, encryption, SOC 2/HIPAA compliance.",
8
8
 
package/src/cli/index.js CHANGED
@@ -117,7 +117,7 @@ function refreshContext(root) {
117
117
 
118
118
  function printHelp() {
119
119
  console.log(`
120
- SpecLock v5.2.4 — AI Constraint Engine (Spec Compiler + Code Graph + Typed Constraints + Python SDK + ROS2 + REST API v2 + Gemini LLM + Policy-as-Code + Auth + RBAC + Encryption)
120
+ SpecLock v5.2.5 — AI Constraint Engine (Spec Compiler + Code Graph + Typed Constraints + Python SDK + ROS2 + REST API v2 + Gemini LLM + Policy-as-Code + Auth + RBAC + Encryption)
121
121
  Developed by Sandeep Roy (github.com/sgroy10)
122
122
 
123
123
  Usage: speclock <command> [options]
@@ -9,7 +9,7 @@
9
9
  import { readBrain, readEvents } from "./storage.js";
10
10
  import { verifyAuditChain } from "./audit.js";
11
11
 
12
- const VERSION = "5.2.4";
12
+ const VERSION = "5.2.5";
13
13
 
14
14
  // PHI-related keywords for HIPAA filtering
15
15
  const PHI_KEYWORDS = [
@@ -91,7 +91,7 @@ export const SYNONYM_GROUPS = [
91
91
  "private key", "access key", "api secret", "api token",
92
92
  "credentials", "credential"],
93
93
  ["frontend", "frontend code", "client-side", "client side",
94
- "browser", "react state", "ui component"],
94
+ "browser", "react state", "ui component", "ui"],
95
95
 
96
96
  // --- Dependencies ---
97
97
  ["dependency", "package", "library", "module", "import", "require",
@@ -239,6 +239,7 @@ export const EUPHEMISM_MAP = {
239
239
  "streamline": ["remove", "simplify", "modify", "reduce", "weaken", "bypass", "disable"],
240
240
  "optimize": ["modify", "change", "remove", "reduce"],
241
241
  "modernize": ["replace", "rewrite", "change"],
242
+ "reorganize": ["modify", "change", "tamper", "alter"],
242
243
  "revamp": ["replace", "rewrite", "change"],
243
244
  "overhaul": ["replace", "rewrite", "change", "modify"],
244
245
  "refresh": ["replace", "update", "change"],
@@ -771,6 +772,11 @@ export const CONCEPT_MAP = {
771
772
  "denied applications": ["application decisions", "application processing",
772
773
  "benefits decisions"],
773
774
 
775
+ // Privacy / data protection
776
+ "privacy": ["confidential", "pii", "personal data", "data protection",
777
+ "restricted access"],
778
+ "confidential": ["privacy", "private", "restricted", "pii", "data protection"],
779
+
774
780
  // Telecom / billing
775
781
  "call records": ["cdr", "call data", "telecom records", "billing records"],
776
782
  "subscriber data": ["customer data", "user data", "telecom records"],
@@ -782,12 +788,12 @@ export const CONCEPT_MAP = {
782
788
  "user location", "pii"],
783
789
 
784
790
  // Frontend frameworks (alternatives = change framework conflict)
785
- "react": ["frontend framework", "ui framework", "vue", "angular",
786
- "svelte", "sveltekit", "next.js", "nextjs"],
787
- "vue": ["frontend framework", "ui framework", "react", "angular",
788
- "svelte", "sveltekit", "nuxt"],
789
- "vue 3": ["frontend framework", "ui framework", "react", "angular",
790
- "svelte", "sveltekit", "nuxt", "vue"],
791
+ "react": ["frontend framework", "ui framework", "frontend", "ui",
792
+ "vue", "angular", "svelte", "sveltekit", "next.js", "nextjs"],
793
+ "vue": ["frontend framework", "ui framework", "frontend", "ui",
794
+ "react", "angular", "svelte", "sveltekit", "nuxt"],
795
+ "vue 3": ["frontend framework", "ui framework", "frontend", "ui",
796
+ "react", "angular", "svelte", "sveltekit", "nuxt", "vue"],
791
797
  "vue.js": ["frontend framework", "ui framework", "react", "angular",
792
798
  "svelte", "sveltekit", "nuxt", "vue"],
793
799
  "svelte": ["frontend framework", "ui framework", "react", "vue",
@@ -806,6 +812,11 @@ export const CONCEPT_MAP = {
806
812
  "ui framework", "next.js", "nuxt"],
807
813
  "ui framework": ["frontend framework", "react", "vue", "angular",
808
814
  "svelte", "sveltekit"],
815
+ "tech stack": ["frontend framework", "backend framework", "react", "vue",
816
+ "angular", "svelte", "express", "django", "technology stack"],
817
+ "technology stack": ["tech stack", "frontend framework", "backend framework"],
818
+ "application framework": ["frontend framework", "backend framework", "react",
819
+ "vue", "angular", "express", "django"],
809
820
 
810
821
  // Backend frameworks (alternatives = change backend conflict)
811
822
  "express": ["backend framework", "fastify", "koa", "hapi", "nestjs"],
@@ -1049,6 +1060,15 @@ export function tokenize(text) {
1049
1060
  }
1050
1061
  }
1051
1062
 
1063
+ // Split hyphenated tokens — "react-based" also adds "react", "based"
1064
+ for (const w of [...rawWords]) {
1065
+ if (w.includes('-')) {
1066
+ for (const part of w.split('-')) {
1067
+ if (part.length >= 2 && !rawWords.includes(part)) rawWords.push(part);
1068
+ }
1069
+ }
1070
+ }
1071
+
1052
1072
  // Basic plural normalization — add both singular and plural forms
1053
1073
  // so "databases" matches "database" and vice versa
1054
1074
  const words = [...rawWords];
@@ -2442,7 +2462,10 @@ export function scoreConflict({ actionText, lockText }) {
2442
2462
  if (!intentAligned && !hasStrongVocabMatch && !_hasStructuralVerbWithOverlap) {
2443
2463
  const actionLower = actionText.toLowerCase();
2444
2464
  const actionWords = actionLower.split(/\s+/).map(w => w.replace(/[^a-z]/g, ""));
2445
- const hasUISubject = actionWords.some(w => UI_COSMETIC_WORDS.has(w));
2465
+ // Guard: "background" in "background check/screening/process" is NOT cosmetic CSS
2466
+ const _hasNonCosmeticBackground = /\bbackground\s+(?:check|screening|investigation|process|task|job|worker|service)\b/i.test(actionLower);
2467
+ const hasUISubject = actionWords.some(w =>
2468
+ UI_COSMETIC_WORDS.has(w) && !(w === "background" && _hasNonCosmeticBackground));
2446
2469
  if (hasUISubject) {
2447
2470
  intentAligned = true;
2448
2471
  reasons.push(
@@ -89,7 +89,7 @@
89
89
  <div class="header">
90
90
  <div>
91
91
  <h1><span>SpecLock</span> Dashboard</h1>
92
- <div class="meta">v5.2.4 &mdash; AI Constraint Engine</div>
92
+ <div class="meta">v5.2.5 &mdash; AI Constraint Engine</div>
93
93
  </div>
94
94
  <div style="display:flex;align-items:center;gap:12px;">
95
95
  <span id="health-badge" class="status-badge healthy">Loading...</span>
@@ -182,7 +182,7 @@
182
182
  </div>
183
183
 
184
184
  <div style="text-align:center;padding:24px;color:var(--muted);font-size:12px;">
185
- SpecLock v5.2.4 &mdash; Developed by Sandeep Roy &mdash; <a href="https://github.com/sgroy10/speclock" style="color:var(--accent)">GitHub</a>
185
+ SpecLock v5.2.5 &mdash; Developed by Sandeep Roy &mdash; <a href="https://github.com/sgroy10/speclock" style="color:var(--accent)">GitHub</a>
186
186
  </div>
187
187
 
188
188
  <script>
@@ -113,7 +113,7 @@ import { fileURLToPath } from "url";
113
113
  import _path from "path";
114
114
 
115
115
  const PROJECT_ROOT = process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
116
- const VERSION = "5.2.4";
116
+ const VERSION = "5.2.5";
117
117
  const AUTHOR = "Sandeep Roy";
118
118
  const START_TIME = Date.now();
119
119
 
package/src/mcp/server.js CHANGED
@@ -120,7 +120,7 @@ const PROJECT_ROOT =
120
120
  args.project || process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
121
121
 
122
122
  // --- MCP Server ---
123
- const VERSION = "5.2.4";
123
+ const VERSION = "5.2.5";
124
124
  const AUTHOR = "Sandeep Roy";
125
125
 
126
126
  const server = new McpServer(