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
4 changes: 4 additions & 0 deletions tests/prose/cases/scoping-defines-the-quickfix/act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Execute skills/workflow-scoping-entry/SKILL.md with arguments
$0=quick-fix, $1=support-email, and continue into the processing skill it
hands off to. Follow the whole scoping pass to its conclusion. Stop when
the prose reaches the pipeline continuation — do not invoke the bridge.
46 changes: 46 additions & 0 deletions tests/prose/cases/scoping-defines-the-quickfix/assert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
The prose should have taken this path:

1. the entry finds no scoping recorded, reads the carrier — the
description and the session log's exploration — and hands off with it;
the entry itself creates and asks nothing
2. no specification exists, so the pass starts fresh with no resume
choice put to the user
3. context gathering reads the seed and description first, and its
questions go to what the carrier does not answer — where the address
appears — not to the what and why it already holds. Two exchanges at
most
4. the complexity check passes silently: a mechanical single-purpose
change raises no warning and no promotion offer
5. the specification is written and registered through the engine —
started and completed — before any plan exists
6. with no project default recorded, the format choice is put to the
user, and the choice is recorded as the project default
7. tasks are written under the hard rules — at most two, no acceptance
criteria — and the plan is registered with its gates set to auto;
scoping itself is marked complete only after the plan is in place
8. the conclusion renders the completion display and reaches the bridge
handoff, where the walk stops without invoking it

Further claims:

- no agents are dispatched at any point — scoping writes its spec and
tasks directly
- nothing is implemented: no task is started, and nothing outside
`.workflows/` changes

EXPECTED WORLD — from a work unit holding only its discovery carrier:

- a specification at
`.workflows/support-email/specification/support-email/specification.md`
carrying the scoping shape — change description, scope, exclusions,
verification — and naming both the old and new addresses
- the scope reflecting what the user actually said: the checkout footer
and contact page as known sites, the transactional template as
suspected, with the exact locations left to implementation to confirm
- a plan at `.workflows/support-email/planning/support-email/planning.md`
with one or two task files beside it in local-markdown form, none of
them started
- the manifest holding specification, planning and scoping all completed,
the plan on the local-markdown format with its gates set to auto
- local-markdown recorded as the project's default plan format
- no implementation or review directories, and no second work unit
53 changes: 53 additions & 0 deletions tests/prose/cases/scoping-defines-the-quickfix/case.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"origin": "quick-fix had no coverage anywhere — this walks its whole definition stage: entry, context, spec, format, tasks, conclusion, in the single pass scoping is",
"entry": "workflow-scoping-entry",
"world": "claims",
"files": [
"skills/workflow-scoping-entry/SKILL.md",
"skills/workflow-scoping-entry/references/validate-phase.md",
"skills/workflow-scoping-entry/references/invoke-skill.md",
"skills/workflow-scoping-process/SKILL.md",
"skills/workflow-scoping-process/references/gather-context.md",
"skills/workflow-scoping-process/references/complexity-check.md",
"skills/workflow-scoping-process/references/write-specification.md",
"skills/workflow-scoping-process/references/select-format.md",
"skills/workflow-scoping-process/references/write-tasks.md",
"skills/workflow-scoping-process/references/conclude-scoping.md",
"skills/workflow-shared/references/seed-context.md",
"skills/workflow-knowledge/references/knowledge-usage.md",
"skills/workflow-knowledge/references/contextual-query.md",
"skills/workflow-planning-process/references/output-formats.md",
"skills/workflow-planning-process/references/output-formats/local-markdown/about.md",
"skills/workflow-planning-process/references/output-formats/local-markdown/authoring.md"
],
"conduct": "The user knows exactly what the change is and why: the support@ mailbox is being retired at the end of the month and mail to it already bounces, so everything should say help@ instead. Asked where it appears, they are sure about the checkout footer and the contact page, think it may also be in a transactional email template, and do not know any file names. They have no exceptions or exclusions to name. When offered tooling or format choices they take the simplest option that adds no external dependencies — plain files in the repo. They answer the question asked, concretely, and say plainly when they do not know.",
"invariants": {
"engine_before_write": true,
"calls_include": [
"manifest get support-email.scoping.support-email status",
"manifest get support-email description",
"topic start support-email specification support-email",
"topic complete support-email specification support-email",
"topic start support-email planning support-email",
"topic complete support-email planning support-email",
"topic complete support-email scoping support-email",
"project.defaults.plan_format local-markdown",
"render phase-completed support-email --phase scoping"
],
"calls_in_order": [
"manifest get support-email.scoping.support-email status",
"topic start support-email specification support-email",
"topic complete support-email specification support-email",
"topic start support-email planning support-email",
"topic complete support-email planning support-email",
"topic complete support-email scoping support-email",
"render phase-completed support-email --phase scoping"
],
"calls_exclude": [
"task start",
"task next",
"topic reopen",
"workflow-bridge"
]
}
}
12 changes: 12 additions & 0 deletions tests/prose/cases/scoping-defines-the-quickfix/fixture-state.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

// The quick-fix is captured and its definition stage has not begun.

const m = require('../../mainlines/quickfix.cjs');

module.exports = {
build(h) {
m.init(h);
m.create(h);
},
};
8 changes: 8 additions & 0 deletions tests/prose/cases/scoping-defines-the-quickfix/fixture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
A quick-fix shaped in discovery: the retired support email address needs
replacing with the new one wherever it appears. The work unit exists with
its session log; scoping has not begun, and no specification or plan
exists anywhere.

The context was cleared at the phase boundary — this session opens cold
at the entry skill with nothing but the two arguments and what is on
disk.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"showClearContextOnPlanAccept": true,
"permissions": {
"allow": [
"Edit(.workflows/**)",
"Bash(mv .workflows/:*)"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ddb2aec6b94ecc0e076a44f9f1cfb6293f30cca9dcc9f933a57276c03f1e8314
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.cache/
.manifest.json.*.tmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"work_units": {
"support-email": {
"work_type": "quick-fix"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Discovery Session 001

Date: 2026-01-01
Work unit: support-email

## Description (as of session)

Replace the retired support email address with the new one.

## Seed

(none)

## Imports

(none)

## Map State at Start

(n/a — single-topic work)

## Exploration

The support@ mailbox is being retired at the end of the month and
mail to it already bounces for some customers; everything should
point at help@ instead. Purely mechanical — same links, same copy,
different address. The user was not sure everywhere it appears and
wants that pinned down during scoping. Confirmed as a quick-fix.

## Edits

(none)

## Topics Identified

(none)

## Conclusion

(none)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "support-email",
"work_type": "quick-fix",
"status": "in-progress",
"created": "2026-01-01",
"description": "Replace the retired support email address with the new one",
"phases": {}
}
72 changes: 72 additions & 0 deletions tests/prose/mainlines/quickfix.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';

// Quick-fix mainline: the smallest pipeline shape. Discovery shapes the
// work and commits it; scoping is the whole definition stage in one pass.
//
// The Exploration deliberately holds the what and the why but not the
// where. Scoping's gather-context skips its questions when the carrier
// already captures all three, and that guard is a judgement call — a
// carrier that plainly lacks the where makes the questioning arm the only
// honest reading, which is what the scoping case needs to exercise.

const WU = 'support-email';

function init(h) {
h.knowledge('setup', '--keyword-only');
h.engine('boot');
}

function create(h) {
// Shape per workflow-discovery/references/template.md + confirm-trigger.md:
// single-phase work backfills Exploration at creation; Edits, Topics
// Identified, and Conclusion land as (none).
const log = `.workflows/${WU}/discovery/sessions/session-001.md`;
h.write(log, [
'# Discovery Session 001',
'',
'Date: 2026-01-01',
`Work unit: ${WU}`,
'',
'## Description (as of session)',
'',
'Replace the retired support email address with the new one.',
'',
'## Seed',
'',
'(none)',
'',
'## Imports',
'',
'(none)',
'',
'## Map State at Start',
'',
'(n/a — single-topic work)',
'',
'## Exploration',
'',
'The support@ mailbox is being retired at the end of the month and',
'mail to it already bounces for some customers; everything should',
'point at help@ instead. Purely mechanical — same links, same copy,',
'different address. The user was not sure everywhere it appears and',
'wants that pinned down during scoping. Confirmed as a quick-fix.',
'',
'## Edits',
'',
'(none)',
'',
'## Topics Identified',
'',
'(none)',
'',
'## Conclusion',
'',
'(none)',
'',
].join('\n'));
h.engine('workunit', 'create', WU, 'quick-fix',
'--description', 'Replace the retired support email address with the new one',
'--session-log-file', log);
}

module.exports = { WU, init, create };