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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ workflow even when no native skill creator or repository validator is installed.
- `scripts/install.mjs` stages, validates, and commits an installation.
- `scripts/remote-install.mjs` stages and transfers an SSH environment install.
- `scripts/validate.mjs` checks inventory, frontmatter, links, and portability.
- `scripts/check-harness-policy.mjs` validates a business repository's mixed
pstack/mstack policy and detects duplicate verification maps.
- `.codex-plugin/` packages the same skill tree for Codex.

The installer stages every selected skill, applies its adapter, validates the
Expand All @@ -320,6 +322,22 @@ uses the current harness's adapter instead of naming one vendor's commands.

Run `node scripts/validate.mjs` to print the validated skill count.

For a business repository that mixes pstack and mstack, initialize its shared
project workflow from this checkout:

```bash
node <mstack-checkout>/scripts/check-harness-policy.mjs init --root <project> --app web --check 'node --test' --pstack <exact-pstack-commit>
```

Replace the app, check command, and pstack revision with the project's values.
Initialization exports `.harness/check.mjs` and its library for committed CI
checks, without requiring an unpublished npm version. It leaves the application
contract for `/create-verification-skill` to create or migrate and prove. See
[mixed-Harness adoption](./docs/guide/11-mixed-harness.md) for wrapper generation,
receipts, repository protection, and reviewed checker upgrades. After a release
includes this CLI, use its exact package version for initialization and run
recording.

To validate and print a user's model configuration, run:

```bash
Expand Down
8 changes: 7 additions & 1 deletion automations/benny/FOR_AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ i want two cursor automations that work together in one slack issue channel.
- budgets: `<polling, verdict wait, follow-up, repro, rejection, fix>`
- optional bot token capability: `<none, file download, or editable operations status>`

start from [`configuration.example.yaml`](./templates/configuration.example.yaml) and [`feature-map.example.md`](./skills/reproduce-and-fix-issues/references/feature-map.example.md). copy and fill them outside this pack, for example under `.cursor/benny/`. keep secret values in a secret manager or environment.
start from [`configuration.example.yaml`](./templates/configuration.example.yaml).
copy and fill the configuration outside this pack, for example under
`.cursor/benny/`. when the project has a shared contract, set the feature-map
path to `.harness/verify/<app>/features/README.md`. read its linked feature files
and app contract instead of creating a benny-only map. use
[`feature-map.example.md`](./skills/reproduce-and-fix-issues/references/feature-map.example.md)
for the required content. keep secret values in a secret manager or environment.

## for the agent

Expand Down
2 changes: 1 addition & 1 deletion automations/benny/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ the files in this directory are dormant setup and automation sources. they do no
}
```

4. keep user-owned configuration outside the copied pack, for example in `.cursor/benny/`. adapt [`configuration.example.yaml`](./templates/configuration.example.yaml) and [`feature-map.example.md`](./skills/reproduce-and-fix-issues/references/feature-map.example.md).
4. keep user-owned configuration outside the copied pack, for example in `.cursor/benny/`. adapt [`configuration.example.yaml`](./templates/configuration.example.yaml). point `control.feature_map_path` at `.harness/verify/<app>/features/README.md` when the project has a shared verification contract. benny reads the linked feature files and the same contract as other Harnesses. use the [map example](./skills/reproduce-and-fix-issues/references/feature-map.example.md) for required content, not a second copy of project facts.
5. commit `.cursor/settings.json`, `.cursor/automations/benny/`, and any secret-free configuration before enabling either automation.
6. review each new automation draft or update existing automations in their editors. then send a harmless test report and verify every source-channel post stays in the original thread.
22 changes: 19 additions & 3 deletions automations/benny/skills/reproduce-and-fix-issues/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Wait for a trusted triage marker in the source thread. Reproduce the exact sympt

Load the external Benny configuration supplied by the automation. If the config, required actions, control adapter, or completed feature map is missing, fail closed.

Read `AGENTS.md` and `.harness/workflow.md` when present. Use the shared project
workflow for writable worktree isolation, declared revisions, and evidence.
Resolve `.harness/policy.json` before selecting an app map. The automation's
configuration must point at that app's canonical feature index. Report a stale
or conflicting map instead of silently following it.

## Hard safety rules

- Freeze the source channel and root thread coordinates before doing any work.
Expand Down Expand Up @@ -125,9 +131,16 @@ If no operations channel is configured, keep detailed status in the automation r

## 5. Load and check the control adapter

Read `references/control-adapter.md` and the completed map at `control.feature_map_path`, then invoke the skill named by `control.skill_name`.
Read `references/control-adapter.md` and the completed map at
`control.feature_map_path`, then invoke the skill named by `control.skill_name`.
For a canonical `features/README.md`, read the matching linked feature file and
its app's `contract.md`. Resolve a wrapper's `metadata.verification-contract`
from the repository root. Adapt the contract to the available driver without
creating a second map or changing the required proof.

Find the feature-map section that matches the reported user path. Read it before driving the app. If no section covers the feature, mark the run blocked instead of inventing a path or selector.
Find the mapped feature that matches the reported user path. Read it before
driving the app. If no entry covers the feature, mark the run blocked instead of
inventing a path or selector.

Require all seven capabilities:

Expand Down Expand Up @@ -286,7 +299,10 @@ Run focused tests, then smoke the blast radius around the changed behavior. Cove
Only after before-and-after proof:

- Review the final diff for unrelated changes and secrets.
- Run the repository's required checks.
- Run the repository's required checks. When `.harness/policy.json` exists,
follow `.harness/workflow.md` to record the final commit and canonical feature
evidence. Include the receipt and retained artifacts in the review handoff.
Passing commands alone do not prove the reported UI behavior.
- Create small ordered commits when the repository workflow allows it.
- Open a draft pull request. Never merge or deploy from this workflow.
- Link the configured tracker issue using the tracker's supported pull request syntax.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,20 @@ Benny does not know how to start or drive every app. The user must configure one

Set its skill name in `control.skill_name`.

Set the completed user-facing feature map path in `control.feature_map_path`. Copy and fill [`feature-map.example.md`](./feature-map.example.md) outside `.cursor/automations/benny/` instead of editing the copied example.
Set `control.feature_map_path` to the app's canonical feature index, such as
`.harness/verify/web/features/README.md`, when the repository uses a shared
project contract. Load its linked feature files and adjacent `contract.md`.
The control skill may be a neutral `verify-<app>` wrapper that resolves
`metadata.verification-contract` from the repository root.

Keep driver-specific capability adaptation in the installed control skill.
Launch commands, fixtures, user paths, expected results, and cleanup belong to
the canonical contract. Do not copy them into Benny configuration.

For a legacy project without a shared policy, an existing completed external
map can remain until migration. The [map example](./feature-map.example.md)
describes the required content. Keep any user-owned map outside the copied
pack, and replace it with the canonical index during mixed-Harness adoption.

If the skill, feature map, or a required capability is absent, ambiguous, or incomplete, repro and fix work must fail closed.

Expand Down Expand Up @@ -52,7 +65,8 @@ Do not set internal state, call hidden app methods, write directly to storage, o

### Drive mapped features and states

Read the relevant feature-map section before driving the app.
Read the relevant feature file or legacy map section before driving the app.
An index is a list of links, not the complete feature definition.

The adapter must expose ways to:

Expand Down Expand Up @@ -134,7 +148,8 @@ The adapter must:
- Surface startup failures as failures.
- Bound retries.
- Keep secrets out of logs and artifacts.
- Keep captures outside the repository.
- Keep captures outside tracked source. A shared project's ignored artifact
location can hold files referenced by its run receipt.
- Support a fresh or reset state between the two repro attempts.
- Avoid production changes unless the user explicitly configured a safe test action.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# Feature-map example

In a project with `.harness/policy.json`, use these fields to complete the
canonical feature files under `.harness/verify/<app>/features/`. Set Benny's
`control.feature_map_path` to their `README.md` index. Do not create a separate
Benny map. This single-file example also describes legacy maps used before
shared-project adoption.

Map every user-facing feature Benny may reproduce. Read the relevant section before driving the app. Keep this map at the user point of view. Discover internals and current code paths at runtime instead of freezing them here.

Copy this file outside `.cursor/automations/benny/`, for example to `.cursor/benny/feature-map.md`, and set `control.feature_map_path` to the copy. Pack refreshes must not overwrite it.
For a legacy project without a shared contract, copy this file outside
`.cursor/automations/benny/`, then set `control.feature_map_path` to the completed
copy. Pack refreshes must not overwrite it. During mixed-Harness migration,
move its reconciled facts to the canonical feature files and retire the copy.

## Per-feature template

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Use regular `github.com` pull request links.

## Measure the baseline

Load the shared project workflow and canonical contract when present. Resolve
the configured feature index to the matching feature file. Give baseline and
patched builds separate instance state as the contract requires, and identify
each tested commit in the evidence. If an older revision lacks the mapped path,
report that limitation rather than applying the current map without checking.

For an open pull request, use its base branch as the baseline.

For a merged fix, use the revision immediately before the fix when that revision builds and represents the old behavior.
Expand Down
37 changes: 31 additions & 6 deletions automations/benny/skills/setup-benny/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,35 @@ Open these copied examples:
Create user-owned copies outside `.cursor/automations/benny/`. These are configuration files, not pack files. Example locations:

- Project config, such as `.cursor/benny/configuration.yaml`
- Project feature map, such as `.cursor/benny/feature-map.md`
- Canonical feature index, such as `.harness/verify/web/features/README.md`
- Project routing map, such as `.cursor/benny/routing.md`
- User config, such as `~/.config/benny/configuration.yaml`
- User feature map, such as `~/.config/benny/feature-map.md`
- Legacy user feature map, when the project has no shared contract

Fill one feature-map section for every user-facing feature the automation may reproduce. Keep it at the user point of view. Do not freeze implementation details or current code paths in the map.
When the project has `.harness/policy.json`, read `.harness/workflow.md` and
select its canonical app. Set `control.feature_map_path` to that app's
`features/README.md`. Read the linked feature files and the adjacent
`contract.md`. Reuse them instead of making a Benny-only copy. The configured
control skill supplies the available driver and follows that contract.

When canonical verification does not exist, use `/create-verification-skill` to
create or migrate it as part of authorized verification setup. A legacy project
without a shared policy may keep an existing completed external map until it
migrates. Never keep both definitions active after adoption.

Map every user-facing feature the automation may reproduce. Keep user paths and
expected observations in the canonical feature files. Discover implementation
paths from source when investigating a report.

Do not edit the copied examples. Pack refreshes may update source-managed files after conflict review, but they must never touch the user-owned copies.

Prefer committed, secret-free files in the target repository when a fresh automation checkout must read them. Otherwise paraphrase the required values into the live prompt. Reference a repository file only after the built-in `/automate` skill confirms that the file is committed in the repository where the automation runs.
Require the shared project workflow, canonical contract, and feature files to
be committed before enabling an automation that uses them. Reference their
repository paths instead of paraphrasing project facts into the prompt. For
configuration unrelated to verification, prefer committed, secret-free files
when a fresh automation checkout must read them. Otherwise paraphrase the
required values. Reference a repository file only after the built-in
`/automate` skill confirms that it is committed in the automation repository.

Use stable repository-relative paths for committed pack and configuration files. Never reference the plugin source directory or a plugin cache path from a live automation.

Expand Down Expand Up @@ -150,7 +169,10 @@ If no routing map is configured, triage may classify a report but must not guess

## 6. Verify the control adapter

Read `../reproduce-and-fix-issues/references/control-adapter.md` and the user's completed feature map.
Read `../reproduce-and-fix-issues/references/control-adapter.md` and the user's
completed feature map. For a canonical index, load every linked feature file
and its adjacent app contract. Verify that the configured map agrees with the
project policy. Run the policy check when present.

Confirm that the named skill can:

Expand Down Expand Up @@ -204,7 +226,10 @@ After the triage editor handoff is complete, give `automate` this complete repro
- Trigger on the same new top-level reports in the configured source Slack channel.
- Use the configured repository and default branch.
- Read the source thread and reply only inside it.
- Include pull request creation and the configured tracker, control-adapter, and feature-map requirements. Paraphrase mapped user paths and states unless `automate` confirms an eligible committed file in the same repository.
- Include pull request creation and the configured tracker, control-adapter,
and feature-map requirements. For a shared project contract, require its
committed canonical paths. For a legacy project, paraphrase mapped user paths
only when `automate` cannot reference an eligible committed map.
- Wait for a trusted triage marker before acting.
- Reproduce the exact symptom twice through the mapped real UI and capture evidence.
- Verify an existing fix without authoring over it.
Expand Down
2 changes: 1 addition & 1 deletion automations/benny/templates/configuration.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ routing:

control:
skill_name: "control-target-app"
feature_map_path: ".cursor/benny/feature-map.md"
feature_map_path: ".harness/verify/web/features/README.md"
environment: "safe-test-environment-placeholder"
artifact_directory: "/tmp/benny-artifacts"
artifact_retention_hours: 24
Expand Down
5 changes: 5 additions & 0 deletions automations/benny/templates/reproduce-automation-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ Trigger:

The creation intent should describe this as a new top-level report in the configured source Slack channel. It should include the configured repository, default branch, issue tracker, control adapter, feature map, and draft pull request capability.

When the repository has `.harness/policy.json`, include the instruction to read
`.harness/workflow.md` and use its canonical app contract. The configured
feature-map path must be that app's `features/README.md`; load its linked files
before driving. Keep the prompt as an entry pointer rather than a copied map.

Treat the source channel and root thread timestamp as immutable. If either is missing or does not match configuration, stop without posting.

Wait for a configured triage marker from the configured triage identity in this exact thread. Proceed only for `[benny:bug]` or `[benny:performance]`.
Expand Down
6 changes: 4 additions & 2 deletions docs/guide/01-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ Use `inherit-parent` for the current chat model through the Harness's documented

## Accept the verification offer, or don't

At the end of setup, `/setup-mstack` looks for a way to prove app behavior in your project, either a `verify-*` skill or an existing harness. If it finds neither, it offers once to generate one with [`/create-verification-skill`](../../skills/create-verification-skill/SKILL.md).
At the end of setup, `/setup-mstack` looks for a shared verification contract, a `verify-*` wrapper, or an existing repository driver. Several wrappers pointing at one contract count as one workflow. Setup reports conflicting legacy definitions instead of creating another copy.

Say yes and it writes `verify-<app>/` under the active Harness's project skill root. See [the project skill paths](../../skills/create-verification-skill/references/harness-paths.md) for the root used by each Harness. The generated skill teaches agents to drive your app the way a user does, and setup proves it once before handing it over. Say no and setup moves on. You can run `/create-verification-skill` yourself any time. [Verify and ship](./06-verify-and-ship.md#create-a-project-verification-skill) covers when it earns its place.
If it finds neither a reusable verification workflow nor a repository driver, setup offers once to run [`/create-verification-skill`](../../skills/create-verification-skill/SKILL.md). When you accept, the generator writes `.harness/verify/<app>/contract.md`, its feature map, and thin discovery wrappers. It proves one feature in the real app before handing over the result. Model setup alone does not start the app or create a team policy.

You can run `/create-verification-skill` yourself any time. [Verify and ship](./06-verify-and-ship.md#create-a-project-verification-skill) covers the proof. For a team using both native pstack and mstack, follow [the mixed-Harness adoption guide](./11-mixed-harness.md) to add the shared project workflow and CI checks.

After setup, start a new session. The model configuration applies to new sessions.

Expand Down
Loading