Files
openprose__prose/packages/std/controls/refine.md
irl-dan 63c8ce4b23 Migrate std and co into packages/ monorepo layout
Move the standard library (previously `github.com/openprose/std`) and
the company-as-prose library (previously local dir
`/Users/sl/code/openprose/company-as-prose`) into this repository
under `packages/std/` and `packages/co/` respectively.

Motivation: concentrate attention on one repository so stars,
discussions, and issues aggregate. `openprose/std` was a genuinely
useful asset nobody could find because ~50 stars on its own repo
told a much worse story than 1,106 stars on `openprose/prose`
would have. Same logic applies to co.

Layout choice: `packages/{std,co}/` rather than `std/` + `co/` at
the repo root. Root siblings accumulate over time, and a flat
top-level made future libraries (hub, kit, dev, etc.) compete with
spec infrastructure. `packages/` is bounded — new libraries land
there without cluttering root. Matches pnpm/Deno/monorepo tooling
conventions.

Changes:

- New: `packages/std/` (copied from openprose/std, `.git` excluded)
- New: `packages/co/` (copied from company-as-prose, README updated
  for new name and location)
- `packages/std/README.md`: updated shorthand expansion reference
- `packages/co/README.md`: renamed "company-as-prose" to "co" in
  self-references, added std-vs-co split heuristic, updated
  `prose run` examples to use `co/` shorthand
- `skills/open-prose/deps.md`:
  - `std/` shorthand now expands to
    `github.com/openprose/prose/packages/std/`
  - `co/` shorthand added, expands to
    `github.com/openprose/prose/packages/co/`
  - Both shorthands resolve into the same clone of
    `openprose/prose` under `.deps/github.com/openprose/prose/`;
    `packages/std/` and `packages/co/` are sibling subdirectories
  - `prose.lock` format row updated to `host/owner/repo sha`
    (matches the explicit-host resolution that landed in #35)
  - `.deps/` directory structure example redrawn to show the
    `{host}/{owner}/{repo}/packages/{std,co}/...` shape
  - Error message and Interaction tables refreshed accordingly
  - Resolution Algorithm step 1 now documents both shorthands
- `skills/open-prose/forme.md`: Step 2 resolution list updated to
  include co/ shorthand and the host-keyed `.deps/` layout
- `skills/open-prose/help.md`: Q&A "How do dependencies work?"
  rewritten to name both shorthands and the new explicit-host model
- `skills/open-prose/state/filesystem.md`: `.deps/` directory
  tree re-drawn to include the `{host}/` layer with std/co as
  sibling packages inside the clone
- `skills/open-prose/guidance/patterns.md`,
  `skills/open-prose/guidance/antipatterns.md`: examples now use
  the `std/` shorthand or explicit `github.com/...` rather than
  the deprecated bare `openprose/std/` form
- `skills/open-prose/examples/registry-import/index.md`: sample
  service reference switched to `std/evals/inspector`
- `README.md`: Stdlib badge replaced with internal `packages/std/`
  link plus new `packages/co/` link; "Standard Library" section
  rewritten as "Libraries" with both packages described

Out of scope for this PR (deliberately):
- Tooling changes to `prose install` and Forme's `.deps/` writer
  to adopt the `{host}/{owner}/{repo}/` layout in practice — this
  PR is spec-only. Existing tooling continues to work against
  whatever layout it currently implements; the spec now describes
  the target.
- Retiring the `openprose/std` GitHub repo. Delete that repo
  separately after this merges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:14:31 -07:00

96 lines
3.3 KiB
Markdown

---
name: refine
kind: composite
---
# Refine
Iteratively improve a result through delegation rounds until a quality threshold is met.
### Metadata
- `version`: 0.2.0
- `role`: coordinator
### Runtime
- `state.reads`: &controlState
- `state.writes`: &controlState
### Slots
- `refiner`
- `evaluator`
### Shape
- `self`: manage refinement rounds, pass evaluator feedback to refiner
- `delegates`:
- `refiner`: produce or improve a result
- `evaluator`: score the result 0..1 and suggest improvements
- `prohibited`: none
### Requires
- &controlState exists at __controlState with:
refiner: string -- component name for the refiner
evaluator: string -- component name for the evaluator
task_brief: string -- the task
max_rounds: number -- (optional, default 3)
threshold: number -- (optional, default 0.8) score at which to stop
### Ensures
- Round 1: refiner produces initial result from the task brief
- Evaluator scores the result (0..1) and provides specific improvement suggestions
- If score >= threshold: return immediately
- If score < threshold: refiner receives the result, score, and suggestions
- Each round accumulates improvement — refiner sees its own prior output
- Returns when threshold met or max_rounds exhausted
- &controlState.result contains the final output
- &controlState.score contains the final score
- &controlState.rounds_used contains the number of rounds
### Delegation Loop
```javascript
const { refiner, evaluator, task_brief, max_rounds = 3, threshold = 0.8 } = __controlState;
let currentResult = null;
let currentScore = 0;
let roundsUsed = 0;
for (let round = 0; round < max_rounds; round++) {
roundsUsed = round + 1;
// Refiner produces or improves
let refinerBrief = round === 0
? task_brief
: `Improve this result. Current score: ${currentScore}.\n\nOriginal task: ${task_brief}\n\nCurrent result:\n${currentResult}\n\nImprovement suggestions:\n${__controlState._lastSuggestions}`;
currentResult = await rlm(refinerBrief, null, { use: refiner });
// Evaluator scores
const evalBrief = `Score this result from 0 to 1 and provide specific improvement suggestions.\n\nTask: ${task_brief}\n\nResult:\n${currentResult}`;
const evaluation = await rlm(evalBrief, null, { use: evaluator });
// Parse score from evaluation
const scoreMatch = String(evaluation).match(/(\d+\.?\d*)/);
currentScore = scoreMatch ? parseFloat(scoreMatch[1]) : 0;
if (currentScore > 1) currentScore = currentScore / 100; // handle percentage
__controlState._lastSuggestions = evaluation;
if (currentScore >= threshold) break;
}
__controlState.result = currentResult;
__controlState.score = currentScore;
__controlState.rounds_used = roundsUsed;
return(currentResult);
```
### Notes
The refiner does not know it is in a refinement loop. The evaluator does not know its score controls iteration.
Different from `retry-with-learning`: refinement improves work that is mediocre — the result exists but is not good enough. Retry-with-learning recovers from failure — the result is broken or absent. Refinement uses a continuous quality score (0..1) and improvement suggestions. Retry uses binary failure detection and failure analysis. A result that scores 0.4 needs refinement. A result that throws an error or returns nothing needs retry.