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,231 @@
|
|
|
1
|
+
id: edge-case-coverage-ledger-tally
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: edge-case-coverage
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: tally — Which Submission Handles Every Required Edge Case
|
|
7
|
+
summary: A ledger-tally spec enumerates six mandatory edge cases (empty input, duplicate-id last-wins, Unicode NFC grouping, integer overflow, blank-account skipping, zero-amount boundary). Six submissions are under review; exactly one handles all six while each of five decoys misses exactly one. Classify all six and pin the failing edge for each near-miss.
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (tally-spec, edge-vectors,
|
|
10
|
+
candidates-a, candidates-b, reviewer-thread, submission-manifest). Cite artifact id(s) for every
|
|
11
|
+
claim. Do not invent edge cases the spec omits and do not overlook one it requires. The verdict
|
|
12
|
+
vocabulary is exactly: conforms / violates. A submission `conforms` only if it handles EVERY
|
|
13
|
+
required edge case E1..E6 in tally-spec.
|
|
14
|
+
|
|
15
|
+
submission-manifest declares candidate-1..candidate-6 the complete set with exactly one that
|
|
16
|
+
handles all six edges. Each candidate accumulates per-account totals and returns them as a plain
|
|
17
|
+
object mapping account -> decimal-string total.
|
|
18
|
+
|
|
19
|
+
1. Classify each of candidate-1..candidate-6 as `conforms` or `violates`.
|
|
20
|
+
|
|
21
|
+
2. For every candidate you mark `violates`, name the single required edge (one of E1..E6) it
|
|
22
|
+
fails and cite the edge-vectors input on which its output differs from the expected output.
|
|
23
|
+
State both the expected output and the candidate's output.
|
|
24
|
+
|
|
25
|
+
3. Exactly one candidate `conforms` (handles all six edges). Identify it.
|
|
26
|
+
|
|
27
|
+
4. Which candidate(s), if any, drop an account whose only entry has amount "0" — i.e. FAIL E6
|
|
28
|
+
(zero-amount boundary)? If none do, say so explicitly and explain why.
|
|
29
|
+
|
|
30
|
+
5. In reviewer-thread, reviewer @nadia says candidate-4 "is fine because Unicode normalization is
|
|
31
|
+
a display concern, not an accounting one." Per tally-spec, does candidate-4 conform? Cite the
|
|
32
|
+
required edge and the edge-vectors input that settles it.
|
|
33
|
+
artifacts:
|
|
34
|
+
- id: tally-spec
|
|
35
|
+
type: spec
|
|
36
|
+
label: tally specification with required edge-case set (complete)
|
|
37
|
+
content: |
|
|
38
|
+
tally(entries: Entry[]): Record<string, string>
|
|
39
|
+
|
|
40
|
+
type Entry = { entryId: string; account: string; amount: string };
|
|
41
|
+
- amount is a base-10 INTEGER string (minor units), possibly larger than 2^53, never
|
|
42
|
+
fractional, never negative in this task's data.
|
|
43
|
+
- The result maps each surviving account to its total as a decimal string.
|
|
44
|
+
|
|
45
|
+
A conforming implementation MUST handle every one of the following required edge cases. This
|
|
46
|
+
list is COMPLETE — there are no other required edges, and an implementation that mishandles
|
|
47
|
+
any single one does NOT conform.
|
|
48
|
+
|
|
49
|
+
E1 EMPTY INPUT. tally([]) returns {} (an empty object). It must not throw and must not
|
|
50
|
+
return null/undefined.
|
|
51
|
+
|
|
52
|
+
E2 DUPLICATE ID (LAST-WINS). If the same entryId appears more than once in entries, only the
|
|
53
|
+
LAST occurrence counts; earlier occurrences with that entryId are superseded (they are
|
|
54
|
+
replays/corrections) and must NOT be added.
|
|
55
|
+
|
|
56
|
+
E3 UNICODE GROUPING. Accounts are grouped after Unicode NFC normalization. The composed form
|
|
57
|
+
"José" (ending U+00E9) and the decomposed form "Jose"+U+0301 (an 'e' followed by the
|
|
58
|
+
combining acute accent) denote the SAME account and their amounts combine.
|
|
59
|
+
|
|
60
|
+
E4 OVERFLOW. Per-account totals must be accumulated with arbitrary-precision integers
|
|
61
|
+
(BigInt), because a total may exceed Number.MAX_SAFE_INTEGER (9007199254740991). Totals
|
|
62
|
+
computed with 64-bit floating Number are non-conforming when they lose precision.
|
|
63
|
+
|
|
64
|
+
E5 BLANK ACCOUNT SKIP. An entry whose account is the empty string or consists solely of
|
|
65
|
+
whitespace is skipped entirely — it contributes to no account and creates no key.
|
|
66
|
+
|
|
67
|
+
E6 ZERO-AMOUNT BOUNDARY. An amount of exactly "0" is a valid entry. An account whose entries
|
|
68
|
+
net to 0 (including an account whose only entry is "0") still APPEARS in the result with
|
|
69
|
+
total "0"; it must not be dropped.
|
|
70
|
+
|
|
71
|
+
This is the entire required edge-case set.
|
|
72
|
+
- id: edge-vectors
|
|
73
|
+
type: table
|
|
74
|
+
label: authoritative edge-case input/output vectors
|
|
75
|
+
content: |
|
|
76
|
+
One authoritative vector per required edge, computed from tally-spec. A conforming
|
|
77
|
+
implementation reproduces every expected output exactly.
|
|
78
|
+
|
|
79
|
+
EV-E1 (empty):
|
|
80
|
+
input: []
|
|
81
|
+
expected: {}
|
|
82
|
+
|
|
83
|
+
EV-E2 (duplicate id, last-wins):
|
|
84
|
+
input: [ { entryId: "t1", account: "alice", amount: "100" },
|
|
85
|
+
{ entryId: "t1", account: "alice", amount: "250" } ]
|
|
86
|
+
expected: { "alice": "250" } # last occurrence of t1 wins; NOT "350"
|
|
87
|
+
|
|
88
|
+
EV-E3 (unicode NFC grouping):
|
|
89
|
+
input: [ { entryId: "u1", account: "Jos"+U+00E9, amount: "10" }, # composed "José"
|
|
90
|
+
{ entryId: "u2", account: "Jose"+U+0301, amount: "5" } ] # decomposed "José"
|
|
91
|
+
expected: { "José": "15" } # one account after NFC; total 10 + 5
|
|
92
|
+
|
|
93
|
+
EV-E4 (overflow):
|
|
94
|
+
input: [ { entryId: "o1", account: "vault", amount: "9007199254740993" }, # 2^53 + 1
|
|
95
|
+
{ entryId: "o2", account: "vault", amount: "2" } ]
|
|
96
|
+
expected: { "vault": "9007199254740995" }
|
|
97
|
+
note: 64-bit Number rounds "9007199254740993" to 9007199254740992, then +2 gives
|
|
98
|
+
9007199254740994 -> "9007199254740994" (WRONG). BigInt gives the exact
|
|
99
|
+
"9007199254740995".
|
|
100
|
+
|
|
101
|
+
EV-E5 (blank account skip):
|
|
102
|
+
input: [ { entryId: "b1", account: "", amount: "50" },
|
|
103
|
+
{ entryId: "b2", account: " ", amount: "70" },
|
|
104
|
+
{ entryId: "b3", account: "bob", amount: "5" } ]
|
|
105
|
+
expected: { "bob": "5" } # "" and " " skipped; no "" or " " key
|
|
106
|
+
|
|
107
|
+
EV-E6 (zero-amount boundary):
|
|
108
|
+
input: [ { entryId: "z1", account: "zed", amount: "0" } ]
|
|
109
|
+
expected: { "zed": "0" } # account still appears with total "0"
|
|
110
|
+
- id: candidates-a
|
|
111
|
+
type: code
|
|
112
|
+
label: submissions candidate-1, candidate-2, candidate-3
|
|
113
|
+
content: |
|
|
114
|
+
// ---- candidate-1 ----
|
|
115
|
+
function candidate1(entries: Entry[]): Record<string, string> {
|
|
116
|
+
const dedup = new Map<string, Entry>();
|
|
117
|
+
for (const e of entries) dedup.set(e.entryId, e); // last occurrence wins
|
|
118
|
+
const totals = new Map<string, bigint>();
|
|
119
|
+
for (const e of dedup.values()) {
|
|
120
|
+
if (e.account.trim() === '') continue; // skip blank accounts
|
|
121
|
+
const name = e.account.normalize('NFC'); // NFC grouping
|
|
122
|
+
totals.set(name, (totals.get(name) ?? 0n) + BigInt(e.amount));
|
|
123
|
+
}
|
|
124
|
+
const out: Record<string, string> = {};
|
|
125
|
+
for (const [name, sum] of totals) out[name] = sum.toString();
|
|
126
|
+
return out; // [] -> {}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---- candidate-2 ----
|
|
130
|
+
function candidate2(entries: Entry[]): Record<string, string> {
|
|
131
|
+
if (entries.length === 0) throw new Error('tally: no entries'); // throws on empty input
|
|
132
|
+
const dedup = new Map<string, Entry>();
|
|
133
|
+
for (const e of entries) dedup.set(e.entryId, e);
|
|
134
|
+
const totals = new Map<string, bigint>();
|
|
135
|
+
for (const e of dedup.values()) {
|
|
136
|
+
if (e.account.trim() === '') continue;
|
|
137
|
+
const name = e.account.normalize('NFC');
|
|
138
|
+
totals.set(name, (totals.get(name) ?? 0n) + BigInt(e.amount));
|
|
139
|
+
}
|
|
140
|
+
const out: Record<string, string> = {};
|
|
141
|
+
for (const [name, sum] of totals) out[name] = sum.toString();
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ---- candidate-3 ----
|
|
146
|
+
function candidate3(entries: Entry[]): Record<string, string> {
|
|
147
|
+
const totals = new Map<string, bigint>();
|
|
148
|
+
for (const e of entries) { // no dedup by entryId
|
|
149
|
+
if (e.account.trim() === '') continue;
|
|
150
|
+
const name = e.account.normalize('NFC');
|
|
151
|
+
totals.set(name, (totals.get(name) ?? 0n) + BigInt(e.amount));
|
|
152
|
+
}
|
|
153
|
+
const out: Record<string, string> = {};
|
|
154
|
+
for (const [name, sum] of totals) out[name] = sum.toString();
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
- id: candidates-b
|
|
158
|
+
type: code
|
|
159
|
+
label: submissions candidate-4, candidate-5, candidate-6
|
|
160
|
+
content: |
|
|
161
|
+
// ---- candidate-4 ----
|
|
162
|
+
function candidate4(entries: Entry[]): Record<string, string> {
|
|
163
|
+
const dedup = new Map<string, Entry>();
|
|
164
|
+
for (const e of entries) dedup.set(e.entryId, e);
|
|
165
|
+
const totals = new Map<string, bigint>();
|
|
166
|
+
for (const e of dedup.values()) {
|
|
167
|
+
if (e.account.trim() === '') continue;
|
|
168
|
+
const name = e.account; // no NFC normalization
|
|
169
|
+
totals.set(name, (totals.get(name) ?? 0n) + BigInt(e.amount));
|
|
170
|
+
}
|
|
171
|
+
const out: Record<string, string> = {};
|
|
172
|
+
for (const [name, sum] of totals) out[name] = sum.toString();
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ---- candidate-5 ----
|
|
177
|
+
function candidate5(entries: Entry[]): Record<string, string> {
|
|
178
|
+
const dedup = new Map<string, Entry>();
|
|
179
|
+
for (const e of entries) dedup.set(e.entryId, e);
|
|
180
|
+
const totals = new Map<string, number>(); // Number, not BigInt
|
|
181
|
+
for (const e of dedup.values()) {
|
|
182
|
+
if (e.account.trim() === '') continue;
|
|
183
|
+
const name = e.account.normalize('NFC');
|
|
184
|
+
totals.set(name, (totals.get(name) ?? 0) + Number(e.amount));
|
|
185
|
+
}
|
|
186
|
+
const out: Record<string, string> = {};
|
|
187
|
+
for (const [name, sum] of totals) out[name] = String(sum);
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ---- candidate-6 ----
|
|
192
|
+
function candidate6(entries: Entry[]): Record<string, string> {
|
|
193
|
+
const dedup = new Map<string, Entry>();
|
|
194
|
+
for (const e of entries) dedup.set(e.entryId, e);
|
|
195
|
+
const totals = new Map<string, bigint>();
|
|
196
|
+
for (const e of dedup.values()) {
|
|
197
|
+
const name = e.account.normalize('NFC'); // no blank-account skip
|
|
198
|
+
totals.set(name, (totals.get(name) ?? 0n) + BigInt(e.amount));
|
|
199
|
+
}
|
|
200
|
+
const out: Record<string, string> = {};
|
|
201
|
+
for (const [name, sum] of totals) out[name] = sum.toString();
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
- id: reviewer-thread
|
|
205
|
+
type: note
|
|
206
|
+
label: code-review discussion on the six submissions
|
|
207
|
+
content: |
|
|
208
|
+
Review thread for tally (PR #6033).
|
|
209
|
+
|
|
210
|
+
@nadia: "I'd approve candidate-4. NFC normalization is a display concern, not an accounting
|
|
211
|
+
one — the totals are still numerically correct."
|
|
212
|
+
|
|
213
|
+
@owen: "The acceptance bar is E1..E6 all handled. Feed each submission the six edge-vectors
|
|
214
|
+
and compare byte-for-byte. 'Numerically correct on ASCII inputs' isn't the bar."
|
|
215
|
+
|
|
216
|
+
QA-207 (untriaged): "One submission throws instead of returning {} on an empty list. Another
|
|
217
|
+
double-counts a replayed entryId. A third produces the wrong grand total on a very large
|
|
218
|
+
amount. These may be different submissions." Note: a zero-amount account MUST still appear in
|
|
219
|
+
the output per E6.
|
|
220
|
+
- id: submission-manifest
|
|
221
|
+
type: note
|
|
222
|
+
label: submission manifest and acceptance rule
|
|
223
|
+
content: |
|
|
224
|
+
Submissions under review for tally: candidate-1, candidate-2, candidate-3, candidate-4,
|
|
225
|
+
candidate-5, candidate-6. This is the COMPLETE set; no other implementation is being
|
|
226
|
+
considered.
|
|
227
|
+
|
|
228
|
+
Acceptance rule: exactly one submission handles ALL six required edge cases (E1..E6) and is to
|
|
229
|
+
be accepted. Each of the other five mishandles exactly one required edge. The process assumes
|
|
230
|
+
precisely one such all-edges-correct submission exists in this set.
|
|
231
|
+
tags: [generation, edge-case-coverage, unicode, bigint, code-review]
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
id: event-envelope-wire-compat
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: interface-compatibility
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: Which Event Producer Emits an Envelope the Frozen Signed-JSON Consumer Accepts
|
|
7
|
+
summary: A frozen consumer accepts a signed Event envelope whose signature covers a canonical key order. Five producers are proposed; decoys break compatibility subtly — renaming ts to timestamp, emitting traceId as null instead of omitting it, or signing over insertion order not canonical order. One conformer shuffles the WIRE key order yet signs correctly. Classify each conforms/violates, separating the order that matters (signed bytes) from the one that does not (wire keys).
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (consumer-contract,
|
|
10
|
+
producer-a, producer-b, producer-c, producer-d, producer-e, judging-notes). Cite the
|
|
11
|
+
artifact id(s) for every claim. Do not compute any HMAC — per `judging-notes`, compare
|
|
12
|
+
each producer's emitted fields and its SIGNED key order against the consumer's declared
|
|
13
|
+
requirements.
|
|
14
|
+
|
|
15
|
+
Verdict vocabulary: a producer CONFORMS if the envelope it emits is ACCEPTED by the
|
|
16
|
+
frozen consumer (all required fields present with the right names/types/nullability, and
|
|
17
|
+
the signature verifies because it was computed over the declared canonical key order);
|
|
18
|
+
it VIOLATES otherwise.
|
|
19
|
+
|
|
20
|
+
1. For EACH producer (producer-a … producer-e), give a verdict: conforms or violates
|
|
21
|
+
(accepted or rejected by the consumer).
|
|
22
|
+
|
|
23
|
+
2. For every producer you mark VIOLATES, name the exact incompatibility (field-name,
|
|
24
|
+
nullability, or signed-key-order) and cite the specific consumer-contract requirement
|
|
25
|
+
it breaks.
|
|
26
|
+
|
|
27
|
+
3. State the complete set of producers whose envelopes the consumer accepts.
|
|
28
|
+
|
|
29
|
+
4. producer-e emits its JSON keys in a different ORDER than the canonical key order.
|
|
30
|
+
Does that break compatibility? Justify from the consumer-contract's statement about
|
|
31
|
+
wire key order versus signed key order.
|
|
32
|
+
|
|
33
|
+
5. A reviewer rejects producer-e and accepts producer-d, reasoning "the bytes on the
|
|
34
|
+
wire should be in canonical order." Correct them: of producer-e and producer-d, which
|
|
35
|
+
one's signature actually verifies, and why?
|
|
36
|
+
artifacts:
|
|
37
|
+
- id: consumer-contract
|
|
38
|
+
type: spec
|
|
39
|
+
label: frozen consumer acceptance rules
|
|
40
|
+
content: |
|
|
41
|
+
The consumer is FROZEN. It accepts an Event envelope (a single JSON object) iff ALL
|
|
42
|
+
of the following hold. These rules are complete.
|
|
43
|
+
|
|
44
|
+
Required fields (must be present, with these EXACT names and types):
|
|
45
|
+
v number, and it MUST equal 3 (the protocol version)
|
|
46
|
+
id string
|
|
47
|
+
type string, non-empty
|
|
48
|
+
ts integer epoch milliseconds (the field name is exactly "ts")
|
|
49
|
+
data object, REQUIRED and non-null (may be an empty object {}, never null,
|
|
50
|
+
never omitted)
|
|
51
|
+
sig string (the signature, see below)
|
|
52
|
+
Optional field:
|
|
53
|
+
traceId MAY be present or omitted. If present it MUST be a string. It MUST NOT be
|
|
54
|
+
null. (Absent trace => OMIT the key entirely; do not send traceId: null.)
|
|
55
|
+
|
|
56
|
+
Signature check:
|
|
57
|
+
sig must be HMAC-SHA256 over the CANONICAL serialization of the envelope with `sig`
|
|
58
|
+
excluded. The canonical serialization lists keys in this FIXED order (ascending
|
|
59
|
+
lexicographic), joined as key=value with `|`:
|
|
60
|
+
data | id | traceId | ts | type | v
|
|
61
|
+
traceId is included in the canonical string ONLY when it is present. The consumer
|
|
62
|
+
reconstructs this canonical string itself and verifies the HMAC.
|
|
63
|
+
|
|
64
|
+
Wire order vs signed order (read carefully):
|
|
65
|
+
- The order in which keys physically appear in the TRANSMITTED JSON object is
|
|
66
|
+
IRRELEVANT to acceptance. The consumer parses the JSON into a map and rebuilds
|
|
67
|
+
the canonical string in the fixed order above before verifying. Any wire key
|
|
68
|
+
order is fine.
|
|
69
|
+
- What MUST match is the order used to compute the SIGNATURE. A producer that signs
|
|
70
|
+
over a different key order than the canonical `data|id|traceId?|ts|type|v` will
|
|
71
|
+
produce an HMAC that does not verify, and the envelope is rejected.
|
|
72
|
+
- id: producer-a
|
|
73
|
+
type: code
|
|
74
|
+
label: producer-a
|
|
75
|
+
content: |
|
|
76
|
+
// producer-a — hmac(KEY, canonicalString); J = deterministic JSON of an object.
|
|
77
|
+
signedString() {
|
|
78
|
+
return `data=${J(this.data)}|id=${this.id}|ts=${this.ts}|type=${this.type}|v=${this.v}`;
|
|
79
|
+
}
|
|
80
|
+
// emitted envelope (no trace on this event, so traceId is omitted):
|
|
81
|
+
// {"v":3,"id":"e-1","type":"order.created","ts":1699999999000,
|
|
82
|
+
// "data":{"amount":50},"sig":"<hmac over signedString()>"}
|
|
83
|
+
- id: producer-b
|
|
84
|
+
type: code
|
|
85
|
+
label: producer-b
|
|
86
|
+
content: |
|
|
87
|
+
// producer-b — signs over the canonical order, but renames a wire field.
|
|
88
|
+
signedString() {
|
|
89
|
+
return `data=${J(this.data)}|id=${this.id}|ts=${this.ts}|type=${this.type}|v=${this.v}`;
|
|
90
|
+
}
|
|
91
|
+
// emitted envelope:
|
|
92
|
+
// {"v":3,"id":"e-2","type":"order.created","timestamp":1699999999000,
|
|
93
|
+
// "data":{"amount":50},"sig":"<hmac over signedString()>"}
|
|
94
|
+
// (the epoch-ms field is emitted as "timestamp")
|
|
95
|
+
- id: producer-c
|
|
96
|
+
type: code
|
|
97
|
+
label: producer-c
|
|
98
|
+
content: |
|
|
99
|
+
// producer-c — no trace on this event; still emits a traceId key.
|
|
100
|
+
signedString() {
|
|
101
|
+
return `data=${J(this.data)}|id=${this.id}|ts=${this.ts}|type=${this.type}|v=${this.v}`;
|
|
102
|
+
}
|
|
103
|
+
// emitted envelope:
|
|
104
|
+
// {"v":3,"id":"e-3","type":"order.created","ts":1699999999000,"traceId":null,
|
|
105
|
+
// "data":{"amount":50},"sig":"<hmac over signedString()>"}
|
|
106
|
+
- id: producer-d
|
|
107
|
+
type: code
|
|
108
|
+
label: producer-d
|
|
109
|
+
content: |
|
|
110
|
+
// producer-d — signs over the producer's own field-insertion order.
|
|
111
|
+
signedString() {
|
|
112
|
+
return `v=${this.v}|id=${this.id}|type=${this.type}|ts=${this.ts}|data=${J(this.data)}`;
|
|
113
|
+
}
|
|
114
|
+
// emitted envelope:
|
|
115
|
+
// {"v":3,"id":"e-4","type":"order.created","ts":1699999999000,
|
|
116
|
+
// "data":{"amount":50},"sig":"<hmac over signedString()>"}
|
|
117
|
+
- id: producer-e
|
|
118
|
+
type: code
|
|
119
|
+
label: producer-e
|
|
120
|
+
content: |
|
|
121
|
+
// producer-e — signs over the canonical order; emits keys in a different wire order.
|
|
122
|
+
signedString() {
|
|
123
|
+
return `data=${J(this.data)}|id=${this.id}|ts=${this.ts}|type=${this.type}|v=${this.v}`;
|
|
124
|
+
}
|
|
125
|
+
// emitted envelope (note the physical key order differs from canonical):
|
|
126
|
+
// {"sig":"<hmac over signedString()>","type":"order.created","v":3,
|
|
127
|
+
// "data":{"amount":50},"id":"e-5","ts":1699999999000}
|
|
128
|
+
- id: judging-notes
|
|
129
|
+
type: note
|
|
130
|
+
label: how to judge (no HMAC computation needed; scope)
|
|
131
|
+
content: |
|
|
132
|
+
Scope: producer-a … producer-e are the COMPLETE set of proposals. Judge each against
|
|
133
|
+
the frozen consumer-contract only.
|
|
134
|
+
|
|
135
|
+
You do NOT need to compute any HMAC. Two checks decide each producer:
|
|
136
|
+
1. FIELDS ON THE WIRE: does the emitted envelope carry every required field under
|
|
137
|
+
its exact name (v, id, type, ts, data, sig), with data non-null present, v = 3,
|
|
138
|
+
and no traceId: null? A renamed field (e.g. timestamp for ts) means the required
|
|
139
|
+
field is absent. A traceId: null violates the optional-field nullability rule.
|
|
140
|
+
2. SIGNED KEY ORDER: read each producer's signedString(). If its key order equals
|
|
141
|
+
the canonical order data | id | (traceId) | ts | type | v, the signature will
|
|
142
|
+
verify; if the signedString() uses any other key order, the consumer's
|
|
143
|
+
recomputed canonical string differs, so the HMAC will not verify and the
|
|
144
|
+
envelope is rejected — even if all wire fields are correct.
|
|
145
|
+
|
|
146
|
+
Remember the contract's split: the PHYSICAL order of keys in the emitted JSON is
|
|
147
|
+
irrelevant (the consumer re-canonicalizes), but the order fed to signedString() is
|
|
148
|
+
what determines whether the signature verifies. Judge accordingly.
|
|
149
|
+
tags: [wire-protocol, serialization, hmac, canonical-json, interface-compatibility, generation]
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
id: kadane-linear-constant-space
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
category: generation
|
|
4
|
+
cluster: constraint-satisfaction
|
|
5
|
+
difficulty: expert
|
|
6
|
+
title: Which maxSubarray Candidate Meets the O(n) Time, O(1) Space, and Purity Constraints
|
|
7
|
+
summary: A spec requires maxSubarray(nums) to compute the maximum contiguous-subarray sum under four declared NON-functional constraints — single linear O(n) scan, O(1) auxiliary space, purity/no-input-mutation, and the correctness contract. All five candidates compute the correct maximum on the vector, so the only axis is the constraints. One decoy allocates an O(n) prefix array, one uses a nested O(n^2) loop, one mutates the input. Classify each conforms/violates and cite the exact violating construct.
|
|
8
|
+
prompt: |
|
|
9
|
+
Answer each deliverable using ONLY the supplied artifacts (spec, correctness-vector,
|
|
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's structure using the definitions in `reading-guide`.
|
|
13
|
+
|
|
14
|
+
All five candidates return the CORRECT maximum on every correctness-vector row (verify
|
|
15
|
+
by reading if you wish); the ONLY axis that separates them is the four declared
|
|
16
|
+
constraints C1–C4 in `spec`. Verdict vocabulary: a candidate CONFORMS if it satisfies
|
|
17
|
+
ALL FOUR constraints; it VIOLATES if it breaks any one of them.
|
|
18
|
+
|
|
19
|
+
1. For EACH candidate (candidate-a … candidate-e), give a verdict: conforms or
|
|
20
|
+
violates. For every violator, name the exact constraint number (C1, C2, or C3) it
|
|
21
|
+
breaks and quote the exact construct responsible.
|
|
22
|
+
|
|
23
|
+
2. State the complete set of conforming candidates. candidate-e uses a different loop
|
|
24
|
+
shape than candidate-a — confirm it still satisfies every constraint.
|
|
25
|
+
|
|
26
|
+
3. candidate-b returns the right answer. Quote the construct that makes its auxiliary
|
|
27
|
+
space O(n) rather than O(1), and explain why it fails C2 even though it is a single
|
|
28
|
+
pass.
|
|
29
|
+
|
|
30
|
+
4. candidate-d returns the right answer. Name the single constraint it breaks and
|
|
31
|
+
state the exact caller-visible consequence of running it.
|
|
32
|
+
|
|
33
|
+
5. A reviewer approves candidate-c, arguing "it's fine, it only uses two variables."
|
|
34
|
+
Rebut this using C1 and the exact structure of candidate-c.
|
|
35
|
+
artifacts:
|
|
36
|
+
- id: spec
|
|
37
|
+
type: spec
|
|
38
|
+
label: maxSubarray specification (function + non-functional constraints)
|
|
39
|
+
content: |
|
|
40
|
+
FUNCTION maxSubarray(nums)
|
|
41
|
+
|
|
42
|
+
Purpose: return the largest sum obtainable from a NON-EMPTY contiguous subarray of
|
|
43
|
+
`nums`. `nums` is a non-empty array of numbers that may include negatives; when all
|
|
44
|
+
values are negative the answer is the greatest single element.
|
|
45
|
+
|
|
46
|
+
This function ships on a hot path. It MUST satisfy ALL of the following declared
|
|
47
|
+
constraints. Each is a hard requirement, not a preference:
|
|
48
|
+
|
|
49
|
+
C1 TIME: a single linear scan of `nums`, i.e. O(n) in nums.length. Exactly one
|
|
50
|
+
pass over the array. No nested iteration over `nums`, and no sort.
|
|
51
|
+
C2 SPACE: O(1) auxiliary space — a constant number of scalar variables. The
|
|
52
|
+
function MUST NOT allocate any array, Set, Map, or object whose size grows
|
|
53
|
+
with nums.length.
|
|
54
|
+
C3 PURITY: pure and deterministic. It reads only `nums` and returns a number. It
|
|
55
|
+
MUST NOT mutate `nums` (no assignment into nums[i]), MUST NOT use Math.random,
|
|
56
|
+
Date.now, or any I/O, and MUST return the same result for the same input on
|
|
57
|
+
every call.
|
|
58
|
+
C4 CORRECTNESS: returns the maximum non-empty contiguous-subarray sum for the
|
|
59
|
+
declared input domain (see correctness-vector).
|
|
60
|
+
|
|
61
|
+
A candidate CONFORMS iff it satisfies C1 AND C2 AND C3 AND C4. Breaking any single
|
|
62
|
+
constraint means it VIOLATES.
|
|
63
|
+
- id: correctness-vector
|
|
64
|
+
type: table
|
|
65
|
+
label: correctness vector (all candidates return these)
|
|
66
|
+
content: |
|
|
67
|
+
These rows fix the correct output (constraint C4). Every one of the five candidates
|
|
68
|
+
returns the value in the `max` column for the matching `nums`; you can confirm by
|
|
69
|
+
tracing, but the point of this task is the C1–C3 constraints, not C4.
|
|
70
|
+
|
|
71
|
+
nums max why
|
|
72
|
+
[-2,1,-3,4,-1,2,1,-5,4] 6 subarray [4,-1,2,1] sums to 6
|
|
73
|
+
[-3,-1,-2] -1 all negative -> greatest single element
|
|
74
|
+
[5] 5 single element
|
|
75
|
+
[1,2,3] 6 the whole array
|
|
76
|
+
- id: candidate-a
|
|
77
|
+
type: code
|
|
78
|
+
label: candidate-a
|
|
79
|
+
content: |
|
|
80
|
+
// candidate-a
|
|
81
|
+
function maxSubarray(nums) {
|
|
82
|
+
let best = nums[0];
|
|
83
|
+
let cur = nums[0];
|
|
84
|
+
for (let i = 1; i < nums.length; i++) {
|
|
85
|
+
cur = Math.max(nums[i], cur + nums[i]);
|
|
86
|
+
best = Math.max(best, cur);
|
|
87
|
+
}
|
|
88
|
+
return best;
|
|
89
|
+
}
|
|
90
|
+
- id: candidate-b
|
|
91
|
+
type: code
|
|
92
|
+
label: candidate-b
|
|
93
|
+
content: |
|
|
94
|
+
// candidate-b
|
|
95
|
+
function maxSubarray(nums) {
|
|
96
|
+
const pre = [0];
|
|
97
|
+
let minPre = 0, best = -Infinity;
|
|
98
|
+
for (let i = 0; i < nums.length; i++) {
|
|
99
|
+
pre.push(pre[i] + nums[i]);
|
|
100
|
+
best = Math.max(best, pre[i + 1] - minPre);
|
|
101
|
+
minPre = Math.min(minPre, pre[i + 1]);
|
|
102
|
+
}
|
|
103
|
+
return best;
|
|
104
|
+
}
|
|
105
|
+
- id: candidate-c
|
|
106
|
+
type: code
|
|
107
|
+
label: candidate-c
|
|
108
|
+
content: |
|
|
109
|
+
// candidate-c
|
|
110
|
+
function maxSubarray(nums) {
|
|
111
|
+
let best = -Infinity;
|
|
112
|
+
for (let i = 0; i < nums.length; i++) {
|
|
113
|
+
let sum = 0;
|
|
114
|
+
for (let j = i; j < nums.length; j++) {
|
|
115
|
+
sum += nums[j];
|
|
116
|
+
if (sum > best) best = sum;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return best;
|
|
120
|
+
}
|
|
121
|
+
- id: candidate-d
|
|
122
|
+
type: code
|
|
123
|
+
label: candidate-d
|
|
124
|
+
content: |
|
|
125
|
+
// candidate-d
|
|
126
|
+
function maxSubarray(nums) {
|
|
127
|
+
let best = nums[0];
|
|
128
|
+
for (let i = 1; i < nums.length; i++) {
|
|
129
|
+
nums[i] = Math.max(nums[i], nums[i] + nums[i - 1]);
|
|
130
|
+
if (nums[i] > best) best = nums[i];
|
|
131
|
+
}
|
|
132
|
+
return best;
|
|
133
|
+
}
|
|
134
|
+
- id: candidate-e
|
|
135
|
+
type: code
|
|
136
|
+
label: candidate-e
|
|
137
|
+
content: |
|
|
138
|
+
// candidate-e
|
|
139
|
+
function maxSubarray(nums) {
|
|
140
|
+
let best = -Infinity;
|
|
141
|
+
let run = 0;
|
|
142
|
+
for (let i = 0; i < nums.length; i++) {
|
|
143
|
+
run = run + nums[i];
|
|
144
|
+
if (run > best) best = run;
|
|
145
|
+
if (run < 0) run = 0;
|
|
146
|
+
}
|
|
147
|
+
return best;
|
|
148
|
+
}
|
|
149
|
+
- id: reading-guide
|
|
150
|
+
type: note
|
|
151
|
+
label: how to read the constraints (definitions + scope)
|
|
152
|
+
content: |
|
|
153
|
+
Scope: candidate-a … candidate-e are the COMPLETE set of submissions. Every one of
|
|
154
|
+
them returns the correct maximum on every correctness-vector row, so C4 holds for
|
|
155
|
+
all five. Judge them ONLY on whether they also satisfy C1, C2, and C3.
|
|
156
|
+
|
|
157
|
+
How to read each constraint from the code (no execution needed):
|
|
158
|
+
C1 (O(n), single scan): a single `for` loop over `nums` doing O(1) work per
|
|
159
|
+
element is O(n) and satisfies C1. A loop NESTED inside another loop, where
|
|
160
|
+
each ranges up to nums.length, performs about n*n steps — that is O(n^2) and
|
|
161
|
+
does NOT satisfy the single linear-scan requirement. A call to .sort() is also
|
|
162
|
+
not O(n).
|
|
163
|
+
C2 (O(1) auxiliary space): a fixed number of scalar variables (numbers) is O(1).
|
|
164
|
+
An array/Set/Map/object that receives one entry PER element (e.g. via .push in
|
|
165
|
+
the loop) grows to size proportional to nums.length — that is O(n) auxiliary
|
|
166
|
+
space and does NOT satisfy C2. Reusing the input array as storage does not
|
|
167
|
+
count as new allocation (that is a C3 concern, not C2).
|
|
168
|
+
C3 (purity / no mutation): the function must read `nums` and return a number
|
|
169
|
+
without writing back into it. An assignment of the form `nums[i] = ...` mutates
|
|
170
|
+
the caller's array and breaks C3, regardless of whether the returned number is
|
|
171
|
+
correct. Use of Math.random, Date.now, or I/O also breaks C3.
|
|
172
|
+
|
|
173
|
+
A candidate that produces the correct number still VIOLATES if it breaks C1, C2, or
|
|
174
|
+
C3. Cite the exact line/construct when you assign a violation.
|
|
175
|
+
tags: [algorithm, complexity, purity, constraint-satisfaction, generation]
|