Paul HittandClaude Opus 5.5 0781b21f12 Publish to the GitLab package registry on version tags
The README's install line failed: the package was never published, and
nothing told npm where the @extant2000 scope lives. A tag like v1.2.3 now
publishes to this project's registry with CI_JOB_TOKEN, and the README
sets the scope's registry before installing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:42:53 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00
2026-09-28 14:56:00 -04:00

TraceProof

Builds a requirements-to-evidence traceability matrix from rows you load, and reports the gaps and a quality score that leads back to those rows. It is used in Hitt Hosting products.

What it does and why

You load requirements, their links to verifications, risks, parents and stakeholder needs, and the verification items themselves, from whatever database you use. TraceProof takes the rows as plain objects and computes:

  • coverage: how many requirements are traced to a test, verified, linked to a risk, linked to a parent and linked to a stakeholder need;
  • gaps: orphaned requirements, requirements with no test or no risk, suspect links, and failed verifications;
  • a composite quality score from 0 to 100 with a letter grade.

A few rules keep the numbers from flattering the programme.

A requirement with no verifications is not verified. [].every(...) is true, so a naive check reports a requirement with no evidence at all as fully verified. A requirement counts as verified only when it has at least one verification and every one of them is Passed or Waived.

A requirement linked to a test both through a junction table and through a foreign key on the verification item is counted once.

Absent evidence and evidence of failure are different claims. A missing test, risk or parent is reported as not assessed. A failed verification is a failure, and it is the only critical gap.

An empty requirement set is not assessed, not 0% with grade F. Zero next to an F reads as "this programme traced nothing" when the truth is that nothing was loaded. It is the same error as reporting 100% uptime from zero samples, in the other direction.

A composite score is easy to assert and hard to check. The report splits it into its four inputs, each with the count of requirements it was computed over, so a reader can redo the arithmetic. Every gap cites the row that produced it, for example requirements#<id>, with the table name set by requirementTable and verificationTable.

Scoring

The default weights are traced to a test 30%, verified 30%, linked to a risk 20% and linked to a parent 20%. Grades are A from 90, B from 75, C from 60 and D from 40. qualityScore() accepts other weights and thresholds for a different accreditation regime. Weights are not normalised: if they do not sum to 1, the score will not span 0 to 100, which is a caller error worth seeing. toReport() uses the default weights.

Usage

import { computeCoverage, detectGaps, qualityScore, formatTrace, type TraceInput } from '@extant2000/trace-proof'

const input: TraceInput = {
  requirements: [
    { id: 'r1', req_number: 'SYS-001', title: 'Deorbit within 25 years', parent_id: 'p1' },
    { id: 'r2', req_number: 'SYS-002', title: 'Survive launch loads', parent_id: 'p1' },
  ],
  requirementVerifications: [{ requirement_id: 'r1' }],
  requirementRisks: [{ requirement_id: 'r1' }, { requirement_id: 'r2' }],
  verificationItems: [{ id: 'v1', requirement_id: 'r1', status: 'Passed', method: 'Test' }],
}

const coverage = computeCoverage(input)   // pct_test 50, pct_verified 50, ...
const { gaps } = detectGaps(input)        // SYS-002 has no test
const score = qualityScore(coverage)      // { score: 70, grade: 'C', ... }

console.log(formatTrace(input, { requirementTable: 'requirements' }))

The score lines from that output:

· MEDIUM   traced to a test: 1 of 2 (50%)   [NOT MET]
· MEDIUM   verified: 1 of 2 (50%)   [NOT MET]
◦ info     linked to a parent: 2 of 2 (100%)   [MET]
◦ info     linked to a risk: 2 of 2 (100%)   [MET]

The report also lists SYS-002 as not assessed for having no linked test, and notes the composite score of 70/100, grade C.

Gap ids (gap-0, gap-1, ...) are positional and only stable within one call. Do not store them as entity keys.

Install

The package is published to the GitLab package registry, so point the @extant2000 scope there first:

npm config set @extant2000:registry https://gitlab.com/api/v4/packages/npm/
npm install @extant2000/trace-proof

License

MIT. See LICENSE.

S
Description
Links requirements to the evidence that they are met.
Readme MIT
53 KiB
Languages
TypeScript 100%