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 .changeset/plain-ascii-explore-diagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fission-ai/openspec': patch
---

Draw explore-mode diagrams with plain ASCII. The worked examples in the explore skill and `/opsx:explore` command used Unicode box-drawing, arrow, and marker glyphs, whose display width varies across terminals, fonts, and locales. Agents copied the style, causing padded boxes and aligned tables to drift.
109 changes: 56 additions & 53 deletions skills/openspec-explore/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,25 @@ Depending on what the user brings, you might:

**Visualize**
```
┌─────────────────────────────────────────┐
│ Use ASCII diagrams liberally │
├─────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ │
│ │ State │────────▶│ State │ │
│ │ A │ │ B │ │
│ └────────┘ └────────┘ │
│ │
│ System diagrams, state machines, │
│ data flows, architecture sketches, │
│ dependency graphs, comparison tables │
│ │
└─────────────────────────────────────────┘
+------------------------------------------+
| Use ASCII diagrams liberally |
+------------------------------------------+
| |
| [State A] -------> [State B] |
| | |
| v |
| [State C] |
| |
| System diagrams, state machines, |
| data flows, architecture sketches, |
| dependency graphs, comparison tables |
| |
+------------------------------------------+
```

**Draw with plain ASCII only** — borders `+` `-` `|`, arrows `-->` `<--` `^` `v`, markers `*` `x`.
Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII.

**Surface risks and unknowns**
- Identify what could go wrong
- Find gaps in understanding
Expand Down Expand Up @@ -170,17 +173,17 @@ User: I'm thinking about adding real-time collaboration
You: Real-time collab is a big space. Let me think about this...

COLLABORATION SPECTRUM
════════════════════════════════════════════
============================================

Awareness Coordination Sync
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│Presence│ │Cursors │ │ CRDT │
│ "3 │ │ Multi │ │Conflict│
│online" │ │ select │ │ free │
└────────┘ └────────┘ └────────┘
│ │ │
| | |
v v v
+--------+ +--------+ +--------+
|Presence| |Cursors | | CRDT |
| "3 | | Multi | |Conflict|
|online" | | select | | free |
+--------+ +--------+ +--------+
| | |
trivial moderate complex

Where's your head at?
Expand All @@ -192,27 +195,27 @@ User: The auth system is a mess

You: [reads codebase]

┌─────────────────────────────────────────────┐
│ CURRENT AUTH FLOW │
└─────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Google │ │ GitHub │ │ Email │
│ OAuth │ │ OAuth │ │ Magic │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────────────┼─────────────┘
▼
┌───────────┐
│ Session │
└─────┬─────┘
│
▼
┌───────────┐
│ Perms │
└───────────┘
+---------------------------------------------+
| CURRENT AUTH FLOW |
+---------------------------------------------+
|
+-------------+-------------+
v v v
+---------+ +---------+ +---------+
| Google | | GitHub | | Email |
| OAuth | | OAuth | | Magic |
+----+----+ +----+----+ +----+----+
| | |
+-------------+-------------+
v
+-----------+
| Session |
+-----+-----+
|
v
+-----------+
| Perms |
+-----------+

I see three tangles. Which one's burning?
```
Expand Down Expand Up @@ -244,19 +247,19 @@ User: A CLI tool that tracks local dev environments

You: That changes everything.

┌─────────────────────────────────────────────────┐
│ CLI TOOL DATA STORAGE │
└─────────────────────────────────────────────────┘
+-------------------------------------------------+
| CLI TOOL DATA STORAGE |
+-------------------------------------------------+

Key constraints:
• No daemon running
• Must work offline
• Single user
- No daemon running
- Must work offline
- Single user

SQLite Postgres
Deployment embedded ✓ needs server ✗
Offline yes ✓ no ✗
Single file yes ✓ no ✗
Deployment embedded needs server
Offline yes no
Single file yes no

SQLite. Not even close.

Expand Down
140 changes: 73 additions & 67 deletions src/core/templates/workflows/explore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,25 @@ Depending on what the user brings, you might:

**Visualize**
\`\`\`
┌─────────────────────────────────────────┐
│ Use ASCII diagrams liberally │
├─────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ │
│ │ State │────────▶│ State │ │
│ │ A │ │ B │ │
│ └────────┘ └────────┘ │
│ │
│ System diagrams, state machines, │
│ data flows, architecture sketches, │
│ dependency graphs, comparison tables │
│ │
└─────────────────────────────────────────┘
+------------------------------------------+
| Use ASCII diagrams liberally |
+------------------------------------------+
| |
| [State A] -------> [State B] |
| | |
| v |
| [State C] |
| |
| System diagrams, state machines, |
| data flows, architecture sketches, |
| dependency graphs, comparison tables |
| |
+------------------------------------------+
\`\`\`

**Draw with plain ASCII only** — borders \`+\` \`-\` \`|\`, arrows \`-->\` \`<--\` \`^\` \`v\`, markers \`*\` \`x\`.
Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII.

**Surface risks and unknowns**
- Identify what could go wrong
- Find gaps in understanding
Expand Down Expand Up @@ -172,17 +175,17 @@ User: I'm thinking about adding real-time collaboration
You: Real-time collab is a big space. Let me think about this...

COLLABORATION SPECTRUM
════════════════════════════════════════════
============================================

Awareness Coordination Sync
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│Presence│ │Cursors │ │ CRDT │
│ "3 │ │ Multi │ │Conflict│
│online" │ │ select │ │ free │
└────────┘ └────────┘ └────────┘
│ │ │
| | |
v v v
+--------+ +--------+ +--------+
|Presence| |Cursors | | CRDT |
| "3 | | Multi | |Conflict|
|online" | | select | | free |
+--------+ +--------+ +--------+
| | |
trivial moderate complex

Where's your head at?
Expand All @@ -194,27 +197,27 @@ User: The auth system is a mess

You: [reads codebase]

┌─────────────────────────────────────────────┐
│ CURRENT AUTH FLOW │
└─────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Google │ │ GitHub │ │ Email │
│ OAuth │ │ OAuth │ │ Magic │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────────────┼─────────────┘
▼
┌───────────┐
│ Session │
└─────┬─────┘
│
▼
┌───────────┐
│ Perms │
└───────────┘
+---------------------------------------------+
| CURRENT AUTH FLOW |
+---------------------------------------------+
|
+-------------+-------------+
v v v
+---------+ +---------+ +---------+
| Google | | GitHub | | Email |
| OAuth | | OAuth | | Magic |
+----+----+ +----+----+ +----+----+
| | |
+-------------+-------------+
v
+-----------+
| Session |
+-----+-----+
|
v
+-----------+
| Perms |
+-----------+

I see three tangles. Which one's burning?
\`\`\`
Expand Down Expand Up @@ -246,19 +249,19 @@ User: A CLI tool that tracks local dev environments

You: That changes everything.

┌─────────────────────────────────────────────────┐
│ CLI TOOL DATA STORAGE │
└─────────────────────────────────────────────────┘
+-------------------------------------------------+
| CLI TOOL DATA STORAGE |
+-------------------------------------------------+

Key constraints:
• No daemon running
• Must work offline
• Single user
- No daemon running
- Must work offline
- Single user

SQLite Postgres
Deployment embedded ✓ needs server ✗
Offline yes ✓ no ✗
Single file yes ✓ no ✗
Deployment embedded needs server
Offline yes no
Single file yes no

SQLite. Not even close.

Expand Down Expand Up @@ -371,22 +374,25 @@ Depending on what the user brings, you might:

**Visualize**
\`\`\`
┌─────────────────────────────────────────┐
│ Use ASCII diagrams liberally │
├─────────────────────────────────────────┤
│ │
│ ┌────────┐ ┌────────┐ │
│ │ State │────────▶│ State │ │
│ │ A │ │ B │ │
│ └────────┘ └────────┘ │
│ │
│ System diagrams, state machines, │
│ data flows, architecture sketches, │
│ dependency graphs, comparison tables │
│ │
└─────────────────────────────────────────┘
+------------------------------------------+
| Use ASCII diagrams liberally |
+------------------------------------------+
| |
| [State A] -------> [State B] |
| | |
| v |
| [State C] |
| |
| System diagrams, state machines, |
| data flows, architecture sketches, |
| dependency graphs, comparison tables |
| |
+------------------------------------------+
\`\`\`

**Draw with plain ASCII only** — borders \`+\` \`-\` \`|\`, arrows \`-->\` \`<--\` \`^\` \`v\`, markers \`*\` \`x\`.
Unicode diagram glyphs can render at different widths across terminals, fonts, and locales, so padded boxes and aligned tables can drift. Keep every diagram character ASCII.

**Surface risks and unknowns**
- Identify what could go wrong
- Find gaps in understanding
Expand Down
41 changes: 41 additions & 0 deletions test/core/templates/explore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ function occurrenceCount(body: string, value: string): number {
return body.split(value).length - 1;
}

const NON_ASCII = /[^\x00-\x7F]/;

function fencedBlockLines(body: string): Array<[number, string]> {
const lines: Array<[number, string]> = [];
let inFence = false;

body.split('\n').forEach((line, index) => {
if (line.trimStart().startsWith('```')) {
inFence = !inFence;
return;
}
if (inFence) {
lines.push([index + 1, line]);
}
});

return lines;
}

describe('explore templates', () => {
// Regression for #696: explore never loaded the project's declared
// context, so it reasoned without the tech stack, conventions, and
Expand Down Expand Up @@ -223,6 +242,28 @@ describe('explore templates', () => {
}
});

// Regression for #983: the worked examples drew boxes and tables with
// Unicode box-drawing, arrow, and marker glyphs. Agents copy those
// examples verbatim, and on terminals that render the glyphs
// double-width the right border of every padded box drifted loose.
it('draws every fenced example with plain ASCII only (#983)', () => {
for (const [label, body] of bodies) {
const offenders = fencedBlockLines(body)
.filter(([, line]) => NON_ASCII.test(line))
.map(([lineNumber, line]) => `${lineNumber}: ${line}`);

expect(offenders, `${label} fenced examples must be pure ASCII`).toEqual([]);
}
});

it('tells the agent to draw with ASCII and says why (#983)', () => {
for (const [label, body] of bodies) {
expect(body, label).toContain('**Draw with plain ASCII only**');
expect(body, label).toContain('render at different widths');
expect(body, label).toContain('Keep every diagram character ASCII');
}
});

it('stops after scaffolding when the user requests only a new change (#668)', () => {
for (const [label, body] of bodies) {
const transition = newChangeTransition(body, label);
Expand Down
Loading
Loading