First public release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```
|
||||
npm install @extant2000/trace-proof
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT. See [LICENSE](LICENSE).
|
||||
Reference in New Issue
Block a user