Skip to content

Releases: golab-arch/synaptic-sentinel

v0.3.22 — FASE III complete: trust cross-session

Choose a tag to compare

@golab-arch golab-arch released this 08 Jul 19:14

SYNAPTIC Sentinel v0.3.22 — FASE III complete: trust cross-session

Three empirically validated DGs deliver per-fingerprint verdict persistence, cross-finding correlation via grouping, and diff-aware CI/CD integration.

Users now visually see cross-scan verdict drift, provider shifts, confidence deltas, and grouping propagation with reason categorization + delta metrics. The "trust cross-session" behavior FASE III set out to build is empirically REALIZED across 5-baseline trajectories in real user workspaces.

Install from VSIX: download synaptic-sentinel-0.3.22.vsix below and run code --install-extension synaptic-sentinel-0.3.22.vsix or use Install from VSIX... in the Extensions view. Marketplace publish is a separate cycle (still on v0.3.3 — 19-version gap; catching up planned).


What's new (headline features)

🕰️ Verdict history + Previously section (DG-130 A)

Every finding card in the sidebar now shows a collapsible Previously (N prior verdicts) section — the full triage history for that fingerprint (timestamp + provider label + full rationale), preserved across every scan you've ever run. Change providers, re-triage, come back a week later — the trajectory is one click away.

⚠ Verdict-changed banner with reason heuristic (DG-130 A)

When the current triage verdict differs from the previous, the finding card shows a warning banner explaining why:

  • Different provider (deepseek/v4-flash → anthropic/haiku-4-5) — cross-provider agreement is not guaranteed.
  • Verdict reclassified — likely new context signals available.
  • Confidence changed significantly (Δ 0.30).

Reason precedence: provider > class > confidence-delta (threshold 0.15). Empirically validated on 5+ real findings in a single re-triage cycle.

🔗 Cross-finding grouping (DG-131 A — R20)

When N ≥ 2 findings share the same rule + package + version, only the group representative pays the LLM token cost. Members inherit the verdict with a 0.9× confidence downgrade (epistemic honesty: high confidence on the group, medium on each member individually). Sidebar renders GROUPED REP (purple) and GROUPED (lighter purple) badges + a [group SCA:pkg@ver:CVE, member N of M] rationale suffix.

Empirical impact (Baseline-15 in SYNAPTIC_SAAS): 12 LLM calls saved in a single re-triage — 44 findings triaged with only 8 LLM calls + 24 colony-memory + 12 propagated members. 20% cost reduction on that specific workload.

CLI escape hatch: synaptic-sentinel triage --no-group disables grouping globally.

📊 Diff-aware line with reason breakdown (DG-132 A — R22)

Both the terminal and the sidebar summary card now emit:

Scan diff vs previous triage: 1 new · 9 re-classified (0 class, 9 confidence, 0 provider) · 34 unchanged

Every reclassified finding is categorized by reason. The empirical gap of the earlier basic diff (5 confidence-changed findings counting as "unchanged" despite the banner) is now closed — the summary line and the banner agree.

🚦 Diff-aware CI/CD gates + JSON export (DG-132 A)

New CLI command synaptic-sentinel diff --json for structured output tailored to CI/CD tooling:

{
  "scanId": "",
  "summary": { "newFindings": 1, "reclassified": 9, "unchanged": 34 },
  "reclassifiedByReason": { "classChanged": 0, "confidenceDelta": 9, "providerChanged": 0 },
  "newFindings": [{ "fingerprint", "ruleId", "severity", "location", "title" }],
  "reclassified": [{ "", "reason", "from", "to", "confidenceDelta", "fromConfidence", "toConfidence", "fromProvider", "toProvider" }],
  "unchanged": [{ "" }]
}

Per-severity gates on the triage command:

  • --fail-on-new-tp-critical <n> — exit code 1 if new/reclassified-to-TP critical findings exceed N.
  • --fail-on-new-tp-high <n> — same for high.
  • --fail-on-new-tp-medium <n> — same for medium.

Example: synaptic-sentinel triage --re-triage --fail-on-new-tp-critical 0 --fail-on-new-tp-high 3 — zero tolerance for new critical + tolerate up to 3 new high per PR.


The cross-provider reproducibility gap, empirically collected

FASE III collected a dramatic real-world data point in SYNAPTIC_SAAS. The same finding (fast-xml-parser CVE-2026-41650, same code, same lockfile) drifted like this across 5 scans and 2 providers:

Baseline Provider Verdict Confidence
14a deepseek/v4-flash Inconclusive 0.50
14b deepseek/v4-flash Inconclusive 1.00
15 deepseek/v4-flash Inconclusive 0.90
03:11 deepseek/v4-pro Inconclusive 1.00
16 deepseek/v4-pro Inconclusive 0.00 (JsonParseError)

Before v0.3.22 this shift would be invisible — the sidebar would just show the latest verdict and users would either trust it or not. Now the Previously section shows the entire trajectory, the banner explains the delta, and the diff summary counts it correctly. Trust cross-session is not a slogan; it is a measurable UX property.


Hotfixes shipped in this release

  • DG-131.0.1 (placebo — kept for record) — replaced a silent try-catch in the schema v7 ALTER TABLE ADD COLUMN path with explicit PRAGMA table_info check. Turned out to be in a code path that never ran on existing v6 DBs — masked the real bug fixed by DG-131.0.2.
  • DG-131.0.2 (real fix) — root cause identified via node + node-sqlite3-wasm inspection of the real user's colony.db: the schema.sql file had CREATE INDEX IF NOT EXISTS idx_*_group_id ON <table>(group_id) statements running BEFORE the ALTER TABLE in JS. On existing v6 DBs, CREATE TABLE IF NOT EXISTS skipped (table exists without column), then CREATE INDEX failed with "no such column: group_id" aborting the whole migration. Fix: move those CREATE INDEX statements from schema.sql to colony-db.ts (after the ALTER). Empirically pre-ship verified on a clone of the real user's v6 DB: schema 6→7 bumped cleanly, 49 verdicts preserved, columns + indexes created without errors.

Institutional lesson learned reinforced: SIEMPRE empirical inspection FIRST before speculative fixes.


Known tradeoffs (honest, non-optimistic)

  • Sidebar interactive chip filter NOT in v1 — deferred. Users who want to filter by diff status (new / reclassified / unchanged) must scroll or use synaptic-sentinel diff --json for programmatic filtering.
  • Group representative choice = members[0] — deterministic but not necessarily "best" (highest severity + reachability). Trade-off acceptable for v1.
  • findingGroupKey uses literal ruleId — two distinct CVEs on the same package do NOT group. More cautious posture; acceptable v1.
  • Context + Remediation only for group representative — members inherit the triage verdict but have no context/remediation of their own. The GROUPED badge signals the semantics live in the representative.
  • Confidence downgrade factor 0.9 is opinionated — matches the design goal (high confidence on the group, medium on each member individually).
  • Cost varies significantly across providers — Baseline-16 with deepseek-v4-pro cost 4× Baseline-15 with deepseek-v4-flash on identical workload; v4-pro also produced 3 JsonParseError degradations vs 0 for v4-flash. BYOK design preserves user choice.
  • FASE III took 5 vsix updates (step-130-1 + step-131-1 broken + step-131-2 placebo + step-131-3 real + step-132-1) — user install fatigue moderate. Trade-off vs correctness.
  • User's agents.yaml config bug persistent (not FASE III related) — context=Anthropic + remediation=Anthropic with model: deepseek-v4-pro triggers 404 errors on 46 calls per scan. Better error messages are a follow-up candidate.
  • Migration test coverage gap — no unit test for the v6→v7 schema migration path (requires manual setup). Empirical pre-ship testing on a real user DB clone was the workaround.
  • N=1 empirical sample per baseline — 5 baselines in a single workspace is strong evidence but not conclusive.

Testing + verification

  • pnpm verify VERDE: 70 test files / 894 tests / 3 skipped + manifest gate + activation gate (9 commands + 15 subscriptions).
  • Test growth from v0.3.17 → v0.3.22: +115 tests cumulative across all FASE III DGs (17 DG-130 A + 18 DG-131 A + 9 DG-132 A + others).
  • Empirical validation trajectory: Baseline-14 (DG-130 A) → Baseline-15 (DG-131 A post-hotfixes) → Baseline-16 (DG-132 A). Total FASE III duration: 3 days vs estimate 4-6 weeks.

Install

# From the vsix file attached to this release:
code --install-extension synaptic-sentinel-0.3.22.vsix

# Or in VS Code: Extensions → "..." → Install from VSIX...

Clean-install strongly recommended for the schema v7 migration (a lesson from FASE III's hotfix cascade — old cached extension bundles can interfere):

# 1. Close ALL VSCode windows
# 2. Task Manager → End Task on all Code.exe processes
# 3. Clean any prior installs (wildcard):
Remove-Item -Recurse -Force "$env:USERPROFILE\.vscode\extensions\realgolab.synaptic-sentinel-*"
# 4. Install from VSIX in a fresh VSCode window

Roadmap next

FASE IV backlog attack. Priority candidates (empirically motivated by Baseline-16 friction and side observations across FASE III):

  1. R25 sidebar interactive chip filter (DG-132.0.1 reactive) — completes the Sub-A2 v2 promise from Baseline-16.
  2. Better agents.yaml config validation error messages — help users discover their model/provider mismatch faster (currently manifests as 46 opaque 404s).
  3. R21 SBOM export (SPDX / CycloneDX) — compliance workflows.

The full backlog lives in docs/SENTINEL_COMPETITIVE_RESEARCH.md §12.


Apache-2.0 · SYNAPTIC family · Built by GoLab · Empirical validation is not optional.

v0.3.17 — R18 v1 Interaction Graph Layer + telemetry + critical TS ESM resolver fix

Choose a tag to compare

@golab-arch golab-arch released this 01 Jul 16:39

Interaction Graph Layer (R18 v1) infrastructure + telemetry + critical TypeScript ESM resolver fix (Cycle 111, DG-123 A + DG-123.0.1 + DG-123.0.2).

Adds a file-level Interaction Graph to the Coordinator — every Finding in a supported language (TS/TSX/JS/Python) now carries fileContext (role + imports/importedBy) and symbolContext (top-level symbols) that the Brain Layer receives as part of the Triage prompt. Ships with Output-channel telemetry to observe the graph, plus a critical hotfix for the resolver that made it useful for TypeScript ESM projects (specifiers ending in .js).

Empirical classification (Baseline-8d in SENTINEL workspace): H1.5-implicit

The graph builds correctly with rich data (e.g. colony-db.ts role=library imports=1 importedBy=3 symbols=14), the LLM (Sonnet-4.6 via deepseek-v4-flash) produces sophisticated rationales, but does NOT explicitly cite the graph section keywords (imported by, exports, library, entry). Interpretation: for intra-file findings (like SENTINEL's eval-usage and taint-command-injection), the graph context is structurally redundant — the verdict depends on local API usage. R18 v1's real value would surface on cross-module findings; symbol-level cross-file resolution (R18 v2) is documented backlog.

Added

  • DG-123 A — R18 v1 Interaction Graph Layer: new module interaction-graph.ts (~560 lines) with buildInteractionGraph(rootPath) two-pass walker (WASM parsing via web-tree-sitter@0.20.8 + tree-sitter-wasms@0.1.13 for 4 grammars, +5.87 MB uncompressed / +750 KB gzipped vsix bloat). Coordinator Stage 1.5b enriches each finding with fileContext + symbolContext. Triage + Context agents get a new "File interaction context" section in the prompt.
  • DG-123.0.1 — Telemetry via ScanOptions callbacks: onInteractionGraphBuilt + onFindingEnriched best-effort callbacks; CLI wires to [DG-123 A] prefixed lines in the terminal output.
  • DG-123.0.2 — Critical resolver fix for TypeScript ESM: EXTENSION_SUBSTITUTES table maps .js → [.ts, .tsx, .jsx], .mjs → [.mts], .cjs → [.cts], .jsx → [.tsx]. Without this fix, 100% of relative imports in TS ESM projects failed to resolve (Baseline-8c evidence).

Known Issues / Honest tradeoffs

  • LLM utilization is workload-dependent — intra-file findings see structurally redundant graph context; cross-module findings should benefit more (R18 v2 backlog).
  • Only 4 languages in v1 (TS/TSX/JS/Python).
  • Only relative static imports resolve — bare imports (react, zod) return null.
  • role='leaf' has ambiguous semantics for importedByCount === 1 (R18 v1.1 refinement candidate).
  • First-scan latency +500ms-2s from WASM init + graph build (no cache yet).
  • Provider deepseek-v4-flash intermittently returned empty responses in Baselines 8c and 8d (Security check suppressed 2/2 fail, CORS flipped success → failure). Not a graph bug — separate follow-up (DG-125 A candidate).
  • Users of pre-release stepN.vsix (step8/step9) should re-install this release to see accurate role=library values (DG-123.0.2 cascade fix).

Notes

  • pnpm verify VERDE: 63 test files / 779 tests + manifest gate + activation gate. Test growth from v0.3.16: +16 tests (763 → 779).
  • vsce publish to VS Code Marketplace is not part of this release. Marketplace listing is on v0.3.3; 15 GitHub-only releases now accumulate (v0.3.4 → v0.3.17). To install: download synaptic-sentinel-0.3.17.vsix and use code --install-extension synaptic-sentinel-0.3.17.vsix or Install from VSIX... in the Extensions view.
  • Roadmap next: R18 v1.1 (bare imports informational + symbol count refinement); R18 v2 (symbol-level cross-file); DG-125 A (provider intermittent-empty follow-up if persists).

Verification

  • File: synaptic-sentinel-0.3.17.vsix
  • Size: 4,135,298 bytes (3.94 MB), 1849 files
  • SHA-256: c7e6536ec34e0fea164a151c1baeea88d93b6df7e2bdb91c543899c26deca528

v0.3.16 — noise reduction + TP/risk split UX

Choose a tag to compare

@golab-arch golab-arch released this 31 May 03:08

SYNAPTIC Sentinel v0.3.16

Noise reduction + TP/risk split UX win (Cycles 108-109). Packages 3 substantial features accumulated since v0.3.15: a Coordinator-level scout exclude-list that cuts ~80% of structural noise from scan output, plus a new `priorityScore` concept that explicitly separates the LLM's confidence% from a real urgency-of-action signal — fixing the empirical user-confusion "the TP% reads as priority alongside severity" reported in the SENTINEL evaluation handoff.

What changed

  • DG-117 A — Scout exclude-list post-hoc filter (Cycle 108). The Coordinator now drops findings whose `location.path` contains a noise segment before stage 2 (dedup + fp_known). Initial set: `fixtures`, `fixtures`, `node_modules`, `dist`, `build`, `out`, `coverage`, `vendor`, `pycache`. Deliberate decision: no `test`/`tests` segment (would over-reach and silence legitimate auth/validation tests). Applies to ALL 5 scouts via Coordinator — no per-binary flag-syntax conversion.

  • DG-117.0.1 hotfix decimal — Empirical extension (Cycle 108). Baseline-6 revealed 3 noise patterns the initial set missed: `tests/benchmark/ground-truth.json`, `.scanners//...` (CLI-installer artifacts), and `.test.` / `.spec.` filenames. Added 2 segments (`benchmark`, `.scanners`) + new `DEFAULT_EXCLUDED_FILENAME_SUBSTRINGS = ['.test.', '.spec.']` matched against the last path segment. `isPathExcluded` signature extended to 3 args (backward-compatible). Result in SENTINEL workspace: 34 findings → 4 (-88% noise; only 2 real-code FPs + 2 meta-noise survive).

  • DG-118 A — TP/risk split (Cycle 109, backlog #5 from user-handoff). New field `Finding.priorityScore?: 'urgent' | 'high' | 'medium' | 'low' | 'noise'` computed deterministically by `computePriorityScore(severity, classification?)` with this matrix:

    Severity ↓ \ Triage → TP INC (demote) Untriaged FP
    critical urgent high urgent noise
    high high medium high noise
    medium medium low medium noise
    low low low low noise
    info low low low noise

    The sidebar now shows TWO badges side-by-side at the head of each card (severity + priority, deliberately different colors) plus a state badge on the right showing only `TP`/`INC`/`FP`/`NEW` — the confidence% is moved to a secondary line in the brain section with the explicit label `LLM confidence: N%`.

Empirical validation cross-workspace

Baseline-7 in `SYNAPTIC_SAAS`:

  • 37 findings with `priorityScore` populated 37/37
  • All 5 priority tiers present: urgent=2, high=16, medium=15, low=2, noise=2
  • Sanity matrix PASS: `noise ⇔ FP`, `urgent ⇔ critical+TP`, `(low, inconclusive) → low (floor)`, `(medium, inconclusive) → low (demote)`, `(high, inconclusive) → medium (demote)`
  • DG-115 A override directive (prismjs) INTACT — no regression
  • Severity↔priority divergence visualized correctly (e.g. CVE-2026-41650 medium-severity / low-priority due to INC demote)

Known design tradeoffs (honest, anti-optimismo)

  • `priorityScore` is per-finding; SCA grouped remediations (DG-113 A) show 1 action per package family. Observed during Baseline-7: `high=16` priority counts is dominated by ~14 protobufjs CVEs that collapse to one `Upgrade protobufjs to 7.5.8 / 8.2.0` remediation action. The two views disagree on "how much work." Surfacing priority at the group level is a future improvement candidate (`DG-future-group-priority`).
  • Severity ↔ priority divergence is by design, not a bug — that is the point of the split. The UI distinguishes them via different colors + position.
  • Hardcoded exclude-list (no `.sentinelignore` yet). If your project has a directory legitimately named `fixtures` / `benchmark` / `vendor` (production code), findings there are silenced. User-configurable exclude deferred to future sub-DG.
  • Exclude post-hoc filter doesn't save scout CPU — scouts still scan the noise paths; Coordinator just discards afterwards. Acceptable for current workspace sizes.
  • `inconclusive`-but-well-reasoned SAST taint verdicts carried over from v0.3.15 — unchanged, success by design.

Schema changes (additive, backward-compatible)

  • `FindingSchema`: `priorityScore?: 'urgent' | 'high' | 'medium' | 'low' | 'noise'` optional. Findings persisted in `colony.db` from earlier scans accept the absence; the UI falls back gracefully to severity-only rendering when missing.
  • `ScanOutcome.suppressedCount` now aggregates path-excluded findings + stage 2 dedup + fp_known suppression.
  • New export from `@synaptic-sentinel/core`: `computePriorityScore`, `PriorityScoreSchema`, `PRIORITY_SCORES`, `isPathExcluded`, `DEFAULT_EXCLUDED_PATH_SEGMENTS`, `DEFAULT_EXCLUDED_FILENAME_SUBSTRINGS`.

Installation

`vsce publish` to the VS Code Marketplace is not part of this release — the Marketplace listing is on v0.3.3 and 14 GitHub-only releases (v0.3.4 → v0.3.16) accumulate user-side publishing operations. To install in VS Code:

```
code --install-extension synaptic-sentinel-0.3.16.vsix
```

…or use Install from VSIX... in the Extensions view.

Artifact

  • `synaptic-sentinel-0.3.16.vsix` — 1838 files / 3.2 MB / 3,351,025 bytes
  • SHA-256: `c83380b4f0a0812e243949b2d69c0c711005a14dc081a290065bf19106fcfdb3`

Verification

  • `pnpm verify` VERDE: 62 test files / 763 tests + manifest gate (18 checks) + activation gate (9 commands + 15 subscriptions)
  • Test growth from v0.3.15: +56 tests (707 → 763) = +15 exclude (DG-117 A) + +12 hotfix extension (DG-117.0.1) + +29 priority-score matrix + webview render (DG-118 A)

v0.3.15 — prismjs misleading remediation fix + SOFT collapse

Choose a tag to compare

@golab-arch golab-arch released this 30 May 22:13

SYNAPTIC Sentinel v0.3.15

🎯 prismjs misleading remediation fix (DG-115 A + DG-115.1 A G7). Closes the 🚨 prismjs Known Issue declared in v0.3.14 release notes. SCA findings whose vulnerable copy is a transitive nested-pinned dep (e.g. prismjs@1.27.0 nested under refractor@3.6.0) now receive an override directive (npm overrides / yarn resolutions / pnpm.overrides) — a top-level bump alone does NOT honor the parent's pin and the sidebar now surfaces this.

What changed

  • DG-115 A — overrideDirective for transitive nested-pinned SCA. Trivy v0.70.0 already exposes Result.Packages[] with the full dep graph + PkgIdentifier.UID 1:1 matching; the normalizer now consumes it. Each Finding gains sca.dependencyContext { directness, pinnedBy, hasSiblingFixedCopy }. Each FindingGroup with at least one indirect finding + known package manager + known fix version gains remediation.overrideDirective { manager, packageName, versionRange, snippet, hasSiblingFixedCopy, pinnedBy[] }. The sidebar renders the directive as a dominant block above the children, with a Copy button (clipboard API + getSelection().selectAllChildren fallback) and cites the pinner in the risk caveat.
  • DG-115.1 A G7 — STRONG / SOFT visual hierarchy (webview-only refinement). STRONG (hasSiblingFixedCopy: true, e.g. prismjs) stays prominently expanded red. SOFT (hasSiblingFixedCopy: false, ~8 findings per scan: protobufjs / node-forge / fast-uri / uuid / etc.) is now collapsed by default inside a <details> with a one-liner summary "Transitive (via <pinnedBy[0]>) — plain bump usually works; override if it persists (<manager>)". The body (caveat + plain bump line + snippet + Copy + risk caveat) is revealed on expand. Data of the tomo is unchanged.

Known Issues retired

The 🚨 prismjs warning from v0.3.14 is retired. Override directives are now emitted for any transitive nested-pinned SCA finding.

Known Issues still open

  • Parent/child SCA correlation (e.g. @protobufjs/utf8 finding listed as a separate group from its parent protobufjs). Deferred — tracked as DG-future-SCA-dep-graph.
  • Reachability framework-level (config-gated CVEs like fastify trustProxy). Deferred — the new sca.dependencyContext + sca.packageManager fields are the data foundation for it.
  • Inconclusive-but-well-reasoned SAST taint verdicts — unchanged, success by design for the class of finding where the sink's implementation lives in another file.

Trivy DependsOn caveat (known data limit)

Trivy Result.Packages[*].DependsOn lists resolved dep versions, NOT the constraint ranges (^ vs ~ vs exact) of the pinner. SENTINEL cannot decide automatically whether a plain top-level bump satisfies the pinner's constraint; the STRONG / SOFT split uses hasSiblingFixedCopy (binary: is there a fixed copy top-level?) as a safe over-approximation.

Verification

  • Empirical against the SYNAPTIC_SAAS web lockfile (pnpm-lock.yaml with react-syntax-highlighter@15.6.6 → refractor@3.6.0 → prismjs@1.27.0 chain + prismjs@1.30.0 top-level).
  • Baseline-5 (step5.vsix) confirmed overrideDirective + dependencyContext for the prismjs case.
  • Baseline-5.1 (step5b.vsix) confirmed STRONG/SOFT visual hierarchy + tomo data byte-identical to step5.
  • pnpm verify VERDE: 60 test files / 707 tests + manifest gate + activation gate (9 commands + 15 subscriptions).

Schema changes (additive, backward-compatible)

  • TrivyResultSchema: Type?: string, Packages?: TrivyPackage[].
  • ScaMetadataSchema: packageManager?: string, dependencyContext?: DependencyContext.
  • RemediationTargetSchema: overrideDirective?: OverrideDirective.
  • New dependency: semver in @synaptic-sentinel/scouts.

Installation

vsce publish to the VS Code Marketplace is not part of this release — the Marketplace listing is on v0.3.3 and 12 GitHub-only releases (v0.3.4 → v0.3.15) accumulate user-side publishing operations. To install in VS Code:

```
code --install-extension synaptic-sentinel-0.3.15.vsix
```

…or use Install from VSIX... in the Extensions view.

Artifact

  • synaptic-sentinel-0.3.15.vsix — 1838 files / 3.19 MB / 3,346,724 bytes
  • SHA-256: `6e435c0b5a7ae6d43ef6b7a69b9911a00e2694edac92ce2cd42c6c75dd9e89b7`

v0.3.14 — Brain Layer + SCA major release (safety-critical upgrade)

Choose a tag to compare

@golab-arch golab-arch released this 30 May 16:00

Brain Layer + SCA major release — packages 5 cycles of work (Cycles 99-105, DG-110 → DG-113.1 A) responding to the SENTINEL-EVALUATION-REPORT empirical evaluation against a real codebase.

⚠️ Safety-critical upgrade

The previous release v0.3.13 (and the v0.3.3 currently on the VS Code Marketplace) contains a temporal-cutoff bug that causes the Brain Layer to dismiss real 2026 CVEs as "fabricated" with high confidence — burying a serious vulnerability with a confident false-positive. Step 2 of this release fixes that bug with a 3-layer defense in depth.

Upgrade strongly recommended for any user on v0.3.3 or v0.3.13.

Added

  • Step 1 (DG-110 A) — Determinism: temperature: 0 hardcoded in AnthropicLlmClient.completeWithUsage. The Anthropic client was running at the default 1.0; the OpenAI-compatible client already pinned 0 for security-tool determinism. Aligns both adapters.

  • Step 2 (DG-111 A) — Temporal-cutoff bug fix (BLOCKER from report §4 #1). 3-layer defense in depth against the LLM dismissing real, scanner-confirmed CVEs as "fabricated"/"non-existent"/"future":

    • Capa 1 (prompt): SYSTEM_PROMPT rewrite — SCA (Software Composition Analysis) explicitly modeled (was only SAST/secrets); NEW GROUND TRUTH section fixing scanner metadata (CVE IDs, versions, advisory dates) as authoritative; explicit instruction "Your training cutoff is NOT the authoritative source"; criteria for false_positive expanded with negative rule against dismissal.
    • Capa 2 (date injection): Current date (real-world authoritative): <YYYY-MM-DD> prepended to every user prompt.
    • Capa 3 (deterministic guard): guardAgainstFabricatedDismissals overrides false_positive to inconclusive (confidence 0.5) when rationale contains dismissal patterns (fabricated, fictional, spurious, non-existent, not a real, future-dated, future cve/release/version/advisory).
  • DG-111.1 A — Chain-of-Thought schema field order: JSON shape in SYSTEM_PROMPT now lists rationale BEFORE classification and confidence. Forces the LLM to reason before committing to a verdict. Fixes verdict↔rationale contradictions in multi-branch fix cases.

  • DG-111.2 A — Guard precision (scope to SCA): temporal-cutoff guard now only applies to category: 'SCA'. Avoids misfire on Secrets/SAST/IaC/VibeCoded/BusinessLogic findings whose legitimate FP rationales may contain words like "not a real production secret" (test fixtures).

  • Step 3 (DG-112 A) — SAST taint dataflow trace (from report §4 #3). OpenGrep's dataflow_trace (emitted by mode: taint rules) is now captured by the normalizer, canonized to new optional Finding.dataflowTrace, and included in the Triage Agent's user prompt as Dataflow trace (source → intermediate → sink). Defensive caps: max 25 intermediate steps (middle elided), max 200 chars per step content (truncated with ). Resolves "sink not visible" hedging.

  • Step 4 (DG-113 A) — SCA correlation/dedup (from report §4 #4). SCA findings grouped by package family (exact package-name match) in the tomo output. Each group includes unified remediation target as MAX semver per major track (e.g. {"7": "7.5.8", "8": "8.2.0"} with display "7.5.8 / 8.2.0"), with heterogeneity flag. Captures cross-lockfile + intra-package duplications. Sidebar renders expandable "SCA grouped remediations" section. Empirical result: protobufjs 18 findings → 1 grouped remediation action.

  • DG-113.1 A — Discard downgrade tracks: computeRemediationTarget now filters major tracks below the MIN installed major in the group. Empirical trigger: fast-xml-parser 5.5.6 was being recommended 4.5.5 / 5.7.04.5.5 is a major-version downgrade. Post-fix: 5.7.0 only.

Changed

  • FindingSchema extended with optional dataflowTrace? (Step 3) and sca? (Step 4) sub-objects — additive + backward-compatible.
  • TomoBodySchema extended with optional groups?: FindingGroup[]. Canonical integrity hash includes groups.
  • New dependency: semver in @synaptic-sentinel/core.

Known Issues

🚨 prismjs CVE-2024-53382 — false sense of remediation (deferred from report §4 #15)

The Brain Layer correctly identifies prismjs 1.27.0 as a true positive and recommends "upgrade to 1.30.0". However in many repos the top-level prismjs is already 1.30.0 — the vulnerable 1.27.0 is nested under refractor pinned to ~1.27.0.

A naive top-level bump does NOT fix the vulnerability.

Resolving this requires npm:resolutions / yarn:resolutions overrides or dep-graph-aware remediation, deferred to a future release.

For any prismjs advisory, verify manually with npm ls prismjs after applying the recommended bump — and apply an overrides directive if a transitive copy remains.

  • Parent/child SCA correlation (e.g. @protobufjs/utf8 listed separately from protobufjs). The exact-match family key in Step 4 is a deliberate trade-off to avoid over-merging unrelated packages (@types/node + @types/lodash etc. would be wrongly clustered by a naive scope-strip). Resolving parent/child requires a dep-graph, deferred.
  • Inconclusive-but-well-reasoned SAST taint verdicts: even with the dataflow trace, the LLM sees the sink expression but not its implementation (which lives in another file). For sinks like agentLoop.execute(), an inconclusive verdict with a well-reasoned rationale about the visible sink is the expected ceiling without AST cross-file resolution. inconclusive-well-reasoned is success by design for this class of finding.

Notes

  • The previous release v0.3.13 saw 2 hotfix iterations (DG-111.1, DG-111.2) discovered empirically during real-world re-scans. Both are folded into this v0.3.14 release. Step 4 added a third hotfix (DG-113.1, downgrade-track filter).
  • pnpm verify VERDE: 60 test files / 679 tests + manifest gate + activation gate (9 commands + 15 subscriptions).

How to install

code --install-extension synaptic-sentinel-0.3.14.vsix

Or use Install from VSIX... in the VS Code Extensions view.


Marketplace status: vsce publish to the VS Code Marketplace is not part of this release. The Marketplace listing is on v0.3.3; the 11 GitHub-only releases (v0.3.4 → v0.3.14) accumulate user-side publishing operations.

SHA-256: 5fd749e443f0559aebc9368f2b0fd15675c53a176b299a4e1409df533f568041

v0.3.13 — Re-triage controls + cost card freshness timestamp (DG-107 A)

Choose a tag to compare

@golab-arch golab-arch released this 29 May 00:26

Re-triage controls + cost card freshness timestamp (DG-107 A). Closes 2 UX issues reported in empirical feedback after installing v0.3.12 and running Sentinel on a real workspace where the user changed the Brain provider mid-flow (in .sentinel/agents.yaml).

The feedback backlog vacío milestone declared in the v0.3.12 release notes lasted ~30 minutes — a strong validation of the explicit anti-optimismo declared back then ("the feedback received is not exhaustive; other users could uncover new UX issues").

Added

  • Re-triage all button in the sidebar (Issue #1): when there are already-triaged findings in the current scan, a new Re-triage all button appears in the sidebar summary card next to Triage N untriaged. Clicking it shows a modal warning dialog with the exact count of verdicts that will be overwritten plus a caveat about LLM cost being incurred again. False positives marked manually (mark-fp) and the cost history rollup are preserved. Use case: after switching the Brain provider in .sentinel/agents.yaml, click Re-triage all to re-evaluate the same findings with the new provider.

  • synaptic-sentinel triage --re-triage CLI flag (Issue #1): equivalent to the sidebar button. Clears triage_verdicts + context_explanations + remediation_suggestions for the scan's findings (transactional, batches of 500 for large workspaces) before running the full triage pipeline. Preserves fp_known and triage_token_usage.

  • Cost card freshness timestamp (Issue #2): cost card in the sidebar now shows as of YYYY-MM-DD HH:MM (UTC) in its header when there's at least one record in triage_token_usage. Surfaces the case where the current triage run made 0 LLM calls (e.g. provider changed and everything was already triaged) and the cost card would otherwise look "fresh" even though it's showing data from a previous session.

Notes

  • Scope only DG-107 A. No changes to Scout Layer, Brain Layer adapters, benchmark runner, sidebar layout, or colony.db schema.
  • The destructive Re-triage all action only clears the 3 enrichment tables (triage_verdicts + context_explanations + remediation_suggestions). It does NOT touch fp_known (manual FP marks survive), triage_token_usage (cost history accumulates), or learning_records (colony memory persists).
  • The MODAL warning is opt-in. There is no "soft mode" / preview — the count is shown but not the per-finding breakdown.
  • Anti-optimismo: the IMPACT validates only by reproducing the flow below.
  • Deferred — provider-reported badge per-row: same deferral as v0.3.12. The cost card now has both workflow ordering (v0.3.12) and freshness timestamp (this release), but doesn't yet distinguish per-row whether tokens came from the provider's usage field (real) or chars/4 proxy. Surfacing it per-row requires a triage_token_usage v5 → v6 schema migration; will land if there's empirical demand.

How to validate empirically

If you have a workspace with previous scan + triage data in <workspace>/.sentinel/colony.db (e.g. where you ran v0.3.12):

  1. Uninstall the previous version (Ctrl+Shift+P → Extensions: Uninstall Extension, pick SYNAPTIC Sentinel; or code --uninstall-extension RealGoLab.synaptic-sentinel)
  2. Install v0.3.13:
    • Download synaptic-sentinel-0.3.13.vsix from this release
    • code --install-extension synaptic-sentinel-0.3.13.vsix (or use Install from VSIX... in the Extensions view)
  3. Edit <workspace>/.sentinel/agents.yaml and switch the triage agent provider (e.g. from deepseek/v4-flash to anthropic/claude-sonnet-4-6)
  4. Reload the VS Code window (Ctrl+Shift+P → Developer: Reload Window) so the sidebar rehydrates from cache (DG-103 A)
  5. In the SYNAPTIC Sentinel sidebar, you should see the Re-triage all button in the summary card (because findings are triaged). Click it → confirm the MODAL → the triage pipeline runs again with the new provider. Inspect the cost card after: the as of timestamp updates to the new session, and the new provider/model appears in the breakdown.

Known Issues

The Known Issues section is unchanged from v0.3.12 — 1 caveat structurally closed:

  1. Ground truth dataset is AI-drafted (DG-075 caveat heredado, DG-095 A structured in v0.3.7). External citation remains blocked until the corpus reaches ≥ 10 human-reviewed entries.

Asset: synaptic-sentinel-0.3.13.vsix (1838 files / 3.15 MB / SHA-256 f889c9d96d128fac09095f172473cfba6c062068e6ccd1641d45119dda58b4f1).

Marketplace upload status: vsce publish to the VS Code Marketplace is not part of this release. To install in VS Code, download the .vsix and use code --install-extension synaptic-sentinel-0.3.13.vsix (or Install from VSIX... in the Extensions view).

v0.3.12 — Cost card workflow ordering

Choose a tag to compare

@golab-arch golab-arch released this 28 May 19:49

Cost card agent ordering fix (DG-105 A). Closes a small but persistent user-feedback item from the v0.3.9 capture: the Brain Layer cost card in the sidebar showed agents in a counter-intuitive order driven by cost USD (descending). After v0.3.12, agents are ordered by the Brain Layer workflow instead.

Changed

  • Cost card agents are now ordered by Brain Layer workflowtriage → context → remediation, instead of by descending cost. The new SQL order in getCostHistory is CASE agent_id WHEN 'triage' THEN 1 WHEN 'context' THEN 2 WHEN 'remediation' THEN 3 ELSE 99 END, provider_label. Within each agent, rows are stable-sorted alphabetically by provider_label, so multi-provider setups (e.g. 3 providers × 3 agents = 9 rows) render in a predictable order. This affects:
    • The cost card in the SYNAPTIC Sentinel sidebar (after Triage Findings)
    • The CLI table output of synaptic-sentinel cost-history
    • The JSON output of synaptic-sentinel cost-history --json

Notes

  • Scope only DG-105 A. No changes to the Scout Layer, Brain Layer adapters, benchmark runner, sidebar layout, colony.db schema, or activate path.
  • 1-line SQL change covered by 2 new unit tests.
  • How to validate: install v0.3.12, open any workspace with a previous triage in .sentinel/colony.db, and confirm the cost card shows triage → context → remediation (instead of the previous cost-descending order).
  • Deferred — provider-reported badge per-row: the cost card surfaces a ~estimated USD caveat at the card header (since v0.3.9 / DG-099 A), but doesn't yet distinguish per-row whether the tokens came from the provider's own usage field (real) or the chars/4 fallback proxy. That breakdown lives in the synaptic-sentinel triage terminal output today. Surfacing it per-row in the sidebar requires a small schema migration (triage_token_usage v5 → v6 to persist usage_source); will land in a future release if there's empirical demand.

Known Issues

Unchanged from v0.3.11 — 1 caveat structurally closed:

  1. Ground truth dataset is AI-drafted (DG-075 caveat heredado, DG-095 A structured in v0.3.7). External citation remains blocked until the corpus reaches ≥ 10 human-reviewed entries.

Install

Download synaptic-sentinel-0.3.12.vsix and run:

code --install-extension synaptic-sentinel-0.3.12.vsix

Or use Install from VSIX... in the VS Code Extensions view.

SHA-256: c5031f8da5b48a898c88c247a2c5d6c16712d2b070929ae66a2d18d6eea42406

The Marketplace listing remains at v0.3.3 until the publisher uploads with their PAT — semver permits skipping intermediate versions, so a future upload may go from v0.3.3 directly to v0.3.12 (9 versions skipped, max distance of the project so far).

v0.3.11 — Sidebar hydration on activate

Choose a tag to compare

@golab-arch golab-arch released this 28 May 16:55

Sidebar hydration on activate (DG-103 A). Closes a real-world UX bug reported in feedback after using v0.3.10 on a 105-finding project: when you closed the workspace and reopened it later, the SYNAPTIC Sentinel sidebar always showed the empty state (Run "Scan Workspace" to see findings here) — as if no scan had ever run — even though the previous scan + triage + cost data was sitting in <workspace>/.sentinel/colony.db.

After v0.3.11, the sidebar rehydrates automatically on activate from the cached colony.db, with cost: 0 (no scanners re-run, no LLM re-invoked).

Added

  • Sidebar hydration on activate — when the extension activates in a workspace whose .sentinel/colony.db (or legacy .synaptic-sentinel/colony.db) already contains a previous scan, the sidebar restores silently:
    • All findings from the latest scan grouped into the four buckets (To fix · TP / Inconclusive / Untriaged / Already false positive)
    • The triage verdict + context + remediation on every previously-triaged finding
    • The cost card from the last triage session
    • Diagnostics in the editor and the status bar counter
  • synaptic-sentinel show CLI command — reconstructs the tome of the latest scan from colony.db without running scanners or LLM (cost: 0). Used internally by the hydration above; also exposed for scripting:
    • synaptic-sentinel show --path <dir> → JSON tome to stdout
    • synaptic-sentinel show --path <dir> --export <file> → JSON tome to a file

Notes

  • Scope only DG-103 A. No changes to the Scout Layer, Brain Layer adapters, benchmark runner, sidebar layout, or colony.db schema.
  • The hydration is best-effort defensive: if colony.db is missing, corrupted, has a schema mismatch, or any other read failure, the sidebar falls back to the empty state silently. A hydration failure will never crash the extension activation (try/catch is doubled).
  • The hydration is async after activate() returns, so there can be a sub-second moment where the sidebar shows the empty state before snapping to the hydrated view.
  • The hydration runs once per activation (not on file change). To get a fresh scan after editing code outside the extension, run Scan Workspace as usual.

How to validate empirically

If you already have a workspace with previous scan + triage data in <workspace>/.sentinel/colony.db:

  1. Uninstall the previous version (code --uninstall-extension RealGoLab.synaptic-sentinel)
  2. Install v0.3.11: code --install-extension synaptic-sentinel-0.3.11.vsix
  3. Close the project folder entirely (File → Close Folder)
  4. Reopen the same folder (File → Open Folder)

You should see the SYNAPTIC Sentinel sidebar fully populated without running anything: summary card, cost card, four bucketed sections, diagnostics, status bar — all restored from the cache.

Known Issues

Unchanged from v0.3.10 — 1 caveat structurally closed:

  1. Ground truth dataset is AI-drafted (DG-075 caveat heredado, DG-095 A structured in v0.3.7). External citation remains blocked until the corpus reaches ≥ 10 human-reviewed entries.

Install

Download synaptic-sentinel-0.3.11.vsix and run:

code --install-extension synaptic-sentinel-0.3.11.vsix

Or use Install from VSIX... in the VS Code Extensions view.

SHA-256: 417260686e30c7454c067956e9ee03d52b3afd7d88ef97a0cdbca80569ded428

The Marketplace listing remains at v0.3.3 until the publisher uploads with their PAT — semver permits skipping intermediate versions, so a future upload may go from v0.3.3 directly to v0.3.11 (8 versions skipped).

v0.3.10 — Triage cap controls

Choose a tag to compare

@golab-arch golab-arch released this 28 May 14:54

Triage cap controls (DG-101 A). Closes the last silent UX trap from the v0.3.x backlog. Before this release the Triage Findings command silently capped at 25 findings per run (the CLI default), skipping the rest with only a one-line note in the pseudoterminal that was easy to miss. v0.3.10 surfaces the cap, makes it configurable, and gives you a one-click way to triage the remainder.

Added

  • synaptic-sentinel.triageLimit setting — open VS Code Settings (Ctrl+,), search for SYNAPTIC Sentinel, and adjust the cap to any value between 1 and 10000. Default stays at 25. Only applies when you invoke Triage Findings from the Command Palette or status bar.
  • Triage N untriaged button in the sidebar — appears in the summary card whenever there are findings sitting in the Untriaged bucket. One click runs the Brain Layer on all untriaged findings (internal cap 9999) so the bucket clears in a single pass. Uses VS Code's native button theming for coherence with any theme.

Notes

  • Scope only DG-101 A. No changes to the Scout Layer, Brain Layer adapters, benchmark runner, cost card, or colony.db schema.
  • The synaptic-sentinel.triageRemaining command is deliberately not exposed in the Command Palette — it surfaces contextually in the sidebar only when there's something to do.
  • The button uses an internal cap of 9999 (not the configured setting) because it says Triage N untriaged where N is the exact bucket count.

How to validate empirically

  1. Open VS Code Settings (Ctrl+,) → search SYNAPTIC Sentinel
  2. Set synaptic-sentinel.triageLimit to 5
  3. Open a project with ≥ 6 findings (or use any project with multiple findings)
  4. Run SYNAPTIC Sentinel: Scan Workspace
  5. Run SYNAPTIC Sentinel: Triage Findings
  6. Confirm:
    • Only 5 findings get triaged
    • The sidebar shows the rest under Untriaged · run Triage Findings
    • The Triage N untriaged button appears in the summary card
    • Clicking the button triages the rest in one run

Known Issues

The Known Issues section is unchanged from v0.3.9 — 1 caveat structurally closed:

  1. Ground truth dataset is AI-drafted (DG-075 caveat heredado, DG-095 A structured in v0.3.7). External citation remains blocked until the corpus reaches ≥ 10 human-reviewed entries.

Install

Download `synaptic-sentinel-0.3.10.vsix` and run:

```
code --install-extension synaptic-sentinel-0.3.10.vsix
```

Or use Install from VSIX... in the VS Code Extensions view.

SHA-256: `04e6913a0a40aec58365c7025304e0bc3eaca9f2b232b885ee66512cfebe7c44`

The Marketplace listing remains at v0.3.3 until the publisher uploads with their PAT — semver permits skipping intermediate versions, so a future upload may go from v0.3.3 directly to v0.3.10 (7 versions skipped).

v0.3.9 — Sidebar Cost Visibility

Choose a tag to compare

@golab-arch golab-arch released this 27 May 02:56

Sidebar Cost Visibility (DG-099 A). Closes the last UI value-prop gap from Phase 11: the Brain Layer cost summary (tokens + cost USD + latency, per (provider/model, agent)) was previously printed only in the pseudoterminal after each Triage Findings run — useful in the moment, invisible once the terminal was closed or scrolled. v0.3.9 surfaces it as a persistent cost card in the SYNAPTIC Sentinel sidebar, right between the findings summary (v0.3.8 / DG-097 A) and the bucketed findings sections.

Added

  • Cost card in the sidebar — every time you run Triage Findings, the sidebar refreshes with a new cost card showing:
    • Title Brain Layer cost · last session plus the ~estimated USD caveat
    • A compact table per (provider/model, agent) row: calls, input tokens, output tokens, cost USD, avg latency ms (numeric columns use tabular-nums for stable alignment)
    • A total line: Total: N calls · X input · Y output · $Z
    • When no triage has run yet, collapses to Brain Layer cost — run Triage Findings to start tracking cost
  • cost-history --json flag — typed JSON payload ({ limit, rows, totals }) consumed by the extension via Zod schema validation, replacing fragile stdout parsing.

Notes

  • Scope only DG-099 A. No changes to the Scout Layer, Brain Layer adapters, benchmark runner, or colony.db schema.
  • Tokens and cost remain ~estimated (DG-078 B / DG-085 A caveats). The (provider-reported) badge from the terminal cost summary is not yet surfaced per-row in the card.
  • Cost card position is fixed (below findings summary, above sections). "What to fix" is primary; "how much it cost" is secondary scan information.

Known Issues

The Known Issues section is unchanged from v0.3.8 — 1 caveat structurally closed:

  1. Ground truth dataset is AI-drafted (DG-075 caveat heredado, DG-095 A structured in v0.3.7). External citation remains blocked until the corpus reaches ≥ 10 human-reviewed entries.

Install

Download synaptic-sentinel-0.3.9.vsix and run:

code --install-extension synaptic-sentinel-0.3.9.vsix

Or use "Install from VSIX..." in the VS Code Extensions view.

SHA-256: `7dc1886477be1b16e6552380f65955e0c16298673aa96d32e387535bf52085fd`

The Marketplace listing remains at v0.3.3 until the publisher uploads with their PAT — semver permits skipping intermediate versions, so a future upload may go from v0.3.3 directly to v0.3.9.


Milestone: This release closes Cycle 92 / DG-100, the round numeric cycle. 18 sub-DGs in a row without a failed cycle (DG-083 → DG-100). 6 real releases on GitHub.