Guided Engineering

An OPS example, end to end

One small change, followed from the request to the evidence. Everything on this page is read from examples/project/ when the site is built, and that example is executed by npm run example: the prompt and the worklog entries are validated and the prompt's checks are run again.

This is an illustrative example. It is not one of the measured study cases; those are on the results page.

1. The request

What a person wrote, in plain language:

Request

Slugs coming out of packages/slug look wrong in the article URLs. A title like a -- b turns into a------b, and -Hello! turns into -hello-.

Please make slugify produce clean slugs: one hyphen between words, and no hyphen at the start or the end. Two tests in packages/slug/test/slug.test.mjs already describe what I expect and currently fail.

Keep it small: do not add dependencies, do not change the function's name or signature, and do not touch the tests. Other packages in this repository are out of scope.

2. The OPS prompt

The same request as a task contract. It names the workspace, states an objective that can be checked, carries the constraints, orders the work, and lists the checks that decide completion. Nothing has been changed yet at this point; the person reads this and corrects it before any code is touched.

apiVersion: guided-engineering/v1
id: slug.clean-separators
version: 1
title: Make slugify collapse repeated separators and trim hyphens at the edges
agent: guided-engineer
workspace: ./packages/slug

objective: |
  `slugify` returns clean slugs: exactly one hyphen between words and no hyphen
  at the start or the end. `slugify('a  --  b')` returns `a-b` and
  `slugify('  -Hello!  ')` returns `hello`.

context: |
  `packages/slug` is a dependency-free ES module package tested with the Node.js
  built-in test runner. `src/slug.mjs` replaces every non-alphanumeric character
  with its own hyphen, so runs of separators survive as runs of hyphens and
  leading or trailing separators stay in the result. Two tests in
  `test/slug.test.mjs` describe the expected behavior and currently fail.
  The request comes from `request.md` at the repository root.

inputs:
  - src/slug.mjs
  - test/slug.test.mjs

dependencies:
  - Node.js 20 or newer is available as `node`

constraints:
  - Change only `src/slug.mjs`.
  - Do not edit, skip, or delete any test.
  - Do not add dependencies.
  - Keep the exported name `slugify` and its single-argument signature.
  - Leave every other package in the repository untouched.

requirements:
  - id: R1
    text: Runs of separator characters collapse into a single hyphen.
  - id: R2
    text: The result never starts or ends with a hyphen.
  - id: R3
    text: Existing behavior (lowercasing, diacritic stripping) is preserved.

steps:
  - id: reproduce
    title: Reproduce the failure
    requirements: [R1, R2]
    actions:
      - Run `node --test` in the workspace and record which tests fail and with which actual values.
      - Confirm the two failing tests are the separator-collapsing and edge-trimming tests; stop if anything else fails.

  - id: fix
    title: Correct the separator handling
    requirements: [R1, R2, R3]
    actions:
      - Read `src/slug.mjs` and identify the replacement that emits one hyphen per character.
      - Change the implementation so a run of non-alphanumeric characters becomes one hyphen and hyphens at either edge are removed.
      - Keep the normalization, diacritic stripping, and lowercasing steps as they are.

  - id: verify
    title: Verify the final bytes
    requirements: [R1, R2, R3]
    actions:
      - Run `node --test` in the workspace after the last edit and record the exit code and the pass and fail counts.
      - Confirm with `git status --short` that `src/slug.mjs` is the only modified file.

output:
  - file: src/slug.mjs
    rules:
      - Exports `slugify(input)` with the same signature.
      - Uses no dependencies.

verification:
  - id: unit-tests
    expect: All four tests in `test/slug.test.mjs` pass.
    run: node --test
    requirements: [R1, R2, R3]
  - id: scope
    expect: '`src/slug.mjs` is the only file changed inside or outside the workspace.'
    requirements: [R3]

stopConditions:
  - A test other than the two described ones fails before any change is made.
  - The fix cannot be made without editing a test or adding a dependency.

limits:
  repairAttempts: 2
  timeBudgetMinutes: 15

tags:
  - example
  - bugfix
createdBy: guided-engineering

Validated with:

node dist/ops-validate.mjs --resolve examples/project/.guides/prompts/prompt.slug.clean-separators.yaml

3. The plan

Asked to plan, the agent validates the prompt, resolves where the work happens, and writes a plan in which every task has a check. A plan is recorded as a worklog entry with mode: plan, and it cannot claim that anything ran.

Plan: clean separators in slugify

The request was to plan the prompt slug.clean-separators. Nothing was executed: no step ran, no test ran and no file other than this entry changed. status: completed says only that the planning is finished.

What resolved

Validated with ops-validate --resolve, which accepted the prompt.

ReferenceResolves to
Repository rootthis example project
Workspace, the write boundarypackages/slug
Agent guided-engineerthe current executor; the agent map binds no native profile
Inputspackages/slug/src/slug.mjs and packages/slug/test/slug.test.mjs, both present
Outputpackages/slug/src/slug.mjs

Dependency: Node.js 20 or newer as node. The working tree of the example was clean when the plan was written.

Tasks

#StepFilesChangeCheck for this task
1reproducenonenonenode --test in packages/slug fails with exactly two failing tests: the one that collapses repeated separators and the one about hyphens at the edges. The other two pass.
2fixsrc/slug.mjsReplace each run of non-alphanumeric characters with one hyphen, then remove a hyphen at the start and at the end. Keep normalization, diacritic stripping and lowercasing as they are.node --test exits 0.
3verifynonenoneAfter the last edit: node --test exits 0 with four passing tests, and git status --short lists packages/slug/src/slug.mjs as the only changed product file.

Checks that decide completion

Out of scope

The tests, every other package, dependencies, and the name and signature of slugify.

Stop conditions and limits

Who planned

The session that built this repository, acting as the current executor. It followed the ops-execute procedure by reading it. The model is the one the session reports; the host does not expose its version to the session.

Next unit

Execute the prompt, on request.

4. The evidence

Asked to execute, the agent reproduces the failure, makes the change, runs the checks again after the last edit, and records what it observed. The front matter of the entry is the checkpoint and the index of evidence:

apiVersion: guided-engineering/v1
entryId: 2026-11-13.slug-clean-separators
date: '2026-11-13T19:19:40Z'
prompt:
  id: slug.clean-separators
  version: 1
  sha256: 09a3e858eeccfb4712e4a06e9cc19eb3e9b2b9cadbb481b8f76a3b4965b13cef
agent: guided-engineer
executor:
  host: claude-code
  hostVersion: UNKNOWN
  model: claude-fable-5-2
mode: execute
status: completed
steps:
  - id: reproduce
    status: done
    evidence:
      - packages/slug/test/slug.test.mjs
  - id: fix
    status: done
    evidence:
      - packages/slug/src/slug.mjs
  - id: verify
    status: done
    evidence:
      - packages/slug/src/slug.mjs
checks:
  - id: unit-tests
    result: pass
    command: node --test
    exitCode: 0
    at: '2026-11-13T19:19:11Z'
  - id: scope
    result: pass
    command: git status --short
    exitCode: 0
    at: '2026-11-13T19:19:12Z'
    evidence:
      - packages/slug/src/slug.mjs

And the readable record:

Clean separators in slugify

The request was to execute the prompt slug.clean-separators, after the plan in 2026-11-13.slug-clean-separators-plan.md.

What was done

Checks

CheckCommand or observationResultWhen
unit-testsnode --test in packages/slugexit code 0, four tests passed, none failedafter the last edit
scopegit status --short from the repository root listed packages/slug/src/slug.mjs as the only modified file; the only other new files are this entry and the plan entryas expectedafter the last edit

Failures and repairs

None. The failing run during reproduce was the expected starting state, not a failed check. No repair attempt was used.

Decisions and open questions

Who executed

The session that built this repository, acting as the current executor. It followed the ops-execute procedure by reading it. The model is the one the session reports; the host does not expose its version to the session. No one reviewed or approved this change, so the entry has no approvals.

Next unit

A person reads the diff of packages/slug/src/slug.mjs and decides whether to keep it.

5. The decision

The entry has no approvals. The agent executed and reported; whether the change is merged is a person's decision, and when it is made it is recorded as that person's, with a reference to where it was given.