Initial commit — design docs + Phase 0 validation harness
Sets up the Socrata project repo with: docs/ — strategy and design documents - idea.md: full product vision - implementation-plan.md: Phase 0 + Phase 1 MVP plan - phase-0-validation.md: 2-week validation experiment strategy - phase-0-plan.md: concrete Phase 0 build plan - phase-0-results.md: Phase 0 gate outcome — GO for MVP - sysml-modeling.md: metamodel + SE discipline + validation rules - socrates.md: agent character, surfaces, modes, prompts, lifecycle - sync.md: bidirectional text↔diagram sync engineering - design-source/: HTML/CSS/JS handoff bundle from Claude Design phase-0/ — validated harness (CLI, no UI, no DB) - LM Studio (local OpenAI-compatible) generation + detection + judge - PlantUML rendering for SysML model visualization - 10-seed corpus (8 working + 2 holdouts) - 5 corpus runs with iteration history in reports/ - Final gate: 10/10 pass, mean 4.32/5, holdouts validated Phase 1 MVP scope and milestones documented in implementation-plan.md.
This commit is contained in:
99
docs/design-source/socrata/project/text-canvas.jsx
Normal file
99
docs/design-source/socrata/project/text-canvas.jsx
Normal file
@@ -0,0 +1,99 @@
|
||||
// TextCanvas — narrative editor surface with markup chips, headings, prose.
|
||||
// Renders chips per markupStyle: "pill" | "underline" | "bracket" | "color".
|
||||
|
||||
const CHIP_TYPE_LABEL = {
|
||||
block: "block",
|
||||
property: "property",
|
||||
association: "assoc",
|
||||
requirement: "req",
|
||||
};
|
||||
|
||||
function Chip({ kind, id, label, markupStyle, onHover, onClick, focused }) {
|
||||
const cls = `chip chip-${kind} chip-style-${markupStyle}${focused ? " chip-focus" : ""}`;
|
||||
const handlers = {
|
||||
onMouseEnter: () => onHover && onHover(id),
|
||||
onMouseLeave: () => onHover && onHover(null),
|
||||
onClick: () => onClick && onClick(id, kind),
|
||||
};
|
||||
if (markupStyle === "bracket") {
|
||||
return (
|
||||
<span className={cls} {...handlers}>
|
||||
<span className="chip-bracket">[</span>
|
||||
<span className="chip-kind">{CHIP_TYPE_LABEL[kind]}:</span>
|
||||
<span className="chip-label">{label}</span>
|
||||
<span className="chip-bracket">]</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (markupStyle === "underline") {
|
||||
return (
|
||||
<span className={cls} {...handlers}>
|
||||
<span className="chip-glyph">{kindGlyph(kind)}</span>
|
||||
<span className="chip-label">{label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
// pill (default) and color both render as filled chips, color uses kind color, pill is muted.
|
||||
return (
|
||||
<span className={cls} {...handlers}>
|
||||
<span className="chip-glyph">{kindGlyph(kind)}</span>
|
||||
<span className="chip-label">{label}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function kindGlyph(kind) {
|
||||
switch (kind) {
|
||||
case "block": return "▢";
|
||||
case "property": return "·";
|
||||
case "association": return "→";
|
||||
case "requirement": return "§";
|
||||
default: return "·";
|
||||
}
|
||||
}
|
||||
|
||||
function TextCanvas({ data, density, markupStyle, focusBlockId, setFocusBlockId, gutter }) {
|
||||
const padY = density === "compact" ? 10 : 18;
|
||||
return (
|
||||
<div className="text-canvas" style={{ padding: `${padY}px ${density === "compact" ? 22 : 36}px` }}>
|
||||
{gutter}
|
||||
{data.narrative.map((node, i) => {
|
||||
if (node.type === "h1") return <h1 key={i} className="t-h1">{node.text}</h1>;
|
||||
if (node.type === "h2") return <h2 key={i} className="t-h2">{node.text}</h2>;
|
||||
if (node.type === "p") {
|
||||
return (
|
||||
<p key={i} className="t-p">
|
||||
{node.children.map((c, j) => {
|
||||
if (c.t === "text") return <span key={j}>{c.v}</span>;
|
||||
if (c.t === "chip") return (
|
||||
<Chip key={j} kind={c.kind} id={c.id} label={c.label}
|
||||
markupStyle={markupStyle}
|
||||
focused={focusBlockId === c.id}
|
||||
onHover={setFocusBlockId}
|
||||
onClick={(id) => setFocusBlockId(id)}
|
||||
/>
|
||||
);
|
||||
return null;
|
||||
})}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
|
||||
{/* a Socrates inline annotation (margin note) */}
|
||||
<div className="margin-note">
|
||||
<span className="margin-note-glyph">Σ</span>
|
||||
<span>
|
||||
<span className="margin-note-who">Socrates · margin</span>
|
||||
<span className="margin-note-text">
|
||||
"Refuses to produce solutions" is a strong constraint. Have you decided what counts as a "solution" vs. a "scaffold"? This boundary will determine whether the refusal policy is enforceable.
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
window.TextCanvas = TextCanvas;
|
||||
window.Chip = Chip;
|
||||
Reference in New Issue
Block a user