mirror of
https://github.com/EveryInc/compound-engineering-plugin.git
synced 2026-09-29 17:50:12 +02:00
102 lines
5.4 KiB
TypeScript
102 lines
5.4 KiB
TypeScript
import { describe, expect, test } from "bun:test"
|
|
import { readFile } from "node:fs/promises"
|
|
import path from "node:path"
|
|
|
|
// 2026-08-18: the Core Principles and the Phase 0.3 coherent-work gate moved
|
|
// out of SKILL.md into references/interaction-rules.md and references/phase-0.md
|
|
// when the body was restructured under the Codex 8000-byte prompt budget. Both
|
|
// are artifact/scope invariants rather than window-deciding rules, and the body
|
|
// names each file as a required read before the step that applies it, so they are
|
|
// asserted against the files that now own them.
|
|
const interactionRulesPath = path.join(
|
|
process.cwd(),
|
|
"skills/ce-brainstorm/references/interaction-rules.md",
|
|
)
|
|
const phase0Path = path.join(process.cwd(), "skills/ce-brainstorm/references/phase-0.md")
|
|
const sectionsPath = path.join(
|
|
process.cwd(),
|
|
"skills/ce-brainstorm/references/brainstorm-sections.md",
|
|
)
|
|
const markdownRenderingPath = path.join(
|
|
process.cwd(),
|
|
"skills/ce-brainstorm/references/markdown-rendering.md",
|
|
)
|
|
const htmlRenderingPath = path.join(
|
|
process.cwd(),
|
|
"skills/ce-brainstorm/references/html-rendering.md",
|
|
)
|
|
|
|
describe("ce-brainstorm integration scope check", () => {
|
|
test("treats named sources as coverage before splitting implementation work", async () => {
|
|
const skill = await readFile(interactionRulesPath, "utf8")
|
|
const corePrinciplesStart = skill.indexOf("## Core Principles")
|
|
const interactionRulesStart = skill.indexOf("## Interaction Rules")
|
|
const corePrinciples = skill.slice(corePrinciplesStart, interactionRulesStart)
|
|
|
|
expect(corePrinciplesStart).toBeGreaterThanOrEqual(0)
|
|
expect(interactionRulesStart).toBeGreaterThan(corePrinciplesStart)
|
|
expect(corePrinciples).toContain("Do not turn coverage into decomposition")
|
|
expect(corePrinciples).toContain(
|
|
"treat named devices, providers, and data sources as coverage requirements, not automatically as separate integration workstreams",
|
|
)
|
|
expect(corePrinciples).toContain(
|
|
"Split them only when a shared access path cannot satisfy a named requirement",
|
|
)
|
|
expect(corePrinciples).toContain(
|
|
"Leave connector selection to planning unless that choice materially changes product scope or behavior",
|
|
)
|
|
})
|
|
|
|
test("narrows multi-outcome requests to one coherent work unit without creating a parent roadmap", async () => {
|
|
const skill = await readFile(phase0Path, "utf8")
|
|
const phase03Start = skill.indexOf("#### 0.3 Assess Scope")
|
|
const phase03 = skill.slice(phase03Start)
|
|
|
|
expect(phase03Start).toBeGreaterThanOrEqual(0)
|
|
expect(phase03).toContain("Coherent-work gate")
|
|
expect(phase03).toContain("more than one independently plannable product outcome")
|
|
expect(phase03).toContain("Ask which one area this brainstorm should own")
|
|
expect(phase03).toContain("sole source of Requirements, Flows, Acceptance Examples")
|
|
expect(phase03).toContain("Carry the boundary into the Goal Capsule")
|
|
expect(phase03).toContain("does not create a parent plan or a roadmap")
|
|
})
|
|
|
|
test("preserves the broader relationship in plain language with bullets before diagrams", async () => {
|
|
const sections = await readFile(sectionsPath, "utf8")
|
|
const sectionStart = sections.indexOf("semantic role `work-relationships`")
|
|
const sectionEnd = sections.indexOf("\n\n- **Actors**", sectionStart)
|
|
const relationshipContract = sections.slice(sectionStart, sectionEnd)
|
|
|
|
expect(sectionStart).toBeGreaterThanOrEqual(0)
|
|
expect(sectionEnd).toBeGreaterThan(sectionStart)
|
|
expect(relationshipContract).toContain("shallow indented bullet list")
|
|
expect(relationshipContract).toContain("indentation groups the prose but never carries the")
|
|
expect(relationshipContract).toContain("current understanding, not a committed roadmap")
|
|
expect(relationshipContract).toContain("Use no diagram by default")
|
|
expect(relationshipContract).toContain("non-linear cross-links, fan-in, or fan-out")
|
|
expect(relationshipContract).toContain("do not create or synchronize a separate master map")
|
|
})
|
|
|
|
test("gives the relationship section a format-specific semantic role independent of its heading", async () => {
|
|
const sections = await readFile(sectionsPath, "utf8")
|
|
const markdown = await readFile(markdownRenderingPath, "utf8")
|
|
const html = await readFile(htmlRenderingPath, "utf8")
|
|
const readinessStart = sections.indexOf("## Ready for Planning Check")
|
|
const readinessEnd = sections.indexOf("## Product Contract hard floor", readinessStart)
|
|
const readinessCheck = sections.slice(readinessStart, readinessEnd)
|
|
|
|
expect(sections).toContain("semantic role `work-relationships`")
|
|
expect(sections).toContain("stable even if its visible heading is renamed")
|
|
expect(readinessStart).toBeGreaterThanOrEqual(0)
|
|
expect(readinessEnd).toBeGreaterThan(readinessStart)
|
|
expect(readinessCheck).toContain("When the coherent-work gate split a broader request")
|
|
expect(readinessCheck).toContain("the `work-relationships` section is present")
|
|
expect(readinessCheck).toContain("<!-- ce-section: work-relationships -->")
|
|
expect(readinessCheck).toContain('data-ce-section="work-relationships"')
|
|
expect(markdown).toContain("<!-- ce-section: work-relationships -->")
|
|
expect(markdown).toMatch(/only exception.*contract-defined invisible\s+semantic marker/s)
|
|
expect(html).toContain('data-ce-section="work-relationships"')
|
|
expect(html).toContain("stable even when the visible heading changes")
|
|
})
|
|
})
|