Add concept world catalog and review workflow

AI-assisted: prepared by Codex at Paul's request.
This commit is contained in:
Paul Bakaus
2026-07-18 14:12:05 -07:00
parent 77c7d8e0fc
commit 2b1f36c43e
576 changed files with 45547 additions and 30979 deletions
+159
View File
@@ -0,0 +1,159 @@
import crypto from 'node:crypto';
import { readFileSync } from 'node:fs';
export const CONCEPT_STATUSES = new Set(['approved', 'rejected']);
export function normalizeConceptForm(value) {
return String(value || '')
.normalize('NFKD')
.toLowerCase()
.replace(/[’‘]/g, "'")
.replace(/[^a-z0-9]+/g, ' ')
.trim();
}
export function readConceptCatalog(catalogPath, reviewsPath) {
const catalog = JSON.parse(readFileSync(catalogPath, 'utf8'));
const reviewData = JSON.parse(readFileSync(reviewsPath, 'utf8'));
const reviews = reviewData.reviews || {};
const concepts = [];
for (const family of catalog.families || []) {
for (const concept of family.concepts || []) {
concepts.push({
...concept,
familyId: family.id,
familyLabel: family.label,
status: reviews[concept.id]?.status || 'pending',
review: reviews[concept.id] || null,
});
}
}
return { catalog, reviewData, reviews, concepts };
}
export function validateConceptCatalog(catalog, reviewData, { expectedTotal, minimumTotal } = {}) {
const errors = [];
const warnings = [];
const familyIds = new Set();
const conceptIds = new Set();
const normalizedForms = new Map();
const concepts = [];
if (!Number.isInteger(catalog?.schemaVersion) || catalog.schemaVersion < 1) {
errors.push('catalog.schemaVersion must be a positive integer');
}
if (typeof catalog?.catalogVersion !== 'string' || !catalog.catalogVersion.trim()) {
errors.push('catalog.catalogVersion must be a non-empty string');
}
if (!Array.isArray(catalog?.families) || catalog.families.length < 3) {
errors.push('catalog.families must contain at least three families');
}
for (const family of catalog?.families || []) {
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(family.id || '')) {
errors.push(`invalid family id: ${String(family.id)}`);
} else if (familyIds.has(family.id)) {
errors.push(`duplicate family id: ${family.id}`);
}
familyIds.add(family.id);
if (typeof family.label !== 'string' || !family.label.trim()) {
errors.push(`family ${family.id || '(unknown)'} needs a label`);
}
if (!Array.isArray(family.concepts) || family.concepts.length === 0) {
errors.push(`family ${family.id || '(unknown)'} has no concepts`);
continue;
}
for (const concept of family.concepts) {
concepts.push(concept);
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(concept.id || '')) {
errors.push(`invalid concept id: ${String(concept.id)}`);
} else if (conceptIds.has(concept.id)) {
errors.push(`duplicate concept id: ${concept.id}`);
}
conceptIds.add(concept.id);
const normalized = normalizeConceptForm(concept.form);
if (!normalized) {
errors.push(`concept ${concept.id || '(unknown)'} needs a form`);
} else if (normalizedForms.has(normalized)) {
errors.push(`duplicate concept form: ${concept.id} and ${normalizedForms.get(normalized)}`);
}
normalizedForms.set(normalized, concept.id);
if (typeof concept.form !== 'string' || !concept.form.includes(',')) {
errors.push(`concept ${concept.id || '(unknown)'} must name a form and inherited structure after a comma`);
}
if (typeof concept.lineage !== 'string' || !concept.lineage.trim()) {
errors.push(`concept ${concept.id || '(unknown)'} needs lineage metadata`);
}
if (!Array.isArray(concept.tags) || concept.tags.length !== 3 || concept.tags.some(tag => typeof tag !== 'string' || !tag.trim())) {
errors.push(`concept ${concept.id || '(unknown)'} must have exactly three structural tags`);
}
if (/\b(?:in the style of|styled like|copy of)\b/i.test(concept.form)) {
errors.push(`concept ${concept.id || '(unknown)'} contains imitation language`);
}
}
}
if (expectedTotal !== undefined && concepts.length !== expectedTotal) {
errors.push(`expected ${expectedTotal} concepts, found ${concepts.length}`);
}
if (minimumTotal !== undefined && concepts.length < minimumTotal) {
errors.push(`expected at least ${minimumTotal} concepts, found ${concepts.length}`);
}
if (!Number.isInteger(reviewData?.schemaVersion) || reviewData.schemaVersion < 1) {
errors.push('reviews.schemaVersion must be a positive integer');
}
for (const [id, review] of Object.entries(reviewData?.reviews || {})) {
if (!conceptIds.has(id)) errors.push(`review references missing concept: ${id}`);
if (!CONCEPT_STATUSES.has(review?.status)) errors.push(`invalid review status for ${id}: ${String(review?.status)}`);
if (typeof review?.reviewedBy !== 'string' || !review.reviewedBy.trim()) {
errors.push(`review ${id} needs reviewedBy`);
}
if (typeof review?.reviewedAt !== 'string' || Number.isNaN(Date.parse(review.reviewedAt))) {
errors.push(`review ${id} needs an ISO reviewedAt timestamp`);
}
}
const approved = concepts.filter(concept => reviewData?.reviews?.[concept.id]?.status === 'approved');
const approvedFamilies = new Set(
(catalog?.families || [])
.filter(family => family.concepts?.some(concept => reviewData?.reviews?.[concept.id]?.status === 'approved'))
.map(family => family.id)
);
if (approved.length < 3) errors.push('at least three concepts must be approved');
if (approvedFamilies.size < 3) errors.push('approved concepts must span at least three families');
return {
errors,
warnings,
stats: {
families: familyIds.size,
concepts: concepts.length,
approved: approved.length,
pending: concepts.length - Object.keys(reviewData?.reviews || {}).length,
rejected: Object.values(reviewData?.reviews || {}).filter(review => review?.status === 'rejected').length,
},
};
}
export function approvedPoolRevision(concepts) {
const payload = concepts
.filter(concept => concept.status === 'approved')
.map(concept => `${concept.familyId}:${concept.id}:${concept.form}`)
.sort()
.join('\n');
return crypto.createHash('sha256').update(payload).digest('hex').slice(0, 12);
}
export function deterministicRank(items, input, idFor = item => item.id) {
return [...items].sort((a, b) => {
const scoreA = crypto.createHash('sha256').update(`${input}:${idFor(a)}`).digest('hex');
const scoreB = crypto.createHash('sha256').update(`${input}:${idFor(b)}`).digest('hex');
return scoreB.localeCompare(scoreA) || idFor(a).localeCompare(idFor(b));
});
}
+1
View File
@@ -1,4 +1,5 @@
// Source scripts default to slash commands. The provider build replaces only
// this exact declaration, avoiding heuristic rewrites across executable code.
export const IMPECCABLE_COMMAND_PREFIX = '/'; // @impeccable-provider-command-prefix
export const IMPECCABLE_PROVIDER_ID = 'source'; // @impeccable-provider-id
export const IMPECCABLE_COMMAND = `${IMPECCABLE_COMMAND_PREFIX}impeccable`;
+30
View File
@@ -0,0 +1,30 @@
export const LLM_ONLY_SLOP_ITEMS = Object.freeze([
'Monospace used merely to signal “technical” or “developer.”',
'Light or dark mode chosen by category habit rather than the actual use scene.',
'Everything wrapped in cards, or identical icon-heading-text cards repeated as the page structure.',
'Hero-metric scaffolds: one oversized number, a small label, supporting stats, and an accent treatment.',
'Decorative glassmorphism, meaningless sparklines, or generic rounded rectangles with drop shadows.',
'A modal chosen by reflex when the task does not require interruption or protected focus.',
]);
export function renderLlmOnlySlopReview({ manualDetector = false, automaticDetector = false, scriptsPath = null } = {}) {
const lines = [
automaticDetector
? 'AI_SLOP_REVIEW_REQUIRED: The automatic detector covers mechanical rules, but this harness has no reliable late review. Before finishing changed UI, inspect the authored result for detector-blind model reflexes:'
: 'AI_SLOP_REVIEW_REQUIRED: The automatic Impeccable design hook is not available for this session. Before finishing changed UI, inspect the authored result for detector-blind model reflexes:',
...LLM_ONLY_SLOP_ITEMS.map((item) => `- ${item}`),
'Fix reflexes, not intentional choices required by the brief or established visual authority.',
];
if (manualDetector && scriptsPath) {
lines.push(`Then run the mechanical detector once over the changed web UI: \`node ${scriptsPath}/detect.mjs --json <changed targets>\`. Do not run it earlier during concept selection.`);
}
return lines.join('\n');
}
export function renderStopSlopReview() {
return [
'[impeccable@1] Detector-blind AI-slop review. The mechanical pass is complete; now inspect the rendered result for model reflexes it cannot reliably detect:',
...LLM_ONLY_SLOP_ITEMS.map((item) => `- ${item}`),
'Fix reflexes, not intentional choices required by the brief or established visual authority. Do not rerun the detector; this is the authored judgment layer.',
].join('\n');
}