fix : ai slop

This commit is contained in:
2026-09-01 20:54:54 +07:00 Unverified
parent 10e3bf987f
commit e3345e1d66
12 changed files with 27 additions and 27 deletions
+11 -11
View File
@@ -17,17 +17,17 @@ Stand outside the change and ask whether it should exist at all, then verify it
Run these in order. Do not skip ahead.
### 1. Intent — what is this actually trying to do?
### 1. Intent - what is this actually trying to do?
- State the goal in one sentence, in your own words. If you cannot, the artifact is underspecified — say so and stop.
- State the goal in one sentence, in your own words. If you cannot, the artifact is underspecified - say so and stop.
- Ask: **is there a simpler, smaller, or more elegant way to achieve the same goal?** Consider:
- Doing nothing (is the problem real / load-bearing?).
- Using something that already exists in the codebase instead of adding new surface.
- A smaller change that solves 90% of the goal with 10% of the risk.
- Solving it at a different layer (config vs code, framework vs app, build vs runtime).
- If a better alternative exists, name it explicitly with rationale. This is the most valuable thing you can output — surface it before the line-by-line review.
- If a better alternative exists, name it explicitly with rationale. This is the most valuable thing you can output - surface it before the line-by-line review.
### 2. Trace — walk the actual code path
### 2. Trace - walk the actual code path
- For each behavior the change claims, trace the path end-to-end through the real code, not just the lines in the diff:
- Entry point → call sites → branches taken → state mutated → exit / return / side effect.
@@ -35,7 +35,7 @@ Run these in order. Do not skip ahead.
- For a plan or design doc: trace the proposed flow against the existing system. Where does it touch reality? What does it assume that isn't true?
- Note every place the trace surprises you (unexpected branch, dead code reached, state you didn't know existed). Surprises are signal.
### 3. Verify — does it actually do what it claims?
### 3. Verify - does it actually do what it claims?
For each claim the change/plan makes, answer:
@@ -48,18 +48,18 @@ For each claim the change/plan makes, answer:
Output one tight section per finding. Order by severity (blocker → major → nit). For each:
- **Finding** — one sentence, specific. Cite `file:line` when applicable.
- **Why it matters** — the consequence, not the principle.
- **Evidence** — the trace step or input that exposes it.
- **Suggested change** — concrete, minimal.
- **Finding** - one sentence, specific. Cite `file:line` when applicable.
- **Why it matters** - the consequence, not the principle.
- **Evidence** - the trace step or input that exposes it.
- **Suggested change** - concrete, minimal.
Close with a one-line verdict: ship / fix-then-ship / rework / reject — with the single biggest reason.
Close with a one-line verdict: ship / fix-then-ship / rework / reject - with the single biggest reason.
## Operating rules
- **No rubber-stamps.** "LGTM" is not an output. If you genuinely find nothing, say what you traced and what you checked, so the user can judge whether your review covered the surface they cared about.
- **Cite or it didn't happen.** Every claim about the code references a specific path, file, or line. No vague "this might break under load."
- **Distinguish claim from verification.** "The PR says X" and "I traced X and confirmed / refuted it" are different — keep them separate in the output.
- **Distinguish claim from verification.** "The PR says X" and "I traced X and confirmed / refuted it" are different - keep them separate in the output.
- **One simpler-alternative pass is mandatory.** Even on small changes, spend one breath asking if the whole thing is necessary. Skip only if the user explicitly says "don't question scope."
- **Don't pad with style nits when there's a structural problem.** If step 1 or step 2 surfaces a real issue, lead with it; defer nits or drop them.
- **No flattery, no hedging.** "This is a great PR but..." adds nothing. State the finding.
+2 -2
View File
@@ -2,8 +2,8 @@
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This version has breaking changes - APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
This block is written and re-added by `next dev` - verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
<!-- END:nextjs-agent-rules -->
+1 -1
View File
@@ -11,7 +11,7 @@ export async function generateMetadata({ params }: { params: Params }): Promise<
await connection();
const { character, page } = await params;
const guide = await getCachedPublicGuide(character);
return guide ? { title: `${page} — ${guide.name} — คู่มือ`, description: guide.overview } : { title: "ไม่พบไกด์" };
return guide ? { title: `${page} - ${guide.name} - คู่มือ`, description: guide.overview } : { title: "ไม่พบไกด์" };
}
export default async function GuideSectionPage({ params }: { params: Params }) {
+1 -1
View File
@@ -15,7 +15,7 @@ export async function generateMetadata({
await connection();
const guide = await getCachedPublicGuide((await params).character);
return guide
? { title: `${guide.name} — คู่มือ`, description: guide.overview }
? { title: `${guide.name} - คู่มือ`, description: guide.overview }
: { title: "ไม่พบไกด์" };
}
@@ -227,7 +227,7 @@ export async function GET(
<div style={{ display: "flex", fontSize: 17, fontWeight: 700 }}>{stat.label}</div>
<div style={{ display: "flex", width: "100%", borderTop: "1px solid #34343d" }} />
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4, fontSize: 14, lineHeight: 1.45 }}>
{stat.values.length ? stat.values.map((value, index) => <span key={`${value}-${index}`} style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 5, color: statPriorityColor(index), whiteSpace: "normal", wordBreak: "break-word" }}>{recommendedStatAsset(value) ? <img src={recommendedStatAsset(value)!} alt="" width={18} height={18} style={{ objectFit: "contain" }} /> : null}{statLabel(value)}</span>) : "—"}
{stat.values.length ? stat.values.map((value, index) => <span key={`${value}-${index}`} style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 5, color: statPriorityColor(index), whiteSpace: "normal", wordBreak: "break-word" }}>{recommendedStatAsset(value) ? <img src={recommendedStatAsset(value)!} alt="" width={18} height={18} style={{ objectFit: "contain" }} /> : null}{statLabel(value)}</span>) : "-"}
</div>
</div>
))}
+1 -1
View File
@@ -4,7 +4,7 @@ import {
ogImageSize,
} from "@/lib/og-image";
export const alt = "Buzz Guide — คู่มือเกนชินสาธารณะที่เตรียมไว้ให้คุณ";
export const alt = "Buzz Guide - คู่มือเกนชินสาธารณะที่เตรียมไว้ให้คุณ";
export const size = ogImageSize;
export const contentType = ogImageContentType;
+2 -2
View File
@@ -272,7 +272,7 @@ function DataSourceEditor({
<datalist id={`fields-${source.id}`}>
{source.fields.filter((candidate) => candidate.key !== field.key).map((candidate) => <option key={candidate.key} value={candidate.key}>{candidate.label}</option>)}
</datalist>
{cell?.error ? <FieldError>สูตรนี้ยังคำนวณไม่ได้: ตรวจสอบชื่อฟิลด์และตัวหาร</FieldError> : <FieldDescription>ตัวอย่างผลลัพธ์: <span className="font-mono text-foreground">{cell?.display ?? "—"}</span></FieldDescription>}
{cell?.error ? <FieldError>สูตรนี้ยังคำนวณไม่ได้: ตรวจสอบชื่อฟิลด์และตัวหาร</FieldError> : <FieldDescription>ตัวอย่างผลลัพธ์: <span className="font-mono text-foreground">{cell?.display ?? "-"}</span></FieldDescription>}
</Field>
);
})}
@@ -280,7 +280,7 @@ function DataSourceEditor({
<div className="overflow-hidden rounded-lg border">
<Table>
<TableHeader><TableRow>{source.fields.slice(0, 3).map((field) => <TableHead key={field.key}>{field.label}</TableHead>)}<TableHead className="w-12" /></TableRow></TableHeader>
<TableBody>{source.rows.slice(0, 10).map((row) => <TableRow key={row.id}>{source.fields.slice(0, 3).map((field) => <TableCell key={field.key} className="max-w-28 truncate">{row.values[field.key] ?? previewRow?.cells[field.key]?.display ?? "—"}</TableCell>)}<TableCell><Button size="xs" variant="ghost" onClick={() => setRowId(row.id)}>แก้ไข</Button></TableCell></TableRow>)}</TableBody>
<TableBody>{source.rows.slice(0, 10).map((row) => <TableRow key={row.id}>{source.fields.slice(0, 3).map((field) => <TableCell key={field.key} className="max-w-28 truncate">{row.values[field.key] ?? previewRow?.cells[field.key]?.display ?? "-"}</TableCell>)}<TableCell><Button size="xs" variant="ghost" onClick={() => setRowId(row.id)}>แก้ไข</Button></TableCell></TableRow>)}</TableBody>
</Table>
</div>
<Button
+2 -2
View File
@@ -84,7 +84,7 @@ function displayCell(
field: string,
): string {
const cell = evaluated.rows.find((row) => row.id === rowId)?.cells[field];
return cell && !cell.error && cell.display != null ? cell.display : "—";
return cell && !cell.error && cell.display != null ? cell.display : "-";
}
export function collectGuideSections(
@@ -538,7 +538,7 @@ function RankingBlock({
#{index + 1}
</span>
<div className="min-w-0">
{detail && detail !== "—" ? (
{detail && detail !== "-" ? (
<TermDetail label={label} detail={detail} />
) : (
<span className="font-medium">{label}</span>
+2 -2
View File
@@ -437,7 +437,7 @@ function ArtifactSection({ guide }: { guide: PublicGuide }) {
<div className="relative size-14 overflow-hidden rounded-xl border bg-muted sm:size-20">
{catalogTalent?.iconUrl ? <Image src={catalogTalent.iconUrl} alt={talentName} fill className="object-contain" /> : <span className="grid size-full place-items-center font-semibold">{talent.type}</span>}
</div>
<Badge variant="secondary">{talent.level ? `เลเวล ${talent.level}+` : "—"}</Badge>
<Badge variant="secondary">{talent.level ? `เลเวล ${talent.level}+` : "-"}</Badge>
<p className="text-xs font-medium sm:text-sm">{talentName}</p>
<p className="text-[11px] text-muted-foreground sm:text-xs">{talentTypeLabel(talent.type)}</p>
</div>
@@ -506,7 +506,7 @@ function ArtifactStat({ iconSrc, label, values }: { iconSrc: string; label: stri
? values.map((value, index) => (
<ArtifactStatValue key={`${value}-${index}`} value={value} index={index} />
))
: <span>—</span>}
: <span>-</span>}
</div>
</div>
);
+1 -1
View File
@@ -134,7 +134,7 @@ function snapshot(pageSlug: string): PageSnapshot | null {
sortOrder: 0,
config: {
eyebrow: "คู่มือตัวละคร",
title: "แอสตรา — ผู้กำหนดจังหวะสนามรบ",
title: "แอสตรา - ผู้กำหนดจังหวะสนามรบ",
subtitle: "ตัวสนับสนุนที่เพิ่มพลังให้ทีมผ่านการจัดลำดับสกิล",
summary:
"ตัวอย่างนี้แสดงว่าคู่มือสามารถอ่านง่ายบนมือถือและยังรองรับข้อมูลคำนวณที่ตรวจสอบได้",
+1 -1
View File
@@ -89,7 +89,7 @@ export function createEditorBlock(
callout: { title: "ข้อควรรู้", body: "เพิ่มรายละเอียด", tone: "info" },
"stat-cards": {
title: "ค่าสำคัญ",
items: [{ id: nestedId(), label: "ค่า", value: "—" }],
items: [{ id: nestedId(), label: "ค่า", value: "-" }],
},
"key-value": {
items: [{ id: nestedId(), label: "หัวข้อ", value: "รายละเอียด" }],
+2 -2
View File
@@ -160,8 +160,8 @@ export const builtInTemplates: readonly TemplateBlueprint[] = [
config: {
title: "เป้าหมายค่าสถานะ",
items: [
{ id: "@id:stat-1", label: "ค่าสำคัญ", value: "—" },
{ id: "@id:stat-2", label: "ค่ารอง", value: "—" },
{ id: "@id:stat-1", label: "ค่าสำคัญ", value: "-" },
{ id: "@id:stat-2", label: "ค่ารอง", value: "-" },
],
},
},