speclock 4.5.0 → 4.5.1

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": "4.5.0",
5
+ "version": "4.5.1",
6
6
 
7
7
  "description": "AI constraint engine with Gemini LLM universal detection, Policy-as-Code DSL, OAuth/OIDC SSO, admin dashboard, telemetry, API key auth, RBAC, AES-256-GCM encryption, hard enforcement, semantic pre-commit, HMAC audit chain, SOC 2/HIPAA compliance. Cross-platform: MCP + direct API. 31 MCP tools + CLI. Enterprise platform.",
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 v4.5.0 — AI Constraint Engine (Gemini LLM + Policy-as-Code + SSO + Dashboard + Telemetry + Auth + RBAC + Encryption)
120
+ SpecLock v4.5.1 — AI Constraint Engine (Gemini LLM + Policy-as-Code + SSO + Dashboard + Telemetry + 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 = "4.5.0";
12
+ const VERSION = "4.5.1";
13
13
 
14
14
  // PHI-related keywords for HIPAA filtering
15
15
  const PHI_KEYWORDS = [
@@ -1964,10 +1964,34 @@ export function scoreConflict({ actionText, lockText }) {
1964
1964
  }
1965
1965
  }
1966
1966
 
1967
+ // Check 3b: Safe/verification verbs against preservation/maintenance locks
1968
+ // "Test that Stripe is working" is COMPLIANT with "must always use Stripe"
1969
+ // "Debug the Stripe webhook" is COMPLIANT — it's verifying the preserved system
1970
+ if (!intentAligned && actionPrimaryVerb) {
1971
+ const lockIsPreservation = /must remain|must be preserved|must always|at all times|must stay/i.test(lockText);
1972
+
1973
+ if (lockIsPreservation) {
1974
+ const SAFE_FOR_PRESERVATION = new Set([
1975
+ "test", "verify", "check", "validate", "confirm", "ensure",
1976
+ "debug", "inspect", "review", "examine", "monitor", "observe",
1977
+ "watch", "scan", "detect", "audit", "report", "document",
1978
+ "read", "view", "generate", "fix", "repair", "patch",
1979
+ "protect", "secure", "guard", "maintain", "preserve",
1980
+ ]);
1981
+ if (SAFE_FOR_PRESERVATION.has(actionPrimaryVerb)) {
1982
+ intentAligned = true;
1983
+ reasons.push(
1984
+ `intent alignment: verification/maintenance "${actionPrimaryVerb}" is ` +
1985
+ `compliant with preservation lock`);
1986
+ }
1987
+ }
1988
+ }
1989
+
1967
1990
  // Check 4: Enhancement/constructive actions against preservation/maintenance locks
1968
1991
  // "Increase the rate limit" is COMPLIANT with "rate limiting must remain active"
1969
1992
  // "Add better rate limit error messages" is COMPLIANT (doesn't disable rate limiting)
1970
1993
  // But "Add a way to bypass rate limiting" is NOT safe (contains negative op "bypass")
1994
+ // And "Add Razorpay" vs "must always use Stripe" is NOT safe (competing alternative)
1971
1995
  if (!intentAligned && actionPrimaryVerb) {
1972
1996
  const ENHANCEMENT_VERBS = new Set([
1973
1997
  "increase", "improve", "enhance", "boost", "strengthen",
@@ -1986,15 +2010,23 @@ export function scoreConflict({ actionText, lockText }) {
1986
2010
  `intent alignment: enhancement action "${actionPrimaryVerb}" is ` +
1987
2011
  `compliant with preservation lock`);
1988
2012
  } else if (CONSTRUCTIVE_FOR_PRESERVATION.has(actionPrimaryVerb)) {
1989
- // Constructive verbs align ONLY if the action doesn't contain negative ops
2013
+ // Constructive verbs align ONLY if:
2014
+ // 1. No negative operations in the action
2015
+ // 2. The action doesn't introduce a COMPETING alternative
2016
+ // "Add Razorpay" vs "must always use Stripe" → competitor (same synonym group)
2017
+ // "Add dark mode" vs "must always use Stripe" → unrelated (safe)
1990
2018
  const actionLower = actionText.toLowerCase();
1991
2019
  const hasNegativeOp = NEGATIVE_INTENT_MARKERS.some(m =>
1992
2020
  new RegExp(`\\b${escapeRegex(m)}\\b`, "i").test(actionLower));
1993
- if (!hasNegativeOp) {
2021
+ // Check if action introduces a competing product/brand from the same category
2022
+ const hasCompetitorMatch = subjectComparison.matchedSubjects.some(m =>
2023
+ typeof m === "string" && m.startsWith("synonym:")
2024
+ );
2025
+ if (!hasNegativeOp && !hasCompetitorMatch) {
1994
2026
  intentAligned = true;
1995
2027
  reasons.push(
1996
2028
  `intent alignment: constructive "${actionPrimaryVerb}" is ` +
1997
- `compliant with preservation lock (no negative operations)`);
2029
+ `compliant with preservation lock (no negative operations, no competitor)`);
1998
2030
  }
1999
2031
  }
2000
2032
  }
@@ -257,7 +257,7 @@ export async function flushToRemote(root) {
257
257
  // Build anonymized payload
258
258
  const payload = {
259
259
  instanceId: summary.instanceId,
260
- version: "4.5.0",
260
+ version: "4.5.1",
261
261
  totalCalls: summary.totalCalls,
262
262
  avgResponseMs: summary.avgResponseMs,
263
263
  conflicts: summary.conflicts,
@@ -89,7 +89,7 @@
89
89
  <div class="header">
90
90
  <div>
91
91
  <h1><span>SpecLock</span> Dashboard</h1>
92
- <div class="meta">v4.5.0 &mdash; AI Constraint Engine</div>
92
+ <div class="meta">v4.5.1 &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 v4.5.0 &mdash; Developed by Sandeep Roy &mdash; <a href="https://github.com/sgroy10/speclock" style="color:var(--accent)">GitHub</a>
185
+ SpecLock v4.5.1 &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>
@@ -91,7 +91,7 @@ import { fileURLToPath } from "url";
91
91
  import _path from "path";
92
92
 
93
93
  const PROJECT_ROOT = process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
94
- const VERSION = "4.5.0";
94
+ const VERSION = "4.5.1";
95
95
  const AUTHOR = "Sandeep Roy";
96
96
  const START_TIME = Date.now();
97
97
 
package/src/mcp/server.js CHANGED
@@ -100,7 +100,7 @@ const PROJECT_ROOT =
100
100
  args.project || process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
101
101
 
102
102
  // --- MCP Server ---
103
- const VERSION = "4.5.0";
103
+ const VERSION = "4.5.1";
104
104
  const AUTHOR = "Sandeep Roy";
105
105
 
106
106
  const server = new McpServer(