mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-12 19:44:48 +01:00
test(W7c): shrink ceo-workflow-clarity to structural and meaning checks
W7c conversion (t05 F5-F8). Pin lines 48 -> 29 (toContain|toMatch|indexOf|includes|ordered); sentence pins
collapse to one case-insensitive meaning check per invariant. Per the Eng
"Retirements" item, CEO invariants count as periodic-only once
plan-ceo-review-benefits retires, so every invariant below keeps a free check.
Removed assertion groups (invariant -> remaining protection):
- Required/Pending/Settled status sentences (4 pins): pending work stays
unapproved; only exact authority settles a choice -> kept free: label order
plus /Pending: unapproved/i and /Settled: ... a recommendation does not/i.
- Admin-route sentences (Skip steps 1-4, 0E/0H ownership, admin answer that
requests a plan change, 0G proposals use this route, mode-change pointer):
admin menus approve nothing and return locally -> kept free: Admin < Plan
decision < steps 1-4 < checkpoints order, /this approves no plan changes/i,
/0D returns to its caller, not to mode selection/i.
- not.toContain('0D never restarts mode selection') and
not.toContain('using the Step 0E mode-handoff format') (t05 F8, bans of
retired phrasings): same invariants -> kept free: the positive route checks.
- '**STOP for the actual answer, even for a lone option.**' exact bold pin:
wait for the answer before recording -> kept free: /stop for the actual
answer/i, located between step 4 and the post-answer checkpoint.
- Mode-change sentences (repeat handoff record, complete newly applicable
Step 0 work, resume the paused step): a mode change waits for an answer ->
kept free: /pause and ask ... keep the mode until answered/i and
/selecting a mode does not approve changes/i; routing table rows kept exact.
- Scope-count sentences: reuse counts against limits, mode recommendation
excludes unchanged reuse, neither approves -> kept free: three short
case-insensitive meaning checks plus the >15 / 8-file / 2-class numbers and
the route order.
- Completion-fraction sentences (select answered questions, exclude unscored,
Y/X definitions): fraction definition -> kept free: 10/7/3 scale, reopened
choice counted once, 'Report X/Y, or `N/A` when Y is zero' (output field).
- Section-gate sentences ('0D's Plan decision route through its post-answer
save', 'Resolve critical risks now') and the literal Decision gate count 11
(t05 F7): one gate per section -> kept free: path order, /no path selects
the mode again/i, gate count derived from '### Section N:' headings.
- Section 1 opening sentences (retain mode/rationale, governing row ID): Section
1 publishes current dispositions, not a mode handoff -> kept free:
**Current scope** present, the four disposition names, /not another mode
handoff; do not ask or log the mode again/i.
Gate-tier judge that also grades this prose: 'plan-ceo-review/SKILL.md modes'.
Mutation pass (scratch worktree, generated plan-ceo-review skill): 16/16 as
expected; 11 kept-step/marker/safety/numeric mutations go red, 5 rewordings of
dropped sentences (and a lowered-register STOP line) stay green. Log:
.context/mutation-ceo-workflow-clarity.md.
This commit is contained in:
1 parent
23a0be82d7
commit
03a4521dda
1 file changed
+35
-53
@@ -28,88 +28,70 @@ const sources = [
|
||||
},
|
||||
];
|
||||
|
||||
const ordered = (text: string, anchors: string[]) => {
|
||||
const positions = anchors.map(anchor => text.indexOf(anchor));
|
||||
expect(positions.every(position => position >= 0), `missing one of ${JSON.stringify(anchors)}`).toBe(true);
|
||||
expect(positions).toEqual([...positions].sort((a, b) => a - b));
|
||||
};
|
||||
|
||||
for (const source of sources) describe(`CEO clarity routing — ${source.label}`, () => {
|
||||
const main = compact(source.main);
|
||||
const section = compact(source.section);
|
||||
const decisions = main.split('### 0D.')[1]!.split('### 0E.')[0]!;
|
||||
const mode = main.split('### 0E.')[1]!.split('### 0F.')[0]!;
|
||||
|
||||
test('pending proposals stay out of approved work and settled means exact authority', () => {
|
||||
expect(main).toContain('**Required choice:** unanswered. Resolve a choice only when continuing would change scope, hide a blocker or produce the wrong output');
|
||||
expect(main).toContain('**Pending:** unapproved; keep in Proposed, not tasks or accepted work');
|
||||
expect(main).toContain('Status is `unresolved` or `reopened`');
|
||||
expect(main).toContain('**Settled:** an answer, direct instruction or authorized auto-decision resolves this exact choice and scope; a recommendation does not');
|
||||
test('decision statuses keep pending work unapproved and settle only on exact authority', () => {
|
||||
ordered(main, ['**Required choice:**', '**Pending:**', '**Settled:**']);
|
||||
expect(main).toMatch(/\*\*Pending:\*\* unapproved/i);
|
||||
expect(main).toMatch(/\*\*Settled:\*\*[^*]*a recommendation does not/i);
|
||||
});
|
||||
|
||||
test('admin menus return locally while prescribed scope menus still require the full approval cycle', () => {
|
||||
expect(decisions).toContain('Skip steps 1–4; this approves no plan changes. Resume that menu\'s next step');
|
||||
expect(decisions).toContain('0E owns mode selection; 0H owns document approval');
|
||||
expect(decisions).toContain('If an admin answer requests a plan change, use the Plan decision route for that change before resuming');
|
||||
expect(decisions).toContain('0G proposals and section findings use this route even with prescribed menus');
|
||||
expect(decisions).toContain('0D returns to its caller, not to mode selection');
|
||||
expect(decisions).toContain('For mode changes, follow 0E\'s **Mode change** instruction');
|
||||
expect(decisions).not.toContain('0D never restarts mode selection');
|
||||
expect(decisions).toContain('**Pre-question checkpoint:**');
|
||||
expect(decisions).toContain('**STOP for the actual answer, even for a lone option.**');
|
||||
expect(decisions).toContain('**Post-answer checkpoint:**');
|
||||
test('admin menus return locally while plan decisions run the full approval cycle', () => {
|
||||
ordered(decisions, ['**Admin question:**', '**Plan decision:**', '**1. Check sources', '**2. Record the pending choice.**', '**3. Compare and save', '**Pre-question checkpoint:**', '**4. Ask, record the answer', '**Post-answer checkpoint:**']);
|
||||
expect(decisions).toMatch(/this approves no plan changes/i);
|
||||
expect(decisions).toMatch(/0D returns to its caller, not to mode selection/i);
|
||||
expect(decisions.split('**4. Ask')[1]!.split('**Post-answer checkpoint:**')[0]).toMatch(/stop for the actual answer/i);
|
||||
});
|
||||
|
||||
test('a mode change waits for authority and resumes without discarding earlier answers', () => {
|
||||
test('a mode change waits for an answer and selecting a mode approves nothing', () => {
|
||||
const change = mode.split('**Mode change:**')[1]!.split('Selecting a mode')[0]!;
|
||||
expect(change).toContain('Pause and ask with the four-mode menu; keep the mode until answered');
|
||||
expect(change).toContain('repeat the handoff/provenance record');
|
||||
expect(change).toContain('complete newly applicable Step 0 work in route order, reusing completed work and scope answers');
|
||||
expect(change).toContain('Then resume the paused step. If unchanged, resume directly');
|
||||
expect(mode).toContain('Selecting a mode does not approve changes');
|
||||
expect(change).toMatch(/pause and ask[^.]*keep the mode until answered/i);
|
||||
expect(mode).toMatch(/selecting a mode does not approve changes/i);
|
||||
expect(mode).toContain('| SCOPE EXPANSION / SELECTIVE EXPANSION | 0F → 0G → 0H (including its spec review loop) → 0I |');
|
||||
expect(mode).toContain('| HOLD SCOPE | 0G → 0I |');
|
||||
expect(mode).toContain('| SCOPE REDUCTION | 0G |');
|
||||
});
|
||||
|
||||
test('scope limits count reused deliverables but mode recommendations count only changed files', () => {
|
||||
expect(main).toContain('Count all deliverables, including reused code, against scope limits');
|
||||
expect(main).toContain('0E counts changed files, excluding unchanged reuse, to recommend a mode');
|
||||
expect(main).toContain('Neither count approves changes');
|
||||
expect(mode).toContain('For >15 planned changed files, recommend SCOPE REDUCTION');
|
||||
const routes = ['For >15 planned changed files', 'If categories overlap or are unclear', 'Otherwise: a new product/system'];
|
||||
const positions = routes.map(route => mode.indexOf(route));
|
||||
expect(positions.every(position => position >= 0)).toBe(true);
|
||||
expect(positions).toEqual([...positions].sort((a, b) => a - b));
|
||||
test('scope limits and mode recommendations keep their numeric thresholds and route order', () => {
|
||||
expect(main).toMatch(/including reused code, against scope limits/i);
|
||||
expect(main).toMatch(/excluding unchanged reuse/i);
|
||||
expect(main).toMatch(/neither count approves changes/i);
|
||||
ordered(mode, ['For >15 planned changed files', 'If categories overlap or are unclear', 'Otherwise: a new product/system']);
|
||||
expect(mode).toMatch(/>15 planned changed files, recommend SCOPE REDUCTION/);
|
||||
expect(main).toContain('more than 8 files or more than 2 new classes/services');
|
||||
});
|
||||
|
||||
test('coverage and kind-only scoring retain approvals and define the completion fraction', () => {
|
||||
test('coverage scoring keeps its scale and the completion fraction keeps its format', () => {
|
||||
expect(decisions).toContain('**Same work, different coverage:**');
|
||||
expect(decisions).toContain('10 = all edge cases, 7 = happy path, 3 = shortcut');
|
||||
expect(decisions).toContain('mode selection and Add/Defer/Skip or Defer/Keep');
|
||||
expect(decisions).toContain('No score does not waive approval checkpoints');
|
||||
expect(section).toContain('Select answered questions scored for coverage under 0D that offered a 10/10 option');
|
||||
expect(section).toContain('Exclude unscored mode/scope choices and unanswered questions');
|
||||
expect(section).toContain('Count a reopened choice only once, using its latest answered option');
|
||||
expect(section).toContain('Y is the number of eligible questions; X is how many selected the 10/10 option');
|
||||
expect(decisions).toMatch(/no score does not waive approval checkpoints/i);
|
||||
expect(section).toMatch(/count a reopened choice only once/i);
|
||||
expect(section).toContain('Report X/Y, or `N/A` when Y is zero');
|
||||
});
|
||||
|
||||
test('section findings check reopening evidence before reusing prior answers', () => {
|
||||
const gate = section.split('**Resolve.**')[1]!.split('**Apply.**')[0]!;
|
||||
const paths = ['1. This section needs a new choice', '2. An exact prior answer covers it', '3. A non-blocking choice belongs to a later section'];
|
||||
const positions = paths.map(path => gate.indexOf(path));
|
||||
expect(positions.every(position => position >= 0)).toBe(true);
|
||||
expect(positions).toEqual([...positions].sort((a, b) => a - b));
|
||||
expect(gate).toContain('0D\'s Plan decision route through its post-answer save');
|
||||
expect(gate).toContain('Resolve critical risks now');
|
||||
expect(gate).toContain('No path selects the mode again');
|
||||
expect(source.section.match(/\*\*Decision gate\.\*\*/g)).toHaveLength(11);
|
||||
ordered(gate, ['1. This section needs a new choice', '2. An exact prior answer covers it', '3. A non-blocking choice belongs to a later section']);
|
||||
expect(gate).toMatch(/no path selects the mode again/i);
|
||||
const sections = source.section.match(/^### Section \d+:/gm)!.length;
|
||||
expect(sections).toBeGreaterThan(0);
|
||||
expect(source.section.match(/\*\*Decision gate\.\*\*/g)).toHaveLength(sections);
|
||||
});
|
||||
|
||||
test('Section 1 publishes current dispositions, not a second initial mode handoff', () => {
|
||||
const opening = section.split('### Section 1: Architecture Review')[1]!.split('Evaluate and diagram:')[0]!;
|
||||
expect(opening).toContain('Publish **Current scope** in chat before the architecture analysis');
|
||||
expect(opening).toContain('Retain 0E\'s selected mode, rationale and preference attribution');
|
||||
expect(opening).toContain('each governing row\'s ID, disposition and answer reference');
|
||||
expect(opening).toContain('including scope decisions after 0E');
|
||||
expect(opening).toContain('Distinguish accepted, deferred, rejected and pending work');
|
||||
expect(opening).toContain('This is a scope update, not another mode handoff; do not ask or log the mode again');
|
||||
expect(opening).not.toContain('using the Step 0E mode-handoff format');
|
||||
expect(opening).toContain('**Current scope**');
|
||||
expect(opening).toMatch(/accepted, deferred, rejected and pending/i);
|
||||
expect(opening).toMatch(/not another mode handoff; do not ask or log the mode again/i);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user