Repository navigation
Releases
Releases · b070nd/cvewatch
v2.1.0
Added
- Match basis: every finding records why it matched (
cpe,package,product,title,text). It is shown in reports,why, the TUI, JSON and CSV exports (new last columnbasis), andsearch basis:weakfinds matches that rest on a mention. - Matching profiles
strict,balanced(default) anddiscovery, global (profile:inconfig.yaml) or per project (profile:in the project file,cvewatch project NAME -profile P, MCPset_profile). - A match that is disproved is retired: the finding stays open, counts as not affected and says why (
retired:uninstalledorunmatched). It returns when the match holds again.revalidatereports the count and lists them. retire: auto | manualinconfig.yaml: withmanualan update leaves disproved matches as they are and reports how many (retirable);cvewatch revalidate -applyretires them.ops.Workspace(everything an interactive front end shows, scoped to the actor) andops.ResolveAll(many status changes as one operation: one save, one audit record per change).
Changed
- Findings are judged by one rule set at every point: a new item, late data, a changed inventory and a revalidation now give the same result for the same advisory, whatever order the reports arrived in. After this upgrade the first update judges the stored advisories again once.
- Judging uses an index of the inventory built once per run, so its cost follows the size of the advisory, not the number of installed packages.
whyjudges only the projects and environment asked for and visible to the actor; its notes no longer mention other projects.- Access is decided before anything else in every operation: a refusal no longer says whether a project exists (
fix,ignore,assign,evidence add, project edits, lifecycle,inventory), and a file-name collision no longer names another actor's project. dashboardandcalendarwrite their shared page only for an actor that sees every project and may change things; others get a refusal (dashboard -out FILEandcalendar -textstill give them their own view).- Bulk status changes in the TUI are one operation: the ledger is saved once and each issue's report is rewritten once.
- The TUI no longer decides what is visible, which environments a bulk change touches, or when an update is due: it asks
ops,queryandstatus.
Fixed
- When two records of the same issue are merged and both have a finding for the same project and environment, which one is kept no longer depends on chance.
cvewatch revalidateand the judging at the start of an update are about five times faster on a large store: a technology name is looked up in the text of a stored advisory without a regular expression for plain ASCII text. The answers are the same.revalidatewrites progress to stderr, so-jsonon stdout stays machine-readable: a start line with the number of stored advisories, a line every five seconds with how many are judged, and a closing line with the time it took and the counts.
v2.0.0
Version 2.0.0 changes things that integrations can see, so read the upgrade notes first. Each project has its own update schedule, a change to a project or to techs.yaml is judged against the stored advisories at once with older history fetched as needed, CVSS is read from every version the sources carry, and projects are kept apart by vendor. Environments are free and optional, you can add your own technologies, the monitor reports GREEN, YELLOW or RED, the TUI is switched by letters, and independent black-box validation led to many correctness fixes.
Upgrading from 1.x
- Health levels are
green,yellowandred;ok,warn,failandunknownare gone. Update scripts that readlevelfromcvewatch status -json(report, daemon, each feed and channel) or from MCPget_status. A monitor that has not read a feed yet is yellow, notunknown.cvewatch statusstill exits non-zero only on red, and no longer printswarning:orOverall:lines. - The TUI screens are switched by the letters
OFPHS, not1to5, and the Status screen is now Health.F(fetch) is nowu, and a few other keys moved; the old and new keys are in the table under Screen keys. - Search terms that name a project, vendor, environment, status, owner and the like must hold on the same environment row, and an exclusion such as
-owner:annkeeps the rows that do not match, so some queries return fewer issues. The text oflistandsearchfor an issue open in several projects now has one version verdict per project; scripts should read-json. - An entry in
sources/with the id of a shipped feed now overrides only the fields it gives and keeps the rest; before, it replaced the whole feed. If you relied on a left-out field being empty, set it explicitly (for examplematch_structured: false). - The shipped
ghsasource sendsGITHUB_TOKEN, when that variable is set, as a bearer token to api.github.com. To keep it unauthenticated, addsources: [{id: ghsa, auth_env: ""}]to a file insources/. cvewatch updateandrunexit 1 when every source failed. One failed source among several still exits 0, and-jsonis unchanged. Check CI and cron wrappers that treated exit 0 as fresh data.- Regional production names such as
prod-euandeu-prodcount as production for "open in prod", the ordering and the development-only package rule (non-prodandpre-proddo not). Development-only packages now count by default inlocal,dev,int,developmentandtest, not only indevandint. - A project file with
environments:still loads with the same meaning, and a file withoutenvsstill meansdev,int,stagingandprod.cvewatch project NAME -migrate-envs -saverewrites the old block aswhen@<env>blocks, and any edit of the differences does it too. cvewatch rescanis nowcvewatch revalidate, and the old name still works. The first cycle after upgrading judges every stored advisory again, which can add findings, and fetches history back to the earliestsincedate or alert horizon of your projects, which can take minutes at NVD's request rate; an interrupted run continues where it stopped.- A
sincedate now also closes the open findings of advisories published before it, as not affected with a note. Moving the date earlier or removing it reopens them, and a status you set yourself is never changed. - Exports and state only gain fields. The JSON export keeps
schema_version1 and its required fields; targets gainvendor, issues gaincvss_version,cvss_vectorandcvss_source, andenvmay be any environment name instead of one of four. CSV has avendorcolumn at the end. The state and the audit log gain optional fields. enrich.cvssis on by default: tracked CVEs that no source rated are looked up at NVD, by CVE id only. Setenrich.cvss: falseto turn it off.
Added
Project files and environments
- Environments have free names (lowercase letters, digits,
-and_, starting with a letter, up to 32 characters);local,dev,int,stagingandprodare suggestions,productioncounts as prod, and a new project starts withlocal. - A
when@<env>:block in a project file holds only what differs there:techs(another version, or a technology that runs only there),exclude(generic technologies that do not run there) andimage. A technology can carryenvs: [...]to run only in some environments. - Environment edits
add_env,remove_envandrename_env:-env-add,-env-removeand-env-rename OLD=NEWon the CLI,+,-andrin the TUI, and the same kinds in MCPedit_project. A rename moves the environment's findings and says how many; a removal also drops its differences. - Edits for the start date, lockfiles, images, versions per environment and technology scope:
-since,-lock TYPE:PATH[:ENV][:dev],-unlock,-lock-dev,-lock-nodev,-image,-env-set,-env-unset,-env-exclude,-env-includeand-tech-envs TECH=ENV,ENVon the CLI, with matching kinds and alockfileobject in MCP. migrate_envs(-migrate-envson the CLI,mon the TUI's differences list) rewrites the oldenvironments:block aswhen@<env>blocks in one previewed step.- Project lifecycle: rename, duplicate, delete, disable and enable in the TUI (
R,D,X,Z, andNfor a new project), on the CLI (cvewatch project rename|duplicate|delete|disable|enable, which shows the consequences until-yes) and in MCP (manage_project, untilconfirm). Delete moves the project file to the backups, and-close-findingsmarks its open findings ignored. - Projects from one Dockerfile, compose or Kubernetes file:
cvewatch discover FILE,cvewatch setup FILEanddiscover_stack. Base images, compose services, Kubernetes images and packages installed in a Dockerfile are marked as infrastructure, with their category. - Discovery and setup skip what
.gitignoreand.git/info/excludeignore.-allreads them anyway, a directly given file that is ignored is refused without it, and the TUI folder box hides ignored entries. - Hints: advice about a project that is not an error, such as an unknown technology with its suggestions, a missing version, a lockfile problem, no prod environment or no start date. They show in the setup review,
cvewatch project,check_projectsandpreview_project_change, and in the TUI underw. check_projectsMCP tool: a read-only report of problems in project files, with the fixes it knows. Validation warns when a lockfile'senvis not in the project'senvs, since such a lockfile is never read.
Technologies and catalog
- Technologies the catalog lacks can be kept as your own keyword:
+termin setup,ctrl+oandKin the TUI, orcvewatch tech add|edit|remove|list. The entry goes toconfig/techs.yamlafter a preview, and a new project is written together with it. - MCP
suggest_tech(the closest names for a typed term),preview_tech_changeandedit_tech(with-allow-write) for your own technologies. The Settings screen's Tech catalog section lists yours, witha,eandx. - The Linux kernel entry takes the names people write (
ubuntu kernel,debian kernel,linux-image,linux image), and the words of an unknown technology are matched one by one.
Updating, history and scheduling
- Per-project schedule:
update: {auto: true, every: 1h}in a project file (everyat least 5m, default theinterval;auto: falseleaves the project out of scheduled runs),update.autoinconfig.yamlas the main switch,-update-everyand-update-autooncvewatch project,set_updatein MCP, and an Updates field in the TUI. - The daemon wakes when the first project is due, at the latest after
interval. A scheduled cycle fetches the feeds once, then judges, reports and alerts only the projects that are due;cvewatch update,cvewatch runanduin the TUI still cover every project. - Last update and next due time per project in
cvewatch statusand on the TUI Health screen; the Projects screen showsevery 1hwithdue now,next 14:05,pausedormanual. cvewatch doctorand validation: aneveryunder 5m is an error, one over 30 days is a warning, and a project withauto: falseis listed.- Revalidation: when a project, its technologies, versions, environments, lockfiles or
sincedate changes, or atechs.yamlentry or the alert horizon does, every stored advisory is judged again, including the ones that matched nothing before. New matches become findings and nothing stored is removed. It runs at the start of every cycle, on the TUI's next read, and in the daemon within about 15 seconds of a file change. cvewatch revalidate [-apply] [-fetch] [-json]previews or applies the same re-judging, and-fetchalso fetches the older advisories the change needs.rescanis the old name and still works.- Back-fill: when a change starts earlier than what the sources have covered, NVD is asked in 119-day windows with paging, GitHub advisories are followed page by page and KEV is read in full. Vendor records, RSS and Hacker News cannot go back, and the cycle notes say so.
sincecloses the open findings of advisories published before it, as not affected with a note saying why. Moving the date earlier, or removing it, reopens the findings cvewatch closed.- Alert horizon:
horizon:inconfig.yaml(unlimited,hour,day,week,month,yearorcustomwithfromandto). A vulnerability published outside it is not judged, alerted or put in a digest, and existing findings stay.cvewatch checkwarns when the window reaches further back thanlookback. published:search field (published:week,published:7d,published:2026-01-01..2026-03-01) and-published VALUEonlist,update,searchandexport.cvewatch updateand the daemon log each finished chunk or page of ...
v1.2.0
Changelog
- e857797: fix: list and update no longer fail when findings exist without -fail-on (@b070nd)
- 512b4fa: feat: cve-records source reads the CVE Program's own records (@b070nd)
- 8d8fb76: docs: document cve-records and prepare the 1.2.0 changelog and version (@b070nd)
- 4a5044f: merged: pull request #13 from b070nd/feature/CVMAS-5-cve-records (@b070nd)
v1.1.0
Changelog
- a9c0890: feat: per-project start date and issue search (@b070nd)
- 427c38c: docs: start date per project and search (@b070nd)
- 4ee1ef9: Merge pull request #11 from b070nd/feature/CVMAS-3-search-and-since (@b070nd)
- 0c37644: docs: prepare the 1.1.0 changelog and version (@b070nd)
- 0e5b222: merged: pull request #12 from b070nd/feature/CVMAS-4-release-1.1.0 (@b070nd)
v1.0.0
Changelog
- 30f56b7: merged: pull request #10 from b070nd/feature/CVMAS-2-wizard (Botond Biro 100288841+b070nd@users.noreply.github.com)
- 8089592: docs: tighten wording, fix stale limits, prepare the 1.0.0 changelog (Botond Biro b070nd.code@gmail.com)
- e0bd7eb: merged: pull request #9 from b070nd/feature/CVMAS-2-wizard (Botond Biro 100288841+b070nd@users.noreply.github.com)
- fecd6d9: test: make discovery, project file, setup and TUI tests portable to Windows (Botond Biro b070nd.code@gmail.com)
- 8725124: docs: catalog, discovery, setup flow, status and dashboard (Botond Biro b070nd.code@gmail.com)
- 01f6df8: feat: setup, status, catalog and project commands, MCP setup tools, SARIF export, agent skills (Botond Biro b070nd.code@gmail.com)
- 3b4ddf6: feat: prompt wizard and full-screen TUI as a separate program (Botond Biro b070nd.code@gmail.com)
- cd2eb04: feat: stack discovery, project file editor and setup flow (Botond Biro b070nd.code@gmail.com)
- 1e31b99: feat: monitor health, status and dashboard, daemon heartbeat, read-only sessions (Botond Biro b070nd.code@gmail.com)
- 7957590: feat: technology catalog with detection hints and vendor feeds (Botond Biro b070nd.code@gmail.com)
- 9de7268: merged: pull request #8 from b070nd/feature/CVMAS-1-overview (Botond Biro 100288841+b070nd@users.noreply.github.com)
- c8f556a: docs: rewrite the README around three perspectives with examples and diagrams (Botond Biro b070nd.code@gmail.com)
- 3612d7d: merged: pull request #7 from b070nd/feature/CVMAS-1-overview (Botond Biro 100288841+b070nd@users.noreply.github.com)
- 01dbd3a: docs: document inventory, tracking, priority, channels, storage and the data contract (Botond Biro b070nd.code@gmail.com)
- 2258943: feat: per-environment inventory, channels, evidence, export, doctor and storage backends (Botond Biro b070nd.code@gmail.com)
- ec540a0: feat: ecosystem-aware names and versions, lockfile and SBOM adapters, priority and EPSS (Botond Biro b070nd.code@gmail.com)
- 9c60cc6: merged: pull request #6 from b070nd/feature/CVMAS-1-overview (Botond Biro 100288841+b070nd@users.noreply.github.com)
- 4cdf0f2: ci: report one aggregate check named test (Botond Biro b070nd.code@gmail.com)
- 3e97332: ci: cache Go modules from app/go.sum (Botond Biro b070nd.code@gmail.com)
- c557ecd: ci: fix Windows gofmt check and Go standard library advisories (Botond Biro b070nd.code@gmail.com)
- 66a1cd2: ci: run on master and feature branches (Botond Biro b070nd.code@gmail.com)
- d9478de: docs: document architecture, matching and compliance; add CI, packaging and community files (Botond Biro b070nd.code@gmail.com)
- 7e7831a: feat: version-aware matching, issue identity, operations module, host and storage seams (Botond Biro b070nd.code@gmail.com)
- c5f70e1: docs: state the license holder in the README (Botond Biro b070nd.code@gmail.com)
- 8abbcff: feat: initial import of cvewatch (Botond Biro b070nd.code@gmail.com)