First public release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Worked example: cap by the worst defect.
|
||||
*
|
||||
* A hand-scored assessment of a fictional product. The scorer rated Security
|
||||
* at 70 and noted, in the same row, an open defect that the rubric caps at 45
|
||||
* (a secret that was exposed and never rotated). A human reading prose can be
|
||||
* charitable and skip the cap. The library cannot: the lowest open cap wins,
|
||||
* and the product's overall score is its weakest dimension, not the average.
|
||||
*
|
||||
* Run: npx tsx examples/cap-by-worst-defect.ts
|
||||
*/
|
||||
import { scoreProduct, type DimensionAssessment, type DimensionKey } from '../src/index.js'
|
||||
|
||||
/** The overall score a hand-scored summary might report: roughly the average. */
|
||||
const HAND_SCORED_OVERALL = 69
|
||||
|
||||
const dimensions: Record<DimensionKey, DimensionAssessment> = {
|
||||
security: {
|
||||
raw: 70,
|
||||
// The scorer named this cap and still wrote 70.
|
||||
openCaps: [{
|
||||
id: 'sec.leaked-secret',
|
||||
evidence: [{ ref: 'docs/security-review.md:14', note: 'exposed API key not yet rotated' }],
|
||||
}],
|
||||
evidence: [{ ref: 'docs/security-review.md' }],
|
||||
bindingConstraint: 'exposed API key not yet rotated',
|
||||
nextAction: 'rotate the key and redeploy',
|
||||
},
|
||||
bugs: {
|
||||
raw: 68,
|
||||
evidence: [{ ref: 'test/api.test.ts' }],
|
||||
bindingConstraint: 'API handlers lack behaviour tests',
|
||||
},
|
||||
compliance: {
|
||||
raw: 73,
|
||||
evidence: [{ ref: 'docs/compliance-checklist.md' }],
|
||||
},
|
||||
consistency: {
|
||||
raw: 68,
|
||||
evidence: [{ ref: 'shared/ui/' }],
|
||||
},
|
||||
usability: {
|
||||
raw: 68,
|
||||
evidence: [{ ref: 'reports/accessibility-scan.json' }],
|
||||
bindingConstraint: 'accessibility findings not yet triaged',
|
||||
},
|
||||
}
|
||||
|
||||
const result = scoreProduct({ product: 'example-app', tier: 'A', dimensions })
|
||||
|
||||
console.log('Hand-scored vs rubric-enforced\n')
|
||||
for (const d of result.dimensions) {
|
||||
const flag = d.boundBy ? ` <- CAPPED by ${d.boundBy.id} (${d.boundBy.max})` : ''
|
||||
console.log(
|
||||
` ${d.dimension.padEnd(12)} raw ${String(d.raw).padStart(3)} -> ${String(d.score).padStart(3)} ${d.band.name}${flag}`,
|
||||
)
|
||||
}
|
||||
console.log(`\n hand-scored overall : ~${HAND_SCORED_OVERALL}`)
|
||||
console.log(` enforced overall : ${result.overall} (${result.band.name})`)
|
||||
console.log(` weakest : ${result.weakest}`)
|
||||
console.log(` average : ${result.average} (reported, never the headline)`)
|
||||
console.log(` delta : ${result.overall - HAND_SCORED_OVERALL}`)
|
||||
|
||||
if (result.overall < HAND_SCORED_OVERALL) {
|
||||
console.log('\n The hand-scored number is higher than the rubric permits.')
|
||||
}
|
||||
Reference in New Issue
Block a user