Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ jobs:
- name: Syntax check tools
run: |
node --check tools/prepare-deck.mjs
node --check tools/validate-brief.mjs
node --check tools/test-brief-validation.mjs
node --check tools/test-agent-workflow.mjs
node --check tools/evaluate-edit.mjs
node --check tools/test-editability-eval.mjs
node --check tools/browser-qa.mjs

- name: Test deck brief validation gate
run: node tools/test-brief-validation.mjs

- name: Test editability evaluator
run: node tools/test-editability-eval.mjs

Expand Down
22 changes: 18 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ LICENSE MIT
.agents/skills/getslide/ Agent Skills / Codex project skill
.claude/skills/getslide/ Byte-identical Claude Code project skill
docs/
DECK_BRIEF.schema.md Deck brief standard
DECK_BRIEF.schema.md Deck brief standard + executable shape
HTML_DECK_CONTRACT.md Requirements every generated deck must satisfy
STUDENT_DEVELOPER_PATTERNS.md Slide pattern catalog
VALIDATION.md Static + real-browser validation checklist
Expand All @@ -62,6 +62,8 @@ prompts/
review-deck-structure.md Review prompt
tools/
prepare-deck.mjs Arbitrary text/Markdown source staging
validate-brief.mjs Structural/source-sufficiency brief gate
test-brief-validation.mjs Brief-gate regression checks
validate-deck.mjs Structural validator
evaluate-edit.mjs Before/after edit-containment evaluator
test-editability-eval.mjs Positive/negative editability regressions
Expand All @@ -78,14 +80,23 @@ Do not add new top-level folders without a decision recorded in `PRODUCT_DECISIO
- **Decks follow the contract.** Any HTML deck you create or edit must satisfy `docs/HTML_DECK_CONTRACT.md`: single file, `section.slide` with unique `data-slide-id` and a `data-pattern` from the catalog, TOC/nav, page numbers, keyboard navigation, print CSS, `:root` design tokens.
- **Edit slides, not the system.** When changing deck content, do not restructure CSS tokens, navigation script, or slide markup conventions unless that is the explicit task.
- **Source grounding is mandatory.** New factual content must be traceable to the source/brief. Missing facts stay in `missing_information`; low-risk framing defaults stay visible in `auto_filled_assumptions`.
- **Briefs are executable contracts.** Before generating a deck, `DECK_BRIEF.md` must pass `tools/validate-brief.mjs`. A structural PASS never substitutes for semantic source/brief review.
- **Templates may contain placeholders; examples may not.** `templates/` uses clearly-safe placeholder content. Anything under `examples/` must be complete, with zero unresolved placeholders (`TODO`, `TBD`, double curly braces, `[PLACEHOLDER]`, lorem ipsum).
- **Keep schema and examples in sync.** If you change `docs/DECK_BRIEF.schema.md`, update the fictional example brief and prompts that reference the fields.
- **Record decisions.** Any scope or positioning change goes into `PRODUCT_DECISIONS.md` in the same change.
- **Portable workflow only.** Public agent helpers may stage user-supplied text locally and assemble checked-in public resources; they may not fetch, upload, host, or call a model/provider.
- **Mechanical gates are bounded evidence.** `evaluate-edit.mjs` proves declared structural/change containment, and `browser-qa.mjs` proves specific runtime behaviors. Neither is semantic source-fidelity or general visual-quality proof.
- **Mechanical gates are bounded evidence.** `validate-brief.mjs` proves brief shape/mechanical sufficiency, `evaluate-edit.mjs` proves declared structural/change containment, and `browser-qa.mjs` proves specific runtime behaviors. None proves semantic source fidelity or general visual quality.

## Validation expectations

After creating or changing `DECK_BRIEF.md`, run:

```sh
node tools/validate-brief.mjs <path-to-DECK_BRIEF.md>
```

`prepare-deck.mjs` also enforces this gate before creating `brief-to-deck-packet.md`.

After editing or creating any deck, run the static validator on every deck you touched and confirm exit code `0`:

```sh
Expand All @@ -107,9 +118,12 @@ node tools/browser-qa.mjs <path-to-deck.html>
When changing the agent/editability workflow or validation tooling, run the proportional regression set:

```sh
node --check tools/validate-brief.mjs
node --check tools/test-brief-validation.mjs
node --check tools/evaluate-edit.mjs
node --check tools/test-editability-eval.mjs
node --check tools/browser-qa.mjs
node tools/test-brief-validation.mjs
node tools/test-editability-eval.mjs
node tools/browser-qa.mjs examples/hackathon-demo/index.html
node tools/test-agent-workflow.mjs
Expand All @@ -121,13 +135,13 @@ Run existing benchmark aggregation only when the completed local benchmark runs

Then perform remaining manual checks in `docs/VALIDATION.md` when applicable, especially:

- source/brief fidelity for every changed factual claim,
- source/brief fidelity for every factual claim,
- print preview with one slide per page,
- projector readability and composition,
- the 1280×800 overflow viewport until it is automated,
- no ghostwriting language or private traces in the diff.

For claims about iterative AI editability, a validator PASS alone is insufficient. For claims about visual/browser quality, static inspection alone is insufficient.
For claims about source grounding, a brief-validator PASS alone is insufficient. For claims about iterative AI editability, a deck-validator PASS alone is insufficient. For claims about visual/browser quality, static inspection alone is insufficient.

Report what you actually checked; never convert a mechanical containment check, static validator, or single browser viewport into broader proof than it provides.

Expand Down
7 changes: 4 additions & 3 deletions PRODUCT_DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Current decision log for getslide.md. This file records what has been decided, what is deferred, what is explicitly out of scope for now, and what remains open. Update it whenever a decision changes.

Last updated: 2026-08-24
Last updated: 2026-08-25

## Decided

Expand All @@ -27,13 +27,14 @@ Last updated: 2026-08-24
| Repo language | **English-first** for all canonical public repo content. Translated README content may exist but must not become the source of truth. |
| License | MIT. |
| Dependencies | None. No build step, no npm packages, no CDN assets. Decks and deterministic helper scripts use platform/browser or Node built-ins only. |
| CI validation | GitHub Actions may run the zero-dependency Node regression checks, edit-containment tests, real installed-browser QA, and the example validator on pull requests and `main`. CI performs **no deploy, publish, artifact upload, model call, browser package installation, or external service integration**. |
| CI validation | GitHub Actions may run the zero-dependency Node regression checks, brief/edit-containment tests, real installed-browser QA, and the example validator on pull requests and `main`. CI performs **no deploy, publish, artifact upload, model call, browser package installation, or external service integration**. |
| Experimental harness | v0.2 provides a provider-neutral, file-based Markdown-to-brief-to-deck benchmark harness. It uses prompts and Node built-ins only; it is not hosted generation or automated factual verification. |
| Generated deck navigation | v0.2.1 requires generated decks to preserve the canonical base-template navigation script. Static validation checks conservative behavior signals; runtime browser and print QA remain separate gates. |
| Agent-native source staging | v0.3 adds `tools/prepare-deck.mjs` so one arbitrary text/Markdown source can be staged into the same brief/deck packet flow without benchmark metadata or a model/network call. |
| Editability evaluation | v0.3 treats post-generation targeted editing as a first-class quality axis. Validator PASS is necessary but insufficient; source grounding, change containment, navigation integrity, and visual/manual QA are evaluated separately. |
| Executable edit containment | v0.3.1 adds `tools/evaluate-edit.mjs` with explicit `targeted`, `split`, `reorder`, and `compression` policies. It invokes the deck validator and blocks undeclared slide/system changes, `:root` drift, and navigation/script drift. This is mechanical containment evidence, **not semantic factual proof**. |
| Real browser QA | v0.3.1 adds `tools/browser-qa.mjs`, which uses an already installed Chrome/Chromium through the DevTools protocol and Node built-ins to check actual `file://` runtime navigation, TOC/hash/page-number synchronization, and one canonical viewport overflow gate. No Puppeteer/Playwright or browser download is added. |
| Executable brief gate | v0.3.2 validates the documented `DECK_BRIEF.md` top-level scalar/list subset before generation. Required fields, confidence, optional field shapes, duplicate/malformed syntax, and the mechanical `high`-confidence/no-unresolved-gap invariant are checked; invalid briefs cannot produce a generation packet. This is structural evidence, **not semantic source-fidelity proof**. |

## Deferred

Expand Down Expand Up @@ -88,4 +89,4 @@ A future hosted wrapper should sell convenience and operational quality, not acc
5. Does `DECK_BRIEF.md` need an explicit schema-version field before external tools start producing briefs?
6. How much of the pattern catalog should remain public as it grows: all of it or a stable public core plus specialized packs?
7. If agent-native usage is strong but setup friction blocks non-agent users, what is the thinnest hosted wrapper that removes that friction without becoming a generic slide SaaS?
8. After mechanical containment and one canonical browser viewport are reliable, which next quality gate delivers more value: semantic source-review automation, 1280×800 responsive QA, or print/PDF rendering evidence?
8. After mechanical containment, executable brief validation, and one canonical browser viewport are reliable, which next quality gate delivers more value: semantic source-review automation, 1280×800 responsive QA, or print/PDF rendering evidence?
15 changes: 13 additions & 2 deletions docs/AGENT_WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ The important separation is:

The agent must never turn a missing metric, user count, result, team role, feature, architecture detail, or implementation fact into an assumption merely to make the deck look complete.

Before generation, validate the brief itself:

```sh
node tools/validate-brief.mjs <run-directory>/DECK_BRIEF.md
```

The validator checks the documented top-level scalar/list shape, required fields, confidence enum, optional field types, duplicate fields, and the mechanical rule that `confidence: high` cannot retain unresolved `missing_information`. It does **not** prove that `key_points` are semantically supported by the source; source/brief review remains a separate requirement.

## Source-sufficiency gate

The agent uses the existing confidence field as an execution gate.
Expand All @@ -84,7 +92,7 @@ A direct end-to-end deck request may proceed without another approval turn when:
- no unresolved factual gap is required for the proposed narrative,
- no new risky assumption is needed.

The brief still remains a saved, reviewable artifact.
The brief still remains a saved, reviewable artifact. `validate-brief.mjs` will mechanically reject `high` confidence if `missing_information` is non-empty.

### Medium

Expand All @@ -104,7 +112,9 @@ After `DECK_BRIEF.md` exists, rerun the same preparation command:
node tools/prepare-deck.mjs <source-file> --out <run-directory>
```

The command now creates `brief-to-deck-packet.md`, which bundles:
`prepare-deck.mjs` reruns `validate-brief.mjs` before generation. If validation fails, it removes any stale `brief-to-deck-packet.md` and stops. A malformed or mechanically inconsistent brief therefore cannot silently advance to deck generation.

When the brief passes, the command creates `brief-to-deck-packet.md`, which bundles:

- the current brief
- `prompts/brief-to-html-deck.md`
Expand Down Expand Up @@ -137,6 +147,7 @@ Use `docs/EDITABILITY_EVAL.md` when testing post-generation changes. A structura
Changes to the agent-native workflow should run:

```sh
node tools/test-brief-validation.mjs
node tools/test-agent-workflow.mjs
node tools/test-generation-harness.mjs
node tools/validate-deck.mjs examples/hackathon-demo/index.html
Expand Down
12 changes: 12 additions & 0 deletions docs/DECK_BRIEF.schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ A deck brief exists so that:

A `DECK_BRIEF.md` file is a Markdown file whose content is a single YAML frontmatter block, optionally followed by free-form Markdown notes. The YAML block is the machine-readable part; the notes are for humans.

The public workflow intentionally uses a small YAML subset: top-level scalar fields and indented dash lists. Avoid nested mappings, block scalars, anchors, aliases, or other advanced YAML features. This keeps the brief portable and allows zero-dependency validation.

Run the executable structural gate before generation:

```sh
node tools/validate-brief.mjs <DECK_BRIEF.md>
```

`tools/prepare-deck.mjs` runs the same gate automatically and refuses to create `brief-to-deck-packet.md` when the brief is invalid. This validates shape and the mechanical confidence/gap invariant; it does **not** prove that a claim is actually supported by the source.

## Fields

### Required fields
Expand Down Expand Up @@ -49,6 +59,8 @@ A `DECK_BRIEF.md` file is a Markdown file whose content is a single YAML frontma
| `medium` | Sources cover the core story, but some slides depend on assumptions or have gaps. | Review `missing_information` and `auto_filled_assumptions` before generating. |
| `low` | Sources are thin or ambiguous; major content had to be assumed. | Add material or answer the missing-information items first. |

The executable validator enforces one mechanical invariant from this table: a brief cannot claim `confidence: high` while `missing_information` still contains unresolved items.

## Rules for `missing_information` and `auto_filled_assumptions`

- Anything the deck states that is **not in the source materials** must appear in `auto_filled_assumptions`.
Expand Down
21 changes: 19 additions & 2 deletions tools/prepare-deck.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
import { basename, dirname, relative, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';

const args = process.argv.slice(2);
if (args.length !== 3 || args[1] !== '--out') {
Expand Down Expand Up @@ -54,13 +55,25 @@ const sourcePacket = [
writeFileSync(resolve(out, 'source-to-brief-packet.md'), sourcePacket, 'utf8');

if (!existsSync(briefPath)) {
if (existsSync(deckPacketPath)) unlinkSync(deckPacketPath);
removeDeckPacket();
console.log('Prepared ' + display(out) + '. Next: create DECK_BRIEF.md from source-to-brief-packet.md, then rerun this command.');
process.exit(0);
}

const brief = readFileSync(briefPath, 'utf8');
if (!brief.trim()) fail('DECK_BRIEF.md exists but is empty: ' + display(briefPath));
if (!brief.trim()) {
removeDeckPacket();
fail('DECK_BRIEF.md exists but is empty: ' + display(briefPath));
}

const briefValidator = resolve(root, 'tools', 'validate-brief.mjs');
const validation = spawnSync(process.execPath, [briefValidator, briefPath], { encoding: 'utf8' });
if (validation.status !== 0) {
removeDeckPacket();
const output = (validation.stdout || validation.stderr || 'brief validation failed').trim();
if (output) console.error(output);
fail('DECK_BRIEF.md failed validation. Fix the brief before preparing a generation packet.');
}

const files = [
'prompts/brief-to-html-deck.md',
Expand All @@ -75,6 +88,10 @@ const deckPacket = '# Brief-to-deck packet\n\n## Current brief\n\n' + brief + '\
writeFileSync(deckPacketPath, deckPacket, 'utf8');
console.log('Prepared ' + display(out) + '. Next: create index.html from brief-to-deck-packet.md, then validate it.');

function removeDeckPacket() {
if (existsSync(deckPacketPath)) unlinkSync(deckPacketPath);
}

function display(path) {
return (relative(process.cwd(), path) || basename(path)).replace(/\\/g, '/');
}
Expand Down
Loading