Files
Paul HittandClaude Opus 5.5 bdb7e46fb0 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:41:52 -04:00

84 lines
3.5 KiB
Markdown

# DeviationLog
Turns field deviations from a written procedure into corrective actions, and
does not count a logged deviation as a handled one.
## What it does and why
It is built against two failures.
### A logged deviation with no resulting action is an open loop
It looks handled because someone wrote it down, but nothing changed. A log
that cannot tell recorded from resolved turns into an archive of problems
nobody fixed. So each entry is judged by where its loop stands:
| State | Result |
|---|---|
| No cause decided (`unadjudicated`) | Not assessed. It is an entry in a list, not a finding yet. |
| Cause decided, no action recorded | Fail. Critical when the cause is a procedure defect. |
| Action still `open` | Fail. The next crew meets the same step unchanged. |
| Action `rejected` | Not applicable, and still printed so the rejection can be reviewed if the step comes up again. |
| Action `applied` | Pass, citing the document or procedure version it changed. |
### Repeat deviations point at the procedure, not the operator
When several different people depart from the same step, the common factor
is the step. Judged one incident at a time, each looks like an individual
mistake and gets closed with "retrained operator". Every entry passes, the
step stays as written, and the deviations continue. Only the aggregate shows
the defect, so DeviationLog computes it and lists it above the individual
entries as a critical failure, even when every incident behind it was
closed.
Repeats are grouped by procedure and step, and counted by distinct operator,
not by incident. One person deviating five times is a conversation with that
person. Five people deviating once each is a defective step. The default
threshold is two operators, set with `minOperators`.
An empty log is reported as not assessed. It is not evidence that no
deviations happened, only that none were written down.
The library is pure: no clock and no I/O. Reports use the
`@extant2000/evidence-record` format, and every finding cites the record it
came from.
## Usage
```ts
import { assessLog, formatLog, repeatOffenders, type Deviation } from '@extant2000/deviation-log'
const deviations: Deviation[] = [
{ id: 'd1', procedure: 'pump-install', step: 'step 7: torque check', operator: 'crew-a',
what: 'skipped the second torque pass', cause: 'execution-error',
action: { description: 'retrained operator', status: 'applied' }, where: 'work order 101' },
{ id: 'd2', procedure: 'pump-install', step: 'step 7: torque check', operator: 'crew-b',
what: 'skipped the second torque pass', cause: 'execution-error',
action: { description: 'retrained operator', status: 'applied' }, where: 'work order 102' },
{ id: 'd3', procedure: 'pump-install', step: 'step 9: leak test', operator: 'crew-c',
what: 'tested at half pressure', where: 'work order 103' },
]
const groups = repeatOffenders(deviations) // steps hit by 2+ operators
const report = assessLog(deviations, { minOperators: 2 })
console.log(formatLog(deviations))
```
Here both step 7 incidents pass on their own, yet the report fails: step 7
was deviated from by two different operators, and that repeat finding comes
first. The step 9 entry is not assessed because no cause has been decided.
## 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/deviation-log
```
## License
MIT. See [LICENSE](LICENSE).