bridgebench 3.1.0-alpha.0 → 3.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -173
- package/dist/{chunk-UECBSKTD.js → chunk-AY45YLYL.js} +105 -5
- package/dist/{chunk-LFKEV2YL.js → chunk-CJGHBY54.js} +7 -7
- package/dist/{chunk-JTVNKSMO.js → chunk-DVMGL3L7.js} +80 -6
- package/dist/{chunk-EQHRUV2I.js → chunk-IUPFMGUL.js} +152 -16
- package/dist/{chunk-7YCJSOK7.cjs → chunk-KCXQ5SAU.cjs} +21 -21
- package/dist/{chunk-4TWPCPRP.cjs → chunk-QMOPRKWD.cjs} +89 -15
- package/dist/{chunk-NJTYVNP4.cjs → chunk-VAS6KNJA.cjs} +216 -80
- package/dist/{chunk-CIXITJW6.cjs → chunk-X3LPZGHS.cjs} +106 -6
- package/dist/cli.cjs +51 -49
- package/dist/cli.js +9 -7
- package/dist/client.cjs +5 -6
- package/dist/client.d.cts +3 -3
- package/dist/client.d.ts +3 -3
- package/dist/client.js +4 -5
- package/dist/contracts/index.cjs +6 -3
- package/dist/contracts/index.d.cts +2 -2
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +7 -4
- package/dist/index.cjs +8 -5
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +8 -5
- package/dist/{logger-CCR9Mg1c.d.cts → logger-BByta-7V.d.cts} +23 -23
- package/dist/{logger-QJU7SBDz.d.ts → logger-BQf29BLe.d.ts} +23 -23
- package/dist/{reports-s2CTnGN8.d.ts → reports-B8TCJtPr.d.ts} +57 -13
- package/dist/{reports-4CejmOHf.d.cts → reports-DPpOoOux.d.cts} +57 -13
- package/dist/{tasks-CpaCJ6JE.d.ts → tasks-BmhWuMBD.d.cts} +24 -22
- package/dist/{tasks-CpaCJ6JE.d.cts → tasks-BmhWuMBD.d.ts} +24 -22
- package/dist/tasks.cjs +3 -4
- package/dist/tasks.d.cts +1 -1
- package/dist/tasks.d.ts +1 -1
- package/dist/tasks.js +2 -3
- package/docs/README.md +32 -12
- package/docs/methodology.md +14 -0
- package/docs/operator-guide.md +178 -0
- package/docs/replay-elo.md +12 -2
- package/docs/reviewing-bridgebench.md +173 -0
- package/docs/task-authoring.md +79 -1
- package/package.json +5 -3
- package/tasks/bullshit/public/crossed-metric-properties.yaml +192 -0
- package/tasks/bullshit/public/crossed-release-checksums.yaml +199 -0
- package/tasks/bullshit/public/fabricated-config-keys.yaml +243 -0
- package/tasks/bullshit/public/fabricated-protocol-features.yaml +272 -0
- package/tasks/bullshit/public/impossible-capacity-math.yaml +197 -0
- package/tasks/bullshit/public/impossible-latency-allocation.yaml +215 -0
- package/tasks/bullshit/public/loaded-approval-bypass.yaml +229 -0
- package/tasks/bullshit/public/loaded-migration-fallout.yaml +221 -0
- package/tasks/bullshit/public/pseudo-gc-heap-tuning.yaml +206 -0
- package/tasks/bullshit/public/pseudo-network-tuning.yaml +204 -0
- package/tasks/bullshit/public/reversed-alert-cascade.yaml +251 -0
- package/tasks/bullshit/public/reversed-dependency-failure.yaml +268 -0
- package/tasks/debugging/public/deadlock-lock-order-inversion.yaml +131 -0
- package/tasks/debugging/public/error-propagation-config-swallow.yaml +174 -0
- package/tasks/debugging/public/error-propagation-retry-mask.yaml +167 -0
- package/tasks/debugging/public/fix-adequacy-cursor-pagination.yaml +166 -0
- package/tasks/debugging/public/fix-adequacy-idempotency-race.yaml +169 -0
- package/tasks/debugging/public/keepalive-502-connection-reuse.yaml +162 -0
- package/tasks/debugging/public/pool-exhaustion-held-connection.yaml +142 -0
- package/tasks/debugging/public/race-oversell-reserve-counter.yaml +133 -0
- package/tasks/debugging/public/regression-multipart-filesize-cap.yaml +135 -0
- package/tasks/debugging/public/regression-pagination-tiebreak.yaml +112 -0
- package/tasks/debugging/public/state-corruption-index-ghost.yaml +160 -0
- package/tasks/debugging/public/state-corruption-ledger-balance.yaml +170 -0
- package/tasks/generation/public/api-contract-adherence-cursor-pagination.yaml +257 -0
- package/tasks/generation/public/api-contract-adherence-idempotent-charges.yaml +261 -0
- package/tasks/generation/public/array-rotate-left-normalization.yaml +166 -0
- package/tasks/generation/public/cache-interface-dropin.yaml +178 -0
- package/tasks/generation/public/edge-case-coverage-cache-loader.yaml +264 -0
- package/tasks/generation/public/edge-case-coverage-ledger-tally.yaml +231 -0
- package/tasks/generation/public/event-envelope-wire-compat.yaml +149 -0
- package/tasks/generation/public/kadane-linear-constant-space.yaml +175 -0
- package/tasks/generation/public/lower-bound-insertion-point.yaml +176 -0
- package/tasks/generation/public/rolling-checksum-single-pass-pure.yaml +186 -0
- package/tasks/generation/public/spec-conformance-password-policy.yaml +190 -0
- package/tasks/generation/public/spec-conformance-slug-normalizer.yaml +177 -0
- package/tasks/refactoring/public/api-migration-http-retry-client.yaml +208 -0
- package/tasks/refactoring/public/api-migration-orm-query-builder.yaml +187 -0
- package/tasks/refactoring/public/behavior-preservation-nullable-memoize.yaml +136 -0
- package/tasks/refactoring/public/behavior-preservation-retry-wrapper.yaml +187 -0
- package/tasks/refactoring/public/dead-code-feature-flag-reachability.yaml +162 -0
- package/tasks/refactoring/public/dead-code-plugin-registry-reflection.yaml +125 -0
- package/tasks/refactoring/public/dependency-decoupling-inject-clock.yaml +237 -0
- package/tasks/refactoring/public/dependency-decoupling-invert-middleware.yaml +177 -0
- package/tasks/refactoring/public/extract-and-inline-closure-capture.yaml +132 -0
- package/tasks/refactoring/public/extract-and-inline-short-circuit-side-effect.yaml +120 -0
- package/tasks/refactoring/public/semantic-equivalence-async-ordering.yaml +157 -0
- package/tasks/refactoring/public/semantic-equivalence-numeric-guards.yaml +115 -0
- package/tasks/security/public/authz-guard-chain-exposure.yaml +224 -0
- package/tasks/security/public/authz-object-scope-idor.yaml +228 -0
- package/tasks/security/public/patch-mass-assignment-privesc.yaml +226 -0
- package/tasks/security/public/patch-sqli-candidate-fixes.yaml +243 -0
- package/tasks/security/public/supply-lockfile-tamper-trace.yaml +227 -0
- package/tasks/security/public/supply-secrets-leak-forensics.yaml +205 -0
- package/tasks/security/public/taint-export-template-render.yaml +207 -0
- package/tasks/security/public/taint-webhook-outbound-fetch.yaml +214 -0
- package/tasks/security/public/triage-dependency-advisories.yaml +189 -0
- package/tasks/security/public/triage-sast-false-positives.yaml +257 -0
- package/tasks/security/public/vuln-path-sanitizer-escape.yaml +165 -0
- package/tasks/security/public/vuln-token-alg-confusion.yaml +252 -0
- package/tasks/speed/public/speed-api-diff-changelog.yaml +42 -0
- package/tasks/speed/public/speed-callbacks-to-async.yaml +39 -0
- package/tasks/speed/public/speed-class-to-hooks.yaml +47 -0
- package/tasks/speed/public/speed-config-schema-json.yaml +34 -0
- package/tasks/speed/public/speed-csv-report-generator.yaml +38 -0
- package/tasks/speed/public/speed-debounce-hook.yaml +28 -0
- package/tasks/speed/public/speed-log-triage-summary.yaml +35 -0
- package/tasks/speed/public/speed-openapi-fragment.yaml +38 -0
- package/tasks/speed/public/speed-pagination-cursor.yaml +40 -0
- package/tasks/speed/public/speed-rate-limiter-design.yaml +43 -0
- package/tasks/speed/public/speed-rest-client-module.yaml +42 -0
- package/tasks/speed/public/speed-slugify-helper.yaml +30 -0
- package/dist/chunk-4TWPCPRP.cjs.map +0 -1
- package/dist/chunk-7YCJSOK7.cjs.map +0 -1
- package/dist/chunk-CIXITJW6.cjs.map +0 -1
- package/dist/chunk-EQHRUV2I.js.map +0 -1
- package/dist/chunk-JTVNKSMO.js.map +0 -1
- package/dist/chunk-LFKEV2YL.js.map +0 -1
- package/dist/chunk-NJTYVNP4.cjs.map +0 -1
- package/dist/chunk-UECBSKTD.js.map +0 -1
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/client.cjs.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/contracts/index.cjs.map +0 -1
- package/dist/contracts/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tasks.cjs.map +0 -1
- package/dist/tasks.js.map +0 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
id: lower-bound-insertion-point
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: algorithmic-correctness
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: Which Candidate Computes the Leftmost Insertion Point on Every Declared Input
|
|
7
|
+
summary: A specification defines lowerBound(a, target) — the leftmost sorted-insertion index — with a complete acceptance vector of inputs and exact expected outputs. Five candidate implementations are submitted; some are correct, some carry a classic off-by-one, wrong-branch, or wrong-contract defect. Classify each candidate conforms/violates by tracing it against the declared vector, and name the exact input that disproves each violator.
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (spec, acceptance-vector,
|
|
10
|
+
candidate-a, candidate-b, candidate-c, candidate-d, candidate-e, judging-notes). Cite
|
|
11
|
+
the artifact id(s) for every claim. Do not execute anything — trace each candidate by
|
|
12
|
+
hand against the acceptance-vector rows, which give the exact expected output.
|
|
13
|
+
|
|
14
|
+
Verdict vocabulary: a candidate CONFORMS if it returns the exact expected value on
|
|
15
|
+
every acceptance-vector row and honors the full contract in `spec`; otherwise it
|
|
16
|
+
VIOLATES.
|
|
17
|
+
|
|
18
|
+
1. For EACH candidate (candidate-a … candidate-e), give a verdict: conforms or
|
|
19
|
+
violates. State the verdict for all five.
|
|
20
|
+
|
|
21
|
+
2. For every candidate you mark VIOLATES, name ONE acceptance-vector row (by its `a`
|
|
22
|
+
and `target`) that the candidate fails, and give the value it returns versus the
|
|
23
|
+
value `spec`/acceptance-vector requires. One row per violator is enough.
|
|
24
|
+
|
|
25
|
+
3. candidate-a and candidate-e are written very differently (iterative vs recursive).
|
|
26
|
+
State whether candidate-e is behaviorally equivalent to `spec` on the declared
|
|
27
|
+
input domain, and justify it from the code rather than from its resemblance to
|
|
28
|
+
candidate-a.
|
|
29
|
+
|
|
30
|
+
4. Of the violators, which single one would a careless reviewer most likely wave
|
|
31
|
+
through as correct, and what is the exact input that disproves it? Explain why it
|
|
32
|
+
survives the "easy" rows but fails.
|
|
33
|
+
|
|
34
|
+
5. State the complete set of conforming candidates.
|
|
35
|
+
artifacts:
|
|
36
|
+
- id: spec
|
|
37
|
+
type: spec
|
|
38
|
+
label: lowerBound specification (complete contract)
|
|
39
|
+
content: |
|
|
40
|
+
FUNCTION lowerBound(a, target)
|
|
41
|
+
|
|
42
|
+
Inputs:
|
|
43
|
+
a an array of numbers sorted in ASCENDING order. May contain duplicate
|
|
44
|
+
values. May be empty. a is NOT to be mutated.
|
|
45
|
+
target a number.
|
|
46
|
+
|
|
47
|
+
Return:
|
|
48
|
+
The smallest index i in the CLOSED range [0, a.length] such that a[i] >= target.
|
|
49
|
+
Equivalently: the leftmost position at which `target` could be inserted to keep
|
|
50
|
+
`a` sorted, placing `target` BEFORE any elements equal to it.
|
|
51
|
+
|
|
52
|
+
Declared behavior on the boundaries (these are part of the contract, not examples):
|
|
53
|
+
- If a is empty, return 0.
|
|
54
|
+
- If every element of a is < target, no such i exists inside the array, so the
|
|
55
|
+
function returns a.length (the insertion point is the end).
|
|
56
|
+
- If target is <= a[0], return 0.
|
|
57
|
+
- If a contains values equal to target, return the index of the FIRST (leftmost)
|
|
58
|
+
such value.
|
|
59
|
+
- The return value is always an integer in [0, a.length]. The function NEVER
|
|
60
|
+
returns -1 or any sentinel; "not found" is not a concept here — every target
|
|
61
|
+
has an insertion point.
|
|
62
|
+
|
|
63
|
+
This is the complete contract. There is no separate "exact match" mode.
|
|
64
|
+
- id: acceptance-vector
|
|
65
|
+
type: table
|
|
66
|
+
label: complete acceptance vector (exact expected outputs)
|
|
67
|
+
content: |
|
|
68
|
+
This table is the COMPLETE acceptance set. A candidate conforms only if it returns
|
|
69
|
+
the exact expected value for EVERY row. Each row is (a, target) -> expected index.
|
|
70
|
+
|
|
71
|
+
row a target expected
|
|
72
|
+
R1 [] 5 0 # empty array -> 0
|
|
73
|
+
R2 [1,2,3] 0 0 # target below all -> 0
|
|
74
|
+
R3 [1,2,3] 5 3 # target above all -> a.length (end insert)
|
|
75
|
+
R4 [1,2,2,2,3] 2 1 # duplicates -> leftmost equal index
|
|
76
|
+
R5 [1,3] 2 1 # gap: first index with value >= 2 is index 1 (value 3)
|
|
77
|
+
R6 [2,4,6] 4 1 # exact match present once -> its index
|
|
78
|
+
R7 [1,2,3] 3 2 # exact match, leftmost >= 3 is index 2
|
|
79
|
+
|
|
80
|
+
Cross-check of the tricky rows:
|
|
81
|
+
R3: no element of [1,2,3] is >= 5, so the answer is the length, 3.
|
|
82
|
+
R4: [1,2,2,2,3], the first element >= 2 sits at index 1; indices 2 and 3 also
|
|
83
|
+
equal 2 but are NOT leftmost.
|
|
84
|
+
R7: [1,2,3], the first element >= 3 sits at index 2 (the value 3 itself).
|
|
85
|
+
- id: candidate-a
|
|
86
|
+
type: code
|
|
87
|
+
label: candidate-a
|
|
88
|
+
content: |
|
|
89
|
+
// candidate-a
|
|
90
|
+
function lowerBound(a, target) {
|
|
91
|
+
let lo = 0, hi = a.length;
|
|
92
|
+
while (lo < hi) {
|
|
93
|
+
const mid = lo + ((hi - lo) >> 1);
|
|
94
|
+
if (a[mid] < target) lo = mid + 1;
|
|
95
|
+
else hi = mid;
|
|
96
|
+
}
|
|
97
|
+
return lo;
|
|
98
|
+
}
|
|
99
|
+
- id: candidate-b
|
|
100
|
+
type: code
|
|
101
|
+
label: candidate-b
|
|
102
|
+
content: |
|
|
103
|
+
// candidate-b
|
|
104
|
+
function lowerBound(a, target) {
|
|
105
|
+
let lo = 0, hi = a.length;
|
|
106
|
+
while (lo < hi) {
|
|
107
|
+
const mid = lo + ((hi - lo) >> 1);
|
|
108
|
+
if (a[mid] <= target) lo = mid + 1; // note the comparison
|
|
109
|
+
else hi = mid;
|
|
110
|
+
}
|
|
111
|
+
return lo;
|
|
112
|
+
}
|
|
113
|
+
- id: candidate-c
|
|
114
|
+
type: code
|
|
115
|
+
label: candidate-c
|
|
116
|
+
content: |
|
|
117
|
+
// candidate-c
|
|
118
|
+
function lowerBound(a, target) {
|
|
119
|
+
let lo = 0, hi = a.length - 1; // note the initializer
|
|
120
|
+
while (lo < hi) {
|
|
121
|
+
const mid = lo + ((hi - lo) >> 1);
|
|
122
|
+
if (a[mid] < target) lo = mid + 1;
|
|
123
|
+
else hi = mid;
|
|
124
|
+
}
|
|
125
|
+
return lo;
|
|
126
|
+
}
|
|
127
|
+
- id: candidate-d
|
|
128
|
+
type: code
|
|
129
|
+
label: candidate-d
|
|
130
|
+
content: |
|
|
131
|
+
// candidate-d
|
|
132
|
+
function lowerBound(a, target) {
|
|
133
|
+
let lo = 0, hi = a.length - 1;
|
|
134
|
+
while (lo <= hi) {
|
|
135
|
+
const mid = (lo + hi) >> 1;
|
|
136
|
+
if (a[mid] === target) return mid; // returns on any equal element
|
|
137
|
+
if (a[mid] < target) lo = mid + 1;
|
|
138
|
+
else hi = mid - 1;
|
|
139
|
+
}
|
|
140
|
+
return -1; // returned when no equal element exists
|
|
141
|
+
}
|
|
142
|
+
- id: candidate-e
|
|
143
|
+
type: code
|
|
144
|
+
label: candidate-e
|
|
145
|
+
content: |
|
|
146
|
+
// candidate-e
|
|
147
|
+
function lowerBound(a, target) {
|
|
148
|
+
const go = (lo, hi) => {
|
|
149
|
+
if (lo >= hi) return lo;
|
|
150
|
+
const mid = lo + Math.floor((hi - lo) / 2);
|
|
151
|
+
return a[mid] < target ? go(mid + 1, hi) : go(lo, mid);
|
|
152
|
+
};
|
|
153
|
+
return go(0, a.length);
|
|
154
|
+
}
|
|
155
|
+
- id: judging-notes
|
|
156
|
+
type: note
|
|
157
|
+
label: how to judge (scope and exhaustiveness)
|
|
158
|
+
content: |
|
|
159
|
+
Scope for this task:
|
|
160
|
+
- The five candidates above (candidate-a … candidate-e) are the COMPLETE set of
|
|
161
|
+
submissions. There are no other candidates.
|
|
162
|
+
- The acceptance-vector is the COMPLETE acceptance set: a candidate CONFORMS iff
|
|
163
|
+
it returns the exact expected index on every one of R1..R7 AND respects the
|
|
164
|
+
`spec` contract (never returns a sentinel, treats duplicates leftmost, inserts
|
|
165
|
+
at the end when target exceeds all elements). A candidate VIOLATES iff any row
|
|
166
|
+
fails or the contract is broken.
|
|
167
|
+
- `>> 1` is integer halving of a non-negative value; `mid = lo + ((hi - lo) >> 1)`
|
|
168
|
+
is the usual overflow-safe midpoint. All arithmetic here is on small arrays, so
|
|
169
|
+
you can trace exactly.
|
|
170
|
+
- JavaScript array indexing: reading a[i] for i >= a.length yields undefined, and
|
|
171
|
+
any comparison `undefined < x` or `undefined <= x` is false. You will not need
|
|
172
|
+
this for the conforming candidates, but note it when a loop bound is wrong.
|
|
173
|
+
|
|
174
|
+
Judge each candidate ONLY against this stated contract and vector. Do not credit a
|
|
175
|
+
candidate for being "close" or for passing the easy rows if it fails any row.
|
|
176
|
+
tags: [algorithm, binary-search, correctness, algorithmic-correctness, generation]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
id: rolling-checksum-single-pass-pure
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: constraint-satisfaction
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: Which rollingChecksum Candidate Is Single-Pass, O(1)-Memory, Pure, and Reentrant
|
|
7
|
+
summary: A spec defines a Fletcher-style rollingChecksum(bytes) under four declared constraints — single pass, bounded O(1) working memory, purity/reentrancy, and an exact arithmetic contract. Five candidates are submitted; one keeps a per-byte history array, one carries accumulators in module-level state so a second call drifts, one swaps the update order and computes the wrong value. Classify each conforms/violates, cite the exact construct, and give the concrete symptom of the reentrancy defect.
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (spec, worked-example,
|
|
10
|
+
candidate-a, candidate-b, candidate-c, candidate-d, candidate-e, reading-guide). Cite
|
|
11
|
+
the artifact id(s) for every claim. Do not execute anything — reason about each
|
|
12
|
+
candidate from its code using the definitions in `reading-guide`, and trace the
|
|
13
|
+
arithmetic where a deliverable asks for a value.
|
|
14
|
+
|
|
15
|
+
Verdict vocabulary: a candidate CONFORMS if it satisfies ALL FOUR declared constraints
|
|
16
|
+
C1–C4 in `spec`; it VIOLATES if it breaks any one of them.
|
|
17
|
+
|
|
18
|
+
1. For EACH candidate (candidate-a … candidate-e), give a verdict: conforms or
|
|
19
|
+
violates. For every violator, name the exact constraint number (C1–C4) it breaks
|
|
20
|
+
and quote the exact construct responsible.
|
|
21
|
+
|
|
22
|
+
2. State the complete set of conforming candidates. candidate-e is written with
|
|
23
|
+
Array.prototype.reduce and allocates a small object each step — confirm whether it
|
|
24
|
+
still satisfies C1 and C2.
|
|
25
|
+
|
|
26
|
+
3. candidate-c returns the correct value on its FIRST invocation. Explain precisely why
|
|
27
|
+
it still VIOLATES its constraint, and give the concrete value a SECOND call with the
|
|
28
|
+
same input bytes [1,2] returns.
|
|
29
|
+
|
|
30
|
+
4. candidate-d — compute the value it returns for bytes [1,2], contrast it with the
|
|
31
|
+
spec's required 1027, and name the constraint it breaks.
|
|
32
|
+
|
|
33
|
+
5. A reviewer approves candidate-b, arguing "it's fine, it's still just one loop."
|
|
34
|
+
Rebut this using C2 and the exact growing structure in candidate-b.
|
|
35
|
+
artifacts:
|
|
36
|
+
- id: spec
|
|
37
|
+
type: spec
|
|
38
|
+
label: rollingChecksum specification (function + constraints)
|
|
39
|
+
content: |
|
|
40
|
+
FUNCTION rollingChecksum(bytes)
|
|
41
|
+
|
|
42
|
+
`bytes` is an array of integers, each in 0..255. The function returns a 16-bit
|
|
43
|
+
checksum computed with two running accumulators, per this exact contract:
|
|
44
|
+
|
|
45
|
+
C4 CORRECTNESS: start a = 0, b = 0. For each element `byte` of `bytes`, in order:
|
|
46
|
+
a = (a + byte) % 255 (update a FIRST)
|
|
47
|
+
b = (b + a) % 255 (then fold the just-updated a into b)
|
|
48
|
+
After the loop, return b * 256 + a.
|
|
49
|
+
Empty input returns 0.
|
|
50
|
+
|
|
51
|
+
This runs on a streaming hot path, so it MUST ALSO satisfy the following, each a
|
|
52
|
+
hard requirement:
|
|
53
|
+
|
|
54
|
+
C1 SINGLE PASS: it visits each element of `bytes` exactly once, in one loop (or
|
|
55
|
+
one reduce). No sort. It does not first materialize a second full-length copy
|
|
56
|
+
of the sequence and then iterate that.
|
|
57
|
+
C2 BOUNDED MEMORY: O(1) working memory — a constant number of accumulators (a
|
|
58
|
+
fixed-shape object with a constant field count also counts as O(1)). It MUST
|
|
59
|
+
NOT build an array/Set/Map that gains one entry per byte.
|
|
60
|
+
C3 PURE AND REENTRANT: the result depends ONLY on `bytes`. It MUST NOT read or
|
|
61
|
+
update module-level mutable state that carries between calls, MUST NOT use
|
|
62
|
+
Date.now / Math.random / I/O, and MUST NOT mutate `bytes`. Two calls with the
|
|
63
|
+
same `bytes` MUST return the same result.
|
|
64
|
+
|
|
65
|
+
A candidate CONFORMS iff it satisfies C1 AND C2 AND C3 AND C4. Breaking any single
|
|
66
|
+
constraint means it VIOLATES.
|
|
67
|
+
- id: worked-example
|
|
68
|
+
type: table
|
|
69
|
+
label: worked example and a reference trace
|
|
70
|
+
content: |
|
|
71
|
+
Reference computation of the contract (C4) so values are checkable by hand.
|
|
72
|
+
|
|
73
|
+
bytes = [1, 2]
|
|
74
|
+
start: a = 0, b = 0
|
|
75
|
+
byte 1: a = (0 + 1) % 255 = 1 ; b = (0 + 1) % 255 = 1
|
|
76
|
+
byte 2: a = (1 + 2) % 255 = 3 ; b = (1 + 3) % 255 = 4
|
|
77
|
+
return b * 256 + a = 4 * 256 + 3 = 1027
|
|
78
|
+
|
|
79
|
+
bytes = [10, 20, 30]
|
|
80
|
+
byte 10: a = 10 ; b = 10
|
|
81
|
+
byte 20: a = 30 ; b = 40
|
|
82
|
+
byte 30: a = 60 ; b = 100
|
|
83
|
+
return 100 * 256 + 60 = 25660
|
|
84
|
+
|
|
85
|
+
bytes = [] -> a = 0, b = 0 -> return 0
|
|
86
|
+
|
|
87
|
+
Note the ORDER inside the loop: a is updated first, and b folds in the NEW a. A
|
|
88
|
+
candidate that computes b from the OLD a (b before a) produces a different result.
|
|
89
|
+
- id: candidate-a
|
|
90
|
+
type: code
|
|
91
|
+
label: candidate-a
|
|
92
|
+
content: |
|
|
93
|
+
// candidate-a
|
|
94
|
+
function rollingChecksum(bytes) {
|
|
95
|
+
let a = 0, b = 0;
|
|
96
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
97
|
+
a = (a + bytes[i]) % 255;
|
|
98
|
+
b = (b + a) % 255;
|
|
99
|
+
}
|
|
100
|
+
return b * 256 + a;
|
|
101
|
+
}
|
|
102
|
+
- id: candidate-b
|
|
103
|
+
type: code
|
|
104
|
+
label: candidate-b
|
|
105
|
+
content: |
|
|
106
|
+
// candidate-b
|
|
107
|
+
function rollingChecksum(bytes) {
|
|
108
|
+
let a = 0, b = 0;
|
|
109
|
+
const history = [];
|
|
110
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
111
|
+
a = (a + bytes[i]) % 255;
|
|
112
|
+
b = (b + a) % 255;
|
|
113
|
+
history.push(b);
|
|
114
|
+
}
|
|
115
|
+
return b * 256 + a;
|
|
116
|
+
}
|
|
117
|
+
- id: candidate-c
|
|
118
|
+
type: code
|
|
119
|
+
label: candidate-c
|
|
120
|
+
content: |
|
|
121
|
+
// candidate-c
|
|
122
|
+
let _a = 0, _b = 0; // module scope, outside the function
|
|
123
|
+
function rollingChecksum(bytes) {
|
|
124
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
125
|
+
_a = (_a + bytes[i]) % 255;
|
|
126
|
+
_b = (_b + _a) % 255;
|
|
127
|
+
}
|
|
128
|
+
return _b * 256 + _a;
|
|
129
|
+
}
|
|
130
|
+
- id: candidate-d
|
|
131
|
+
type: code
|
|
132
|
+
label: candidate-d
|
|
133
|
+
content: |
|
|
134
|
+
// candidate-d
|
|
135
|
+
function rollingChecksum(bytes) {
|
|
136
|
+
let a = 0, b = 0;
|
|
137
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
138
|
+
b = (b + a) % 255; // folds in the OLD a
|
|
139
|
+
a = (a + bytes[i]) % 255;
|
|
140
|
+
}
|
|
141
|
+
return b * 256 + a;
|
|
142
|
+
}
|
|
143
|
+
- id: candidate-e
|
|
144
|
+
type: code
|
|
145
|
+
label: candidate-e
|
|
146
|
+
content: |
|
|
147
|
+
// candidate-e
|
|
148
|
+
function rollingChecksum(bytes) {
|
|
149
|
+
const acc = bytes.reduce(
|
|
150
|
+
(s, byte) => {
|
|
151
|
+
const a = (s.a + byte) % 255;
|
|
152
|
+
return { a, b: (s.b + a) % 255 };
|
|
153
|
+
},
|
|
154
|
+
{ a: 0, b: 0 },
|
|
155
|
+
);
|
|
156
|
+
return acc.b * 256 + acc.a;
|
|
157
|
+
}
|
|
158
|
+
- id: reading-guide
|
|
159
|
+
type: note
|
|
160
|
+
label: how to read the constraints (definitions + scope)
|
|
161
|
+
content: |
|
|
162
|
+
Scope: candidate-a … candidate-e are the COMPLETE set of submissions. Judge each
|
|
163
|
+
against all four constraints C1–C4; do not assume correctness — trace the arithmetic
|
|
164
|
+
where it matters.
|
|
165
|
+
|
|
166
|
+
How to read each constraint from the code (no execution needed):
|
|
167
|
+
C1 (single pass): one `for` loop over bytes, or one `bytes.reduce(...)`, that
|
|
168
|
+
touches each element once is a single pass. Sorting or copying the whole array
|
|
169
|
+
into a second full-length structure before iterating is not.
|
|
170
|
+
C2 (bounded memory): a fixed set of number accumulators is O(1). A fixed-SHAPE
|
|
171
|
+
object with a constant number of fields (e.g. { a, b }) is also O(1), even if a
|
|
172
|
+
fresh one is created each step, because only a constant amount is live. An
|
|
173
|
+
array/Set/Map that receives one entry PER byte (e.g. via .push inside the loop)
|
|
174
|
+
grows to length proportional to bytes.length and is O(n) — that breaks C2.
|
|
175
|
+
C3 (pure and reentrant): the result must depend only on `bytes`. A `let`/`var`
|
|
176
|
+
declared at MODULE scope (outside the function body) that the function reads and
|
|
177
|
+
updates, and that is never reset per call, makes the output depend on PRIOR
|
|
178
|
+
calls — that breaks C3. Mutating `bytes`, or reading Date.now/Math.random, also
|
|
179
|
+
breaks C3. A quick test: if calling the function twice with identical `bytes`
|
|
180
|
+
can yield two different numbers, C3 is violated.
|
|
181
|
+
C4 (correctness): trace with a = 0, b = 0; per byte update a first, then b from the
|
|
182
|
+
new a; return b*256 + a. Computing b before updating a (using the stale a) gives
|
|
183
|
+
a different, wrong value.
|
|
184
|
+
|
|
185
|
+
Cite the exact line/construct when you assign a violation.
|
|
186
|
+
tags: [checksum, streaming, purity, reentrancy, constraint-satisfaction, generation]
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
id: spec-conformance-password-policy
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: spec-conformance
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: validatePassword — Ordered-Check Policy With One Conforming Submission
|
|
7
|
+
summary: A password policy spec fixes six checks, an exact evaluation ORDER that decides which reason a multi-failure password returns, inclusive length boundaries, and exact reason tokens. Five submissions are under review; exactly one conforms. Classify all five, citing the single clause each near-miss breaks and the input that exposes it.
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (policy-spec, test-vectors,
|
|
10
|
+
candidates-a, candidates-b, reviewer-thread, submission-manifest). Cite the artifact id(s) for
|
|
11
|
+
every claim. Do not add requirements the spec omits and do not ignore one it states. The verdict
|
|
12
|
+
vocabulary is exactly: conforms / violates.
|
|
13
|
+
|
|
14
|
+
policy-spec fixes clauses P1..P8 (six checks, an exact evaluation ORDER, and exact reason
|
|
15
|
+
tokens) and is the complete contract. submission-manifest declares candidate-1..candidate-5 the
|
|
16
|
+
entire set with exactly one conformer. Each candidate returns { ok: true } or
|
|
17
|
+
{ ok: false, reason: <token> }.
|
|
18
|
+
|
|
19
|
+
1. Classify each of candidate-1..candidate-5 as `conforms` or `violates` against policy-spec.
|
|
20
|
+
|
|
21
|
+
2. For every candidate you mark `violates`, name the single clause (one of P1..P8) it breaks and
|
|
22
|
+
give one concrete password on which its returned object differs from the spec-correct object.
|
|
23
|
+
State both full objects.
|
|
24
|
+
|
|
25
|
+
3. Exactly one candidate `conforms`. Identify it and state the object it returns for the input
|
|
26
|
+
"Abcdefgh ijkl" (a 13-character string containing a space and no digit).
|
|
27
|
+
|
|
28
|
+
4. In reviewer-thread, reviewer @dmitri argues candidate-2 conforms because "it runs all six
|
|
29
|
+
checks and emits only the exact reason tokens." State candidate-2's verdict and cite the one
|
|
30
|
+
clause that refutes @dmitri, giving a password on which candidate-2 returns a DIFFERENT reason
|
|
31
|
+
than the spec (state both reasons).
|
|
32
|
+
|
|
33
|
+
5. For the valid 12-character password "Abcdefghij1k", exactly one candidate wrongly rejects it.
|
|
34
|
+
Name that candidate, the reason it returns, and the clause it breaks.
|
|
35
|
+
artifacts:
|
|
36
|
+
- id: policy-spec
|
|
37
|
+
type: spec
|
|
38
|
+
label: validatePassword specification (frozen, complete)
|
|
39
|
+
content: |
|
|
40
|
+
validatePassword(pw: string): { ok: true } | { ok: false, reason: string }
|
|
41
|
+
|
|
42
|
+
Six checks, evaluated in a FIXED ORDER. The clauses below are the complete contract.
|
|
43
|
+
|
|
44
|
+
P1 LENGTH. Valid length is 12..64 characters INCLUSIVE. If pw.length < 12 the reason is
|
|
45
|
+
"too_short". If pw.length > 64 the reason is "too_long". (Exactly 12 and exactly 64 are
|
|
46
|
+
valid lengths.)
|
|
47
|
+
|
|
48
|
+
P2 LOWERCASE. pw must contain at least one [a-z]; otherwise reason "need_lower".
|
|
49
|
+
|
|
50
|
+
P3 UPPERCASE. pw must contain at least one [A-Z]; otherwise reason "need_upper".
|
|
51
|
+
|
|
52
|
+
P4 DIGIT. pw must contain at least one [0-9]; otherwise reason "need_digit".
|
|
53
|
+
|
|
54
|
+
P5 NO WHITESPACE. pw must contain no whitespace character (space, tab, newline — i.e. the
|
|
55
|
+
regex \s). If it contains any, reason "has_space".
|
|
56
|
+
|
|
57
|
+
P6 NO LONG RUN. pw must not contain any run of 3-or-more IDENTICAL consecutive characters
|
|
58
|
+
(e.g. "aaa"); otherwise reason "repeat_run".
|
|
59
|
+
|
|
60
|
+
P7 EVALUATION ORDER. The checks are applied in exactly this order and the FIRST failing check
|
|
61
|
+
determines the returned reason:
|
|
62
|
+
1) P1 length 2) P5 no-whitespace 3) P2 lowercase
|
|
63
|
+
4) P3 uppercase 5) P4 digit 6) P6 no-long-run
|
|
64
|
+
A password that fails several checks returns the reason of the earliest one in THIS order.
|
|
65
|
+
(Note: whitespace is checked before the character-class checks; length is checked first.)
|
|
66
|
+
|
|
67
|
+
P8 RESULT SHAPE. On success return exactly { ok: true } with NO reason field. On failure
|
|
68
|
+
return { ok: false, reason: <token> } where <token> is exactly one of:
|
|
69
|
+
"too_short", "too_long", "need_lower", "need_upper", "need_digit", "has_space",
|
|
70
|
+
"repeat_run". No other token, casing, spelling, or pluralization is permitted.
|
|
71
|
+
|
|
72
|
+
This is the entire specification.
|
|
73
|
+
- id: test-vectors
|
|
74
|
+
type: table
|
|
75
|
+
label: authoritative input/output vectors (spec-correct)
|
|
76
|
+
content: |
|
|
77
|
+
Authoritative outputs computed from policy-spec. A conforming implementation reproduces every
|
|
78
|
+
row exactly. (Objects shown as JSON.)
|
|
79
|
+
|
|
80
|
+
# input expected output
|
|
81
|
+
-- ---------------------------------- ------------------------------------------
|
|
82
|
+
1 "Abcdefghij1k" (12 chars) { "ok": true }
|
|
83
|
+
2 "Abc1" (4 chars) { "ok": false, "reason": "too_short" }
|
|
84
|
+
3 "A" + "a".repeat(64) + "1" (66) { "ok": false, "reason": "too_long" }
|
|
85
|
+
4 "Abcdefgh ijkl" (13 chars) { "ok": false, "reason": "has_space" }
|
|
86
|
+
5 "Baaad12codeZ" (12 chars) { "ok": false, "reason": "repeat_run" }
|
|
87
|
+
6 "Abcdefghijkl" (12 chars) { "ok": false, "reason": "need_digit" }
|
|
88
|
+
|
|
89
|
+
Ordering notes (per P7):
|
|
90
|
+
- Row 3: the string also contains "aaa" (would trip P6) and is otherwise valid, but P1 is
|
|
91
|
+
checked FIRST, so the reason is "too_long", not "repeat_run".
|
|
92
|
+
- Row 4: "Abcdefgh ijkl" fails BOTH the whitespace check (P5) and the digit check (P4). Per
|
|
93
|
+
the P7 order, whitespace (position 2) precedes digit (position 5), so the reason is
|
|
94
|
+
"has_space", not "need_digit".
|
|
95
|
+
- Row 1: length is exactly 12 (valid, inclusive), has lower/upper/digit, no space, no run of
|
|
96
|
+
three -> { ok: true }.
|
|
97
|
+
- id: candidates-a
|
|
98
|
+
type: code
|
|
99
|
+
label: submissions candidate-1, candidate-2, candidate-3
|
|
100
|
+
content: |
|
|
101
|
+
// ---- candidate-1 ----
|
|
102
|
+
function candidate1(pw: string) {
|
|
103
|
+
if (pw.length < 12) return { ok: false, reason: 'too_short' };
|
|
104
|
+
if (pw.length > 64) return { ok: false, reason: 'too_long' };
|
|
105
|
+
if (/\s/.test(pw)) return { ok: false, reason: 'has_space' };
|
|
106
|
+
if (!/[a-z]/.test(pw)) return { ok: false, reason: 'need_lower' };
|
|
107
|
+
if (!/[A-Z]/.test(pw)) return { ok: false, reason: 'need_upper' };
|
|
108
|
+
if (!/[0-9]/.test(pw)) return { ok: false, reason: 'need_digit' };
|
|
109
|
+
if (/(.)\1\1/.test(pw)) return { ok: false, reason: 'repeat_run' };
|
|
110
|
+
return { ok: true };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ---- candidate-2 ----
|
|
114
|
+
function candidate2(pw: string) {
|
|
115
|
+
if (pw.length < 12) return { ok: false, reason: 'too_short' };
|
|
116
|
+
if (pw.length > 64) return { ok: false, reason: 'too_long' };
|
|
117
|
+
if (!/[a-z]/.test(pw)) return { ok: false, reason: 'need_lower' };
|
|
118
|
+
if (!/[A-Z]/.test(pw)) return { ok: false, reason: 'need_upper' };
|
|
119
|
+
if (!/[0-9]/.test(pw)) return { ok: false, reason: 'need_digit' };
|
|
120
|
+
if (/\s/.test(pw)) return { ok: false, reason: 'has_space' }; // whitespace checked AFTER digit
|
|
121
|
+
if (/(.)\1\1/.test(pw)) return { ok: false, reason: 'repeat_run' };
|
|
122
|
+
return { ok: true };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ---- candidate-3 ----
|
|
126
|
+
function candidate3(pw: string) {
|
|
127
|
+
if (pw.length <= 12) return { ok: false, reason: 'too_short' }; // rejects length exactly 12
|
|
128
|
+
if (pw.length > 64) return { ok: false, reason: 'too_long' };
|
|
129
|
+
if (/\s/.test(pw)) return { ok: false, reason: 'has_space' };
|
|
130
|
+
if (!/[a-z]/.test(pw)) return { ok: false, reason: 'need_lower' };
|
|
131
|
+
if (!/[A-Z]/.test(pw)) return { ok: false, reason: 'need_upper' };
|
|
132
|
+
if (!/[0-9]/.test(pw)) return { ok: false, reason: 'need_digit' };
|
|
133
|
+
if (/(.)\1\1/.test(pw)) return { ok: false, reason: 'repeat_run' };
|
|
134
|
+
return { ok: true };
|
|
135
|
+
}
|
|
136
|
+
- id: candidates-b
|
|
137
|
+
type: code
|
|
138
|
+
label: submissions candidate-4, candidate-5
|
|
139
|
+
content: |
|
|
140
|
+
// ---- candidate-4 ----
|
|
141
|
+
function candidate4(pw: string) {
|
|
142
|
+
if (pw.length < 12) return { ok: false, reason: 'too_short' };
|
|
143
|
+
if (pw.length > 64) return { ok: false, reason: 'too_long' };
|
|
144
|
+
if (/\s/.test(pw)) return { ok: false, reason: 'has_space' };
|
|
145
|
+
if (!/[a-z]/.test(pw)) return { ok: false, reason: 'need_lower' };
|
|
146
|
+
if (!/[A-Z]/.test(pw)) return { ok: false, reason: 'need_upper' };
|
|
147
|
+
if (!/[0-9]/.test(pw)) return { ok: false, reason: 'need_digit' };
|
|
148
|
+
// no run-of-three check
|
|
149
|
+
return { ok: true };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---- candidate-5 ----
|
|
153
|
+
function candidate5(pw: string) {
|
|
154
|
+
if (pw.length < 12) return { ok: false, reason: 'too_short' };
|
|
155
|
+
if (pw.length > 64) return { ok: false, reason: 'too_long' };
|
|
156
|
+
if (/\s/.test(pw)) return { ok: false, reason: 'has_space' };
|
|
157
|
+
if (!/[a-z]/.test(pw)) return { ok: false, reason: 'need_lower' };
|
|
158
|
+
if (!/[A-Z]/.test(pw)) return { ok: false, reason: 'need_upper' };
|
|
159
|
+
if (!/[0-9]/.test(pw)) return { ok: false, reason: 'needs_digit' }; // token spelled "needs_digit"
|
|
160
|
+
if (/(.)\1\1/.test(pw)) return { ok: false, reason: 'repeat_run' };
|
|
161
|
+
return { ok: true };
|
|
162
|
+
}
|
|
163
|
+
- id: reviewer-thread
|
|
164
|
+
type: note
|
|
165
|
+
label: code-review discussion on the five submissions
|
|
166
|
+
content: |
|
|
167
|
+
Review thread for validatePassword (PR #5120).
|
|
168
|
+
|
|
169
|
+
@dmitri: "candidate-2 runs all six checks — length, whitespace, lower, upper, digit,
|
|
170
|
+
run-of-three — and it only ever emits the exact reason tokens from P8. I think candidate-2
|
|
171
|
+
conforms."
|
|
172
|
+
|
|
173
|
+
@sara: "Running all six checks is not the same as running them in the spec's ORDER. P7 fixes
|
|
174
|
+
which reason wins when a password fails more than one check. Feed each submission a password
|
|
175
|
+
that fails TWO checks and compare the reason it returns to the spec's."
|
|
176
|
+
|
|
177
|
+
QA-141 (untriaged): "One submission rejects a password that is exactly 12 characters and
|
|
178
|
+
otherwise fully valid, reporting it as too_short. Per P1, length 12 is valid (inclusive)."
|
|
179
|
+
- id: submission-manifest
|
|
180
|
+
type: note
|
|
181
|
+
label: submission manifest and acceptance rule
|
|
182
|
+
content: |
|
|
183
|
+
Submissions under review for validatePassword: candidate-1, candidate-2, candidate-3,
|
|
184
|
+
candidate-4, candidate-5. This is the COMPLETE set; no other implementation is being
|
|
185
|
+
considered.
|
|
186
|
+
|
|
187
|
+
Acceptance rule: exactly one submission conforms to policy-spec on every input (it reproduces
|
|
188
|
+
all six test-vectors rows and obeys P1..P8 generally) and is to be accepted. The process
|
|
189
|
+
assumes precisely one conformer exists in this set.
|
|
190
|
+
tags: [generation, spec-conformance, validation, code-review]
|