Domain model
commitwork
This page sets out commitwork's domain model: its subdomains, bounded contexts, context map and ubiquitous language. commitwork is a repository security scanner, local CI runner and scheduled monitor, with remediation and compliance-evidence tooling.
Domain
The domain is the security state of a set of repositories over time: which checks ran against which commit, what each check reported, how each finding was judged, and what was fixed. Every bounded context below reads or writes evidence about that state.
| Subdomain | Type | Bounded context |
|---|---|---|
| Running checks and normalising their output | Core | Check execution |
| Finding history, from first sighting to verified remediation | Core | Fleet monitoring |
| Judgement of findings | Core | Adjudication |
| Remediation work and its evidence | Supporting | Remediation |
| Regulatory evidence for the EU CRA and SOC 2 | Supporting | Compliance evidence |
| Public hostnames and their routing | Supporting | Deployment declaration |
| Access for operators and coding agents | Supporting | Panel and MCP server |
| Scanning engines: Semgrep, CodeQL, gitleaks, TruffleHog, OSV, Trivy and others | Generic | Third-party tools behind an anticorruption layer |
| Credential storage | Generic | The OS keychain, referenced by pointer |
Bounded contexts
- Structure:
- 1. Responsibility
- 2. Aggregates
- 3. Events
- 4. Terms
Check execution bin/commitwork.mjs manifests/
- Responsibility
- Runs checks against one repository, or every git repository under a root, as local commands, and writes one normalised report per check. A manifest maps each CI workflow to the local commands that perform the same checks.
- Aggregates
- Manifest: its checks, groups, requirements and the egress class each check declares.
- Events
- Check ran. Check skipped, with a skip record naming the requirement that was not met.
- Terms
- manifest, check, group, requirement, egress class, skip record, report
Fleet monitoring monitor/
- Responsibility
- Runs check groups on a schedule over declared areas, rolls each sweep into a slice, and tracks each finding from first sighting to verified remediation.
- Aggregates
- Area, with its projects and retention. Slice, with its findings and enrichment. Finding, identified by its place.
- Events
- Sweep intended (
batch-manifest.jsonanchors each repository's commit before the run). Sweep completed (batch-verdict.json). Slice recorded in a hash-chained history. Findingborn,persisting,resolved-fixedorunknown-not-scanned. - Terms
- registry, root, project, area, sweep, rollup, slice, lane, lane kind, carried
Adjudication bin/annotate.mjs monitor/annotations.json
- Responsibility
- Records human judgement on findings and applies it to each slice as of that slice's timestamp. An annotated finding keeps its place in the slice, with the annotation attached.
- Aggregates
- Annotation. A scanner annotation matches every field of a finding's identity plus its repository; a dependency annotation matches the fields it names.
- Events
- Annotation
applied,noMatch,expired,invalidorcarried, published per slice. Ruling recorded. - Terms
- annotation, ruling, fix type,
incorrect-scan-result
Remediation monitor/issue-store.mjs monitor/ledger.mjs
- Responsibility
- Tracks findings that need work as issues with SLA clocks, records each verified fix with its evidence tier, and drafts fixes as triage prompts, agent hand-offs and diffs for
git apply. Applying a fix is a human act. - Aggregates
- Issue, keyed by a source key, with an append-only, hash-chained event trail. Remediation ledger entry.
- Events
- Issue minted, claimed, closed, and reopened under the same id when its finding returns.
fix-authored,fix-verified,fix-disputed. - Terms
- issue, source key, evidence tier, SLA clock, hardener
Compliance evidence cra/
- Responsibility
- Maps the monitor's evidence onto EU Cyber Resilience Act Article 14 obligations, CycloneDX SBOM and VEX, POA&M, SOC 2 and OSCAL. Every output is a draft, and submission to an authority is a human act.
- Aggregates
- Product, the unit the CRA regulates, spanning one or more repositories. Case, hash-chained.
- Events
- Case opened by the exploited-vulnerability watch (KEV × EPSS, every 30 minutes).
early-warning,notificationandfinal-reportfall due on the 24-hour, 72-hour and 14-day clocks. - Terms
- product, case, SBOM, VEX, POA&M, attestation
Deployment declaration bin/deploy.mjs
- Responsibility
- Renders a tunnel ingress fragment from the hostnames each area declares, and compares the declaration with reality on five axes: declared, routed, DNS, origin and TLS. It holds no credentials and applies no change.
- Aggregates
- Hostname declaration, with its
public,requiresAuthandauthAtfields. - Events
- Drift found on an axis (exit 1).
- Terms
- declaration, ingress fragment, drift
Panel and MCP server admin/ mcp/
- Responsibility
- Publishes the evidence to operators through a web panel bound to loopback, and to coding agents through an MCP server. The panel authenticates with passwords, TOTP, passkeys and single sign-on for existing accounts.
- Aggregates
- Account and session in the panel. The MCP server holds none and forwards commands to the contexts that own them.
- Events
- Commands rather than events:
run_checksinto check execution, restricted to bundled manifests;issue_claim,issue_closeandissue_judgeinto remediation. - Terms
- section, workspace, count badge, tool, resource
Context map
| Upstream | Downstream | Relationship | What crosses |
|---|---|---|---|
| Third-party scanners | Check execution | Anticorruption layer | Each tool's output, translated into the finding schema by its check wrapper and the monitor's extractors, with a declared lane kind |
| Check execution | Fleet monitoring | Customer and supplier | Normalised reports per repository and commit, produced by commitwork run <group> inside each sweep |
| Fleet monitoring | Adjudication | Partnership | Findings out; annotations back, applied as of each slice's timestamp |
| Fleet monitoring | Remediation | Published language | Finding keys, as source keys; the issue tracker references the monitor's records and never copies them |
| Fleet monitoring | Compliance evidence | Customer and supplier | Finding lifecycle and KEV/EPSS enrichment, as SBOM, VEX and case clocks |
| Fleet monitoring | Deployment declaration | Customer and supplier | Areas' declared hostnames |
| Every context | Panel and MCP server | Open host service | Evidence and commands, through the panel's routes and the MCP tool names |
lib/ | Every context | Shared kernel | Clock, HTML escaping, brand tokens and other primitives |
Ubiquitous language
- finding
- One claim a check makes about a repository. Its identity is its place: repository, category and the category's identity fields, such as rule, file and package. A line number is never part of it.
- lane
- One check's findings as the monitor receives them.
- lane kind
- What a lane's findings claim:
vulnerability,posture,integrity,policyorhygiene. A lane with no declared kind is reported asunclassified. - area
- The declared unit of report output, retention, freshness and identity. Each registry entry belongs to one area by declaration.
- sweep
- One scheduled run of a check group over an area's repositories.
- slice
- A rollup recorded as a cut through the fleet at one time, with KEV and EPSS enrichment frozen as of that time.
- lifecycle state
born,persisting,resolved-*orunknown-not-scanned. A finding resolves when its repository was scanned and its tool provably ran.- carried
- A category that did not run in a sweep. Its previous counts and rows move forward, marked as carried.
- undetermined
- A severity field outside crit, high, med and low, holding rows whose claim cannot be read as a verdict, with the scanner's original claim preserved.
- annotation
- A human acceptance, applied to matching findings as of a slice's timestamp.
- ruling, fix type
- The two parts of a disposition: whether a finding is real, and how it was addressed.
- evidence tier
- The strength of proof that a fix happened: strong (a lockfile diff between two commits), medium (the fix version is known) or weak (not counted).
- issue
- A unit of remediation work, keyed by the source key of the finding or group it tracks.
- product
- The unit the EU CRA regulates, spanning one or more repositories.
- case
- A record of a reportable exploited vulnerability in a product, with its reporting clocks.
- draft
- Any output addressed to an outside party. Sending it is a human act.
Invariants
- Rule #1Fail closed. A parse failure or a permission error is an error, never an empty result; a missing file (
ENOENT) is the one legitimate absence. - Rule #2Key a finding's identity on its place, never its line number.
- Rule #3Same inputs give byte-identical outputs. Writes are atomic, and re-runs are idempotent.
- Rule #4Keep declaration apart from authority. Tools that describe deployments, DNS or tunnels hold no credentials and apply no changes.
- Rule #5Run no repository-local manifest (
commitwork.json) without--trust-repo-manifest. - Rule #6Leave applying a fix and submitting to an authority to a person.
Releases
Release notifications are published as an Atom feed at /releases.atom. It needs no token and no account.
Every commit carries a version: package.json's patch moves with each one. v0.5.0 is the first release, tagged on the public repository on 2026-10-08.
The versions and milestones so far and the target releases to 1.0.0 each have a page.
Versions are announced here rather than left to aggregators that resolve by name: asked about trufflehog, one returned an abandoned package four major versions behind the tool in use.