check-anatomy: a creature's shape comes from bodyPlan, never species
Three tools read spec.species to decide a creature's SHAPE and all three were wrong the same way, because every creature with a non-human body carries species "baseline" and says what it is in bodyPlan: mj-queue drew a wingless gryphon make-portraits drew a human silhouette for 48 creatures bestiary published "26 of them are not human-shaped" when it is 74 Each was found by looking at the neighbour of the one before, which is not a method — the fourth would have been found by a fourth accident. A line that feeds a shape function from species without naming a resolved plan is the whole defect, in one line, every time, so it is checkable. Proved against the real thing rather than a planted one: checking out each file's parent commit from history makes the guard report that file, at the line the fix touched, and the current tree is clean. The first version required the literal `bodyPlan` on the line and so reported all three FIXED call sites, because the correct form resolves a local `plan` once and then falls back to species on the next line — and that fallback is right. A guard that calls the corrected code broken is exactly what check-rules was reported for earlier tonight, one file over. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9cdb6a23b3
commit
98ca282b89
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { readFile, readdir } from "node:fs/promises";
|
||||
import { join, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { LOCATION_TABLES, BODY_ART } from "../anatomy.mjs";
|
||||
@@ -314,6 +315,48 @@ for (const [id, table] of Object.entries(LOCATION_TABLES)) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- the shape comes from bodyPlan, never from species ----
|
||||
*
|
||||
* Three tools read `spec.species` to decide a creature's SHAPE, and all three were wrong
|
||||
* in the same way, because every creature with a non-human body carries
|
||||
* `species: "baseline"` and says what it is in `bodyPlan`:
|
||||
*
|
||||
* mj-queue.mjs drew a wingless gryphon
|
||||
* make-portraits.mjs drew a human silhouette for 48 creatures
|
||||
* bestiary.mjs published "26 of them are not human-shaped" when it is 74
|
||||
*
|
||||
* Each was found by looking at the neighbour of the one before. R-264 settled the rule
|
||||
* for the harness — `spec.bodyPlan ?? spec.species` — and build-packs writes that to the
|
||||
* actor's speciesProfile. This stops a fourth: a line that feeds a shape function from
|
||||
* `species` without naming `bodyPlan` is the whole defect, in one line, every time.
|
||||
*/
|
||||
{
|
||||
const SHAPE = /\b(?:locationsFor|groundedPlanFor|locationFor)\s*\(|(?:LOCATION_TABLES|BODY_ART)\s*\[/;
|
||||
const files = (await readdir(new URL("../tools/", import.meta.url)))
|
||||
.filter(f => f.endsWith(".mjs") && !f.startsWith("check-"))
|
||||
.map(f => `tools/${f}`)
|
||||
.concat(["ringbrp.mjs", "rules.mjs", "forge.mjs", "postings.mjs"]);
|
||||
for (const rel of files) {
|
||||
let src;
|
||||
try { src = await readFile(new URL(`../${rel}`, import.meta.url), "utf8"); } catch { continue; }
|
||||
src.split("\n").forEach((line, i) => {
|
||||
if (/^\s*(?:\/\/|\*|\/\*)/.test(line)) return; // prose is not code
|
||||
if (!SHAPE.test(line)) return;
|
||||
if (!/\bspecies\b/.test(line)) return; // not fed from species at all
|
||||
/* `plan` as well as `bodyPlan`: the correct form is two lines — a local `plan`
|
||||
resolved once, then `TABLE[plan] ?? TABLE[species] ?? TABLE.baseline` — and the
|
||||
species fallback on that second line is right, not a defect. Requiring the
|
||||
literal `bodyPlan` on the line reported all three FIXED call sites. A guard that
|
||||
calls the corrected code broken is the failure check-rules was reported for
|
||||
earlier tonight, one file over. */
|
||||
if (/\b(?:bodyPlan|plan)\b/.test(line)) return;
|
||||
problems.push(`${rel}:${i + 1} feeds a shape function from species — `
|
||||
+ `a creature's body is in bodyPlan, and every non-human one has species "baseline". `
|
||||
+ `Use \`spec.bodyPlan ?? spec.species\`, as R-264 settled for the harness.`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (problems.length) {
|
||||
console.error("check-anatomy: FAILED");
|
||||
for (const p of [...new Set(problems)]) console.error(" " + p);
|
||||
|
||||
Reference in New Issue
Block a user