Erik Lindqvist
@erik_lindqvist • 3 weeks ago
Score two AI coding agents' solutions to the same task on a weighted rubric, pick one with reasons, and list what to cherry-pick from the loser.
taskattempt_aattempt_bpriorities{{task}}{{attempt_a}}{{attempt_b}}{{priorities}}task: Add a slugify(title) util for blog post URLs: lowercase, ASCII only, words joined by hyphens, max 60 characters, no leading or trailing hyphen.
priorities: Correctness first. We avoid new dependencies for small utilities unless there's a clear reason.
attempt_a:
```ts
export function slugify(title: string): string {
return title
.toLowerCase()
.normalize("NFKD")
.replace(/[̀-ͯ]/g, "")
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, 60)
}
// tests: "Hello World" -> "hello-world"; "Café crème" -> "cafe-creme"
```
attempt_b:
```ts
import slugifyLib from "slugify" // new dependency added to package.json
export function slugify(title: string): string {
const s = slugifyLib(title, { lower: true, strict: true })
return s.length > 60 ? s.slice(0, 60).replace(/-+$/, "") : s
}
// tests: basic words; accents; punctuation stripped; exactly 60 chars; 61 chars cut at a hyphen with no trailing hyphen
```.slice(0, 60), so a title whose 60th character is a hyphen ends in -. For example, 59 letters followed by " post" gives 59 letters and a trailing hyphen."Straße" becomes "stra-e", because NFKD doesn't decompose ß, so the character is replaced with a hyphen. That's ugly but technically meets the spec.ß to ss."". The task doesn't define this case, and neither attempt handles it.Inslugify, move.slice(0, 60)before the leading/trailing hyphen trim so truncation can't leave a trailing hyphen. Add tests for: exactly 60 characters; 61 characters where the cut lands on a hyphen;"Straße"(document the current"stra-e"result); a title with no Latin characters (returns"", add a comment saying callers must handle it). Don't add dependencies. Paste the test output.