feat: add guided prose compose package

This commit is contained in:
irl-dan
2026-08-27 15:59:31 -04:00
parent 2c338823f3
commit cfd9623fa7
18 changed files with 1364 additions and 10 deletions
+4 -1
View File
@@ -1,6 +1,6 @@
# OpenProse for Codex
If you're running in Codex and see a `prose` command, a `*.prose.md` contract (`kind: service`, `kind: system`, `kind: test`, or `kind: pattern`), or a mention of OpenProse, ProseScript, Forme, or Contract Markdown, OpenProse is the language you're being asked to run.
If you're running in Codex and see a `prose` command, a `*.prose.md` contract (`kind: responsibility`, `kind: function`, `kind: gateway`, `kind: test`, or `kind: pattern`), or a mention of OpenProse, ProseScript, Forme, or Contract Markdown, OpenProse is the language you're being asked to run.
Treat `prose run ...` as an instruction inside the current agent session. Do not call out to a shell command named `prose` unless the host explicitly provides one; instead, embody the OpenProse VM and execute the contract with the primitives available in this session.
@@ -8,6 +8,9 @@ Use `prose upgrade --dry-run` to preview legacy migrations and `prose upgrade` t
Open `skills/open-prose/SKILL.md` and treat it as the authoritative router. Every command, every file routing decision, and every capability assumption lives there or behind a pointer inside it. Do not search the workspace for alternate copies of the OpenProse documentation — the canonical files are the ones bundled under `skills/open-prose/`.
Use `prose init` and `prose compose` for progressive program architecture; use
`prose write` for focused authoring when one Contract is already understood.
If your run exposes a concrete improvement to OpenProse itself, consider
`prose run std/evals/prose-contributor -- subjects: <run-ids>`. It turns run
evidence into one focused draft PR. It still needs explicit user approval before
+11
View File
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- **`prose init` and `prose compose` now provide guided, progressive program
architecture.** The obligation-centered `std/ops/compose` directory package
keeps the architect focused on a bounded conceptual frontier, materializes
settled decisions into one canonical Contract package, derives a disposable
visual view, and creates semantic tests outside-in from the package promise
through Contract boundaries, failure behavior, harness portability, and
performance. Framework pressure discovered during composition is routed to
deduplicated public issues rather than implemented in the target program.
## [0.16.0] - 2026-08-24 — open-prose skill & plugin
Skill/plugin-track release. This repository is now OpenProse only — the
+5
View File
@@ -34,6 +34,11 @@ npx skills add openprose/prose
That installs OpenProse into any Prose-Complete coding agent (Claude Code, Codex CLI, OpenCode, and friends). From there, point your agent at a contract and say `prose run <file>`: the session itself embodies the VM; there is no separate binary. The [`examples/`](skills/open-prose/examples/) directory is the tour; start small and read the contract before you run it.
For a new program, say `prose init`, then use `prose compose` to shape its
purpose, topology, Contract boundaries, and outside-in semantic tests. Compose
progressively materializes one directory package; use `prose write` when a
single Contract is already understood and needs focused authoring.
Your first contract is a Markdown file away: `kind: responsibility` frontmatter, a `### Goal` that states what should stay true, and the sections below. The skill teaches your agent the rest.
## The language: Responsibilities
+2
View File
@@ -7,6 +7,7 @@ Reusable OpenProse functions, responsibilities, patterns, roles, delivery adapte
```prose
use "std/evals/inspector"
use "std/evals/prose-contributor"
use "std/ops/compose"
use "std/ops/prose-author"
use "std/patterns/worker-critic"
use "std/patterns/pipeline"
@@ -47,6 +48,7 @@ Operational contracts for profiling, debugging, validation, and wiring.
| Contract | Purpose |
|---------|---------|
| `compose` | Progressively design, test, visualize, and materialize one canonical OpenProse directory package |
| `lint` | Validate structure, schema, shapes, and contract consistency for a contract and its sub-unit tree |
| `preflight` | Check that all runtime dependencies are satisfied before executing a contract |
| `status` | Summarize recent runs from `<openprose-root>/runs/` |
+8
View File
@@ -11,10 +11,18 @@ shape/root questions before authoring. The shell CLI wrapper passes request
text up front and marks the run non-interactive, so missing blocking decisions
come back as `unresolved-intent` instead of terminal prompts.
The `compose/` directory package powers `prose compose` and the architectural portion of
`prose init`. It maintains a small human-facing architectural frontier,
triangulates it with orthogonal constraints, and progressively materializes the
resolved design into one canonical Contract package plus an outside-in test
ladder. It routes OpenProse framework pressure to deduplicated public issues
rather than changing the framework during composition.
## Systems
| System | CLI Command | Description |
|---------|-------------|-------------|
| `compose/` | `prose init` / `prose compose [request...]` | Guided Contract composition with progressive source, semantic tests, visual projection, and issue-routed OpenProse feedback |
| `lint.prose.md` | `prose lint <file>` | Validate structure, schema, shapes, and contract matching |
| `preflight.prose.md` | `prose preflight <file>` | Check that dependencies are installed and environment variables are set |
| `wire.prose.md` | `prose run std/ops/wire` | Run Forme wiring to produce an execution manifest |
@@ -0,0 +1,378 @@
---
name: architecture-designer
kind: function
version: 0.16.0
---
# Architecture Designer
Update the program architecture from the known intent and elicited decisions.
### Parameters
- `current`: prior architecture
- `request`: current request
- `elicitation`: new answers and decisions
- `exploration`: orthogonal constraint analysis
- `topology`: selected whole-system and regional topology profiles, including
their lowering into existing OpenProse mechanisms
- `test_intent`: public promise, prohibited outcomes, and representative
scenarios that the architecture must make testable
- `mental_model_sync`: shared working model used for the decision
- `landscape`: source and runtime facts
### Returns
- `candidate`: proposed architecture, change set, Contract proposals, source
mismatches, scenarios, and next actions
### Strategies
- Give each Contract a one-line promise before detailing procedure.
- Use package-level test intent to challenge decomposition. Every important
observable must have an owner and every prohibited outcome an enforceable
boundary.
- Choose Contract boundaries in light of the selected topology; do not choose a
topology merely to rationalize boundaries already invented.
- Allow different named regions to use different profiles. Treat a hybrid as a
composition of explicit regional profiles, not as an uninformative catch-all.
- Record call edges separately from data, state, and capability edges.
- Name each data edge as `Return.field -> Parameter.field` when known.
- Preserve distinctions between current source, proposed architecture, and
discovered candidate procedure.
- Use the source projector for progressive whole-program source; recommend
`prose write` when one Contract needs focused authoring outside this cycle.
- Recommend `prose compile` only after blocking architectural gaps are closed.
---
## architecture-landscape-scanner
Read the local OpenProse landscape without changing it.
### Parameters
- `request`: current user request
- `subjects`: optional run or source references
### Returns
- `landscape`: OpenProse root, architecture files, source files, compiled
manifests, recent relevant runs, installed standard-library index, harness
configuration, and facts relevant to the current request
### Invariants
- Read-only.
- Prefer focused files and indexes over loading the entire repository.
- Do not treat generated manifests or runtime traces as authored intent.
---
## architecture-loader
Reconstruct the working architecture from the existing program package and its
supporting decision history, or establish an empty bootstrap model.
### Parameters
- `landscape`: scanner output
- `mode`: requested Architect mode
### Returns
- `current`: normalized projection of package source, decisions, assumptions, open
questions, prior feedback candidates, frozen source facts, and discovered
procedure candidates
### Strategies
- Treat the target directory package's `index.prose.md` and nearby Contract
files as the canonical current architecture.
- Use `<openprose-root>/architecture/decisions.md` for durable decisions and
rejected alternatives.
- Use `<openprose-root>/architecture/openprose-feedback.md` for candidate
framework feedback.
- Treat decision and feedback records as provenance, never as overrides for
Contract source.
- If the target package does not exist in `bootstrap` mode, return an empty
model so the source projector can establish its `index.prose.md`; do not
invent its contents here.
---
## architecture-gap-modeler
Find the highest-value unknowns in the current architecture.
### Parameters
- `request`: current design request
- `current`: loaded architecture
- `landscape`: local facts
- `framework_maturity`: current OpenProse maturity
### Returns
- `gaps`: ranked unknowns across desired render, inputs, Contract promises,
interfaces, context exclusions, state ownership, capabilities, composition,
failure behavior, evidence, and harness requirements
### Strategies
- Rank gaps by how many downstream decisions they affect.
- A missing desired render outranks naming and file-layout questions.
- A disputed Contract boundary outranks procedure details inside either side.
- Record possible framework pressure, but do not classify it here.
---
## architectural-frontier-selector
Limit the human-facing design surface without limiting internal exploration.
### Parameters
- `gaps`: ranked architecture gaps
- `current`: current architecture and constraint lattice
- `request`: current user direction
### Returns
- `active_frontier`: one to three concepts containing:
- concept and current architectural level
- why it is active now
- settled constraints that bound it
- orthogonal axes still needed to triangulate it
- decision that would close or materially narrow it
- `deferred_frontier`: important concepts intentionally kept outside the
current human working set, each with the decision or event that should bring
it back
### Invariants
- Never expose more than three active concepts.
- Prefer one concept when it dominates downstream architecture.
- Deferring a concept preserves it; it does not silently resolve or discard it.
- Before opening a new concept, resurface any deferred commitment whose return
condition has been met.
- A settled decision with an unperformed materialization step outranks a new
design question. Perform or explicitly block the step first.
---
## orthogonal-constraint-explorer
Explore each active concept from independent axes so one decomposition does not
run away with the design.
### Parameters
- `frontier`: active architectural concepts
- `current`: current architecture and constraints
- `landscape`: local source, standard-library, harness, and evidence facts
### Returns
- `exploration`: for each active concept:
- independent conceptual fan-outs
- agreements and contradictions among them
- orthogonal constraint seeds such as desired render, information boundary,
state ownership, authority, failure behavior, cost, portability, and UX
- option set that efficiently partitions the remaining concept space
- recommendation with uncertainty, never a hidden decision
### Strategies
- Many agents may investigate one conceptual task; do not confuse agent count
with conceptual breadth.
- Use no more than three conceptual fan-outs at once.
- Give parallel investigators distinct axes rather than near-duplicate briefs.
- Fan in before opening another conceptual task.
---
## topology-profile-selector
Select an architectural shape only after the purpose, desired render, and
load-bearing constraints are understood, and before Contract decomposition is
allowed to harden.
### Parameters
- `current`: current architecture and any prior topology selections
- `request`: current design request
- `elicitation`: newly resolved context and constraints
- `exploration`: orthogonal options and tradeoffs
- `landscape`: installed standard-library patterns, topology guidance, and
canonical examples
### Returns
- `topology`: one or more named regions containing:
- selected topology profile and status: `proposed` or `settled`
- context signals and counter-signals supporting the selection
- compact ASCII shorthand using the profile's standard notation
- likely Contract boundaries and state ownership
- lowering plan using only existing mechanisms: ProseScript `call`, a
`pattern:` instance, or `Requires``Maintains` subscriptions
- compatible nested profiles and relevant standard-library patterns
- canonical examples and unresolved topology questions
### Strategies
- Load topology profiles through progressive disclosure: show a one-line name,
thumbnail, and fit statement first; load full guidance only for plausible
candidates.
- Distinguish architectural levels instead of placing every shape in one flat
list. A pipeline is usually intra-render coordination; a reactive renderer is
a lifecycle and state model; a bus is an integration shape; fan-out/fan-in is
a coordination shape.
- Prefer small labeled diagrams over symbolic shorthand. The diagram should say
what moves, why a branch exists, and where results meet. For example:
Pipeline
[Research] -> [Draft] -> [Review]
Fan out, then combine
+-> [Security review] -+
[Change request] -+-> [API review] ------+-> [Combined findings]
+-> [UX review] -------+
Maintain a projection when its inputs change
[New event or changed input] -> [Render Contract] -> [Updated projection]
^ |
+-- future change ---+
Publish once, deliver to interested Contracts
+-> [Billing Contract]
[Incoming event] -> [Topic] -> [Analytics Contract]
+-> [Notification Contract]
- Names such as `A`, `B`, and `topic` are acceptable only after the architect
already knows what they denote. The first disclosed view uses domain labels,
not notation that requires a legend.
- Prefer ordinary relationship words such as `calls`, `publishes`, `updates`,
and `combines` when arrows alone leave the semantics ambiguous.
- Treat the ASCII view as a mental-model thumbnail, not source or executable
syntax. It must expand into named Contracts and typed relationships before
source projection.
- Store reusable architecture profiles separately from executable coordination
patterns. Profiles may recommend and link to patterns; they do not execute.
- Do not introduce runtime semantics for a profile annotation. Record language
pressure only if repeated programs cannot lower the profile faithfully into
calls, patterns, and subscriptions.
---
## architecture-critic
Stress-test the proposed program without broadening it.
### Parameters
- `candidate`: proposed architecture
- `test_suite`: ordered package and Contract tests
- `landscape`: local facts
- `subjects`: optional run evidence
### Returns
- `program_diagnostics`: ranked findings with affected Contract or edge,
evidence, consequence, and smallest corrective decision
### Strategies
- Check that every Contract boundary earns its cost.
- Check that the package-level tests observe public behavior rather than
implementation trivia, and that Contract tests align with their declared
promises.
- Check that every required Return has a consumer or top-level purpose.
- Check for ambient context, authority widening, shared mutable scratch,
coordinator collapse, implicit joins, ambiguous state ownership, and missing
failure paths.
- Distinguish static architecture findings from observed runtime failures.
- Do not turn style preferences into blocking diagnostics.
---
## architecture-renderer
Render one coherent architecture update and its derived visual map.
### Parameters
- `candidate`: proposed architecture
- `critique`: program diagnostics
- `feedback`: classified OpenProse feedback
- `test_suite`: ordered tests and current readiness gates
### Returns
- `architecture`: complete human-readable architecture
- `constraint_lattice`: settled, provisional, disputed, and superseded
constraints with their relationships and evidence
- `architecture_changes`: focused change list
- `contract_proposals`: source-level changes, with materialization status
- `visual_map`: Mermaid Contract graph derived from the architecture
- `next_actions`: no more than three ordered actions
### Strategies
- Keep the default Contract map readable; split call/data, state, capability,
and runtime views when one graph would become ambiguous.
- Mark proposed Contracts and edges differently from frozen source.
- Include unresolved questions near the affected Contract or relationship.
- Do not include raw transcript or scratch in the architecture.
---
## architecture-persister
Persist only Compose-owned architecture and source projections.
### Parameters
- `rendered`: rendered architecture and feedback
- `source_projection`: progressive Contract source
- `visual_artifact`: derived HTML architecture view
- `persistence`: `persist` or `preview`
- `landscape`: root and existing architecture files
### Returns
- `final_status_summary`: status, mode, persistence result, architecture files
updated, Contracts proposed, unresolved decisions, feedback candidates, and
next action
### Errors
- `persistence-failed`: an owned file could not be written
### Strategies
- In `preview`, return the complete proposed contents and write nothing.
- In `persist`, update the canonical target directory package first:
- `<program-root>/index.prose.md`
- `<program-root>/*.prose.md` for Compose-managed child Contracts
- Then update supporting, non-authoritative records:
- `<openprose-root>/architecture/decisions.md`
- `<openprose-root>/architecture/openprose-feedback.md`
- `<openprose-root>/architecture/view.html`
- Persist resolved and explicitly provisional Compose-managed source in the
target package. Ask before changing a human-frozen region or public promise.
- Keep system-level intent, desired renders, topology, and composition in the
root Contract without duplicating child Contract promises. Keep unresolved
decisions as explicit provisional markers beside the source they affect.
- Mark every Contract and relationship as `proposed`, `frozen-source`, or
`observed-runtime` so design intent and evidence cannot blur together.
- Keep each decision in `decisions.md` under a stable `ARCH-*` identifier with
status, decision, rationale, alternatives, evidence, and affected Contracts.
- Keep each framework feedback record in `openprose-feedback.md` under a stable
`OPF-*` identifier using the complete top-level feedback schema.
- Treat `view.html` as generated and replaceable; never recover canonical
architecture from it.
- Preserve user-authored notes and prior decisions; append or revise by stable
heading rather than replacing the files wholesale.
- Deduplicate feedback records by observation, layer, and affected construct.
- Report every source file and region changed, including its provenance and
whether it remains provisional.
@@ -0,0 +1,41 @@
---
name: test-compose-maintains-architectural-thread
kind: test
version: 0.16.0
subject: compose
---
# Compose Maintains The Architectural Thread
### Fixtures
- `mode`: compose
- `interactive`: true
- `persistence`: preview
- `authority_scope`: openprose-maintainer
- `framework_maturity`: experimental
- `request`: |
The architect previously selected an obligation-centered directory package,
then explored topology guidance and supplied framework feedback. Continue
from the settled package decision without losing the topology findings.
### Expects
- `mental_model_sync`: identifies the obligation-centered package as settled
- `active_frontier`: resurfaces its pending materialization before opening a new
conceptual frontier
- `source_projection`: contains `index.prose.md` plus obligation-owned sibling
Contracts
- `test_strategy`: begins with the package promise and orders later testing
through Contract boundaries, interaction topology, failure behavior, harness
portability, and only then performance
- `openprose_feedback`: preserves topology and package-visibility framework
pressure separately from program architecture
### Expects Not
- `next_actions`: asks the architect to reconfirm the settled package decision
- `source_projection`: modifies topology profiles, language documentation,
compiler, adapter, or harness implementation as part of composition
- `test_strategy`: begins with internal helper implementation or performance
optimization before the public promise
@@ -0,0 +1,73 @@
---
name: architecture-elicitor
kind: function
version: 0.16.0
---
# Architecture Elicitor
Ask only the questions needed to make meaningful architectural progress.
### Parameters
- `frontier`: at most three active architectural concepts
- `exploration`: orthogonal options and tradeoffs
- `mental_model_sync`: compact shared model and selective recall prompts
- `current`: current architecture
- `landscape`: local facts
- `interactive`: whether questions are available
### Returns
- `elicitation`: accepted answers, decisions resolved, new constraints,
remaining open questions, blocking missing decisions, and retry hint
### Strategies
- Begin a new architecture with: “What should be true after this program runs
that was not true before?”
- Ask the highest-leverage question first.
- Do not ask for confirmation of a settled decision. Materialize its next
reversible consequence and then surface the next genuinely unresolved
decision.
- Every question must identify what downstream architecture its answer unlocks.
If no meaningful branch closes or action becomes possible, do not ask it.
- Prefer mutually exclusive options that divide the remaining design space,
with the recommended option first and a short consequence for each.
- Allow the architect to reject the partition and restate the concept.
- Use recall prompts only when the present decision depends on them.
- Ask follow-ups about boundaries, not implementation trivia.
- If interaction is unavailable, preserve the ranked gaps and return a useful
retry hint rather than guessing.
- The user may say “provisional”; record the answer as an assumption rather
than a decision.
---
## mental-model-synchronizer
Restore a compact shared model before asking the architect to decide.
### Parameters
- `current`: current architecture and constraint lattice
- `frontier`: active and deferred concepts
- `exploration`: orthogonal exploration results
### Returns
- `mental_model_sync`: concise statement of:
- current system purpose and desired render
- current zoom level and path
- load-bearing settled constraints relevant now
- what the exploration clarified or challenged
- active options and their real tradeoff
- deferred concepts that remain untouched
- `recall_prompts`: earlier constraints worth resurfacing now because they are
load-bearing, contradicted, or at risk of mental-model drift
### Invariants
- Sync is short enough to hold in working memory.
- Do not repeat the whole architecture.
- Spaced repetition is selective recall, not ritual repetition.
@@ -0,0 +1,83 @@
---
name: openprose-feedback-classifier
kind: function
version: 0.16.0
---
# Openprose Feedback Classifier
Separate project-local design issues from candidate improvements to OpenProse.
### Parameters
- `candidate`: proposed architecture
- `current`: prior architecture
- `request`: current user direction
- `landscape`: local facts
- `subjects`: optional evidence
- `authority_scope`: caller authority
- `framework_maturity`: current framework maturity
### Returns
- `openprose_feedback`: candidate records matching the top-level schema
### Strategies
- First ask whether a clearer Contract or different standard-library
composition solves the pressure without a framework change.
- Attribute each remaining pressure to exactly one primary layer. Record other
layers only as alternatives or follow-ups.
- A single project example is `possibly-general`, not `repeated`.
- Explicit direction from `openprose-maintainer` may be
`maintainer-direction`, even before run evidence exists.
- Broad semantic changes are acceptable candidates in `experimental` mode;
name the experiment that could validate or falsify them.
- Never create a patch, branch, issue, or PR from this classification stage.
Issue publication is a separate, auditable operation after classification.
---
## openprose-feedback-publisher
Move classified framework pressure across the project boundary without changing
the installed OpenProse package.
### Parameters
- `feedback`: classified OpenProse feedback candidates
- `authority_scope`: caller authority
- `landscape`: canonical public repository, existing local feedback records,
and available issue-publishing capability
### Returns
- `openprose_feedback`: candidates annotated with publication status and issue
URL when available
- `feedback_publication`: issues found, issues filed, issue drafts, failures,
and deduplication rationale
### Invariants
- Never implement framework feedback during Compose.
- Never edit the installed language, standard library, interpreter guidance,
compiler, adapter, or harness in response to feedback from the current design
session.
- Search open and closed public issues before filing. Prefer adding evidence to
an existing issue over creating a duplicate.
- Each issue separates observation and evidence from the candidate solution;
Compose discoveries are requests for later work, not foregone conclusions.
- Issue publication is the only permitted outward framework mutation. Never
create a patch, branch, commit, or pull request.
### Strategies
- With `openprose-maintainer` authority and issue capability available, file or
deduplicate the issue after classification.
- Without maintainer authority or issue capability, return a complete issue
draft and preserve it in `architecture/openprose-feedback.md`.
- Use a concise problem-oriented title. Include affected layer, evidence,
smallest plausible change, alternatives, compatibility pressure, and links
to any originating architecture decision that is safe to publish.
- Do not publish project secrets, private paths, raw transcripts, or proprietary
program details. Reduce evidence to the smallest public reproduction.
+368
View File
@@ -0,0 +1,368 @@
---
name: compose
kind: function
version: 0.16.0
---
# Compose
Progressively design and materialize an OpenProse program while keeping the
human architect's mental model coherent. Compose may explore broadly behind the
scenes, but exposes only a small architectural frontier at a time.
This function powers `prose compose`. `prose init` invokes it in `bootstrap`
mode after establishing the OpenProse root and harness selection.
Compose maintains two deliberately separate feedback loops:
1. **Program architecture** — what this program promises, which Contracts it
needs, how values and authority cross boundaries, and what it renders.
2. **OpenProse feedback** — where designing the program reveals pressure on the
language, standard library, interpreter guidance, compiler, adapter ABI, or
authoring experience.
Program decisions progressively update one coherent OpenProse directory
package. Its root `index.prose.md` expresses system-level intent and
composition; nearby Contract files own their local promises. The architecture
model is reconstructed from that package plus its decision history—it is not a
parallel source of truth. OpenProse feedback is recorded only as candidate
feedback. It never changes the language, standard library, skill, or harness
implementation during `prose compose`.
After classification and deduplication, maintainer-authorized feedback is filed
as an issue on the public OpenProse repository for separate implementation.
### Parameters
- `mode`: one of `bootstrap`, `compose`, `review`, or `reflect`; default
`compose`
- `request`: the user's current design goal, question, correction, rough
workflow, or feedback
- `interactive`: whether the host may ask targeted questions; default `true`
- `persistence`: `persist` or `preview`; default `persist`
- `authority_scope`: `project-author` or `openprose-maintainer`; default
`project-author`
- `framework_maturity`: `experimental`, `stabilizing`, or `stable`; default
`experimental` until project configuration says otherwise
- `subjects`: optional completed run IDs, inspection reports, or source paths
to consider in `review` or `reflect` mode
### Returns
- `architecture`: a working projection of the current program package containing:
- intent and desired renders
- topology profiles selected for the whole system or named regions, with
compact ASCII shorthand and the evidence for each selection
- Contract inventory and one-line promises
- parameters, Returns, maintained projections, capabilities, and important
exclusions at each boundary
- call, data, state, and authority relationships
- relevant standard-library composition candidates
- harness capability requirements
- scenarios, failure behavior, decisions, assumptions, and open questions
- `architecture_changes`: changes made or proposed during this invocation,
with rationale
- `contract_proposals`: Contracts to add, split, merge, remove, or revise,
including which resolved changes were materialized into source
- `test_strategy`: ordered tests that progressively constrain the program from
its public promise down to Contract boundaries, failure behavior, portability,
and performance
- `visual_map`: a derived Mermaid Contract map plus a compact ASCII topology
shorthand and concise legends for call, data, maintained-state, and
capability relationships
- `program_diagnostics`: findings about this program, ordered by architectural
impact
- `openprose_feedback`: zero or more candidate feedback records, each with:
- observation: what the design session exposed
- pressure: why the current OpenProse surface made the work harder, less
clear, less portable, or less expressive
- layer: `language`, `standard-library`, `interpreter`, `compiler`,
`adapter`, `authoring`, `visualization`, or `documentation`
- scope: `project-specific`, `possibly-general`, `repeated`, or
`maintainer-direction`
- evidence: answers, architecture decisions, source locations, runs, or
scenarios supporting the record
- candidate_change: the smallest currently plausible change
- alternatives: viable ways to address the pressure without changing that
layer
- maturity_effect: how the proposal should be treated at the current
framework maturity
- status: `candidate`, `already-filed`, or `filed`
- issue_url: public issue when one already exists or was filed
- `feedback_publication`: issues found, filed, or prepared as drafts, including
why any candidate was not published
- `constraint_lattice`: established, provisional, disputed, and superseded
constraints, including the orthogonal constraints that triangulate each
important architectural concept
- `active_frontier`: at most three architectural concepts currently exposed
for human attention, with why each is active and what decision would close it
- `mental_model_sync`: concise restatement of the current system, what changed,
which earlier constraints remain load-bearing, and where uncertainty remains
- `source_projection`: complete Contract source for resolved regions plus
clearly marked placeholders for unresolved regions; never disguise a
placeholder as settled source
- `visual_artifact`: a generated, self-contained HTML view derived from the
architecture and constraint lattice
- `next_actions`: small ordered set such as another composition question,
`prose write`, `prose compile`, or an evidence-gathering run
- `final_status_summary`: concise status, files updated, Contracts proposed,
unresolved decisions, feedback candidates, and next action
### Errors
- `architecture-unresolved`: a missing decision prevents a coherent Contract
boundary or desired render; include the exact decision without inventing it
- `architecture-conflict`: current source, architecture, and the user's new
direction make incompatible claims; preserve both claims and ask which wins
- `persistence-failed`: the program package or supporting records could not be updated;
return the proposed update without claiming it was written
- `insufficient-evidence`: `reflect` was requested but the subjects do not
support the proposed program or OpenProse conclusion
### Invariants
- Begin from the desired render: what should be true after the program runs
that was not true before. Do not begin by asking how many agents the user
wants.
- Turn the desired render into a package-level `kind: test` before internal
decomposition hardens. Tests constrain architecture; they are not merely a
validation batch written after implementation.
- A proposed Contract boundary must earn its existence through an independent
promise, useful isolation, distinct authority, reusable composition,
independently useful output, separate state ownership, parallelism, or
different runtime needs.
- Do not manufacture orchestration when one competent Contract is sufficient.
- Expose no more than three active architectural concepts to the user at once.
Internal agent fan-out may be wider; the human-facing frontier may not.
- Triangulate important concepts with orthogonal constraints. Do not let one
decomposition axis define the architecture by itself.
- Before asking for another decision, provide a compact mental-model sync:
current scope, relevant settled constraints, new pressure, and the decision
now being divided.
- Prefer multiple-choice questions whose options partition the remaining
concept space. Always permit correction or an option the model missed.
- Use spaced repetition for load-bearing constraints: resurface an earlier
decision when new work depends on it, appears to contradict it, or enough
architectural distance has accumulated that drift is plausible.
- Support zooming without losing position. A zoomed-in Contract view retains
its path to the desired render; a zoomed-out system view preserves unresolved
details instead of flattening them away.
- Keep program diagnostics and OpenProse feedback separate. A defect in one
program is not automatically a language defect.
- Materialize Contract source continuously as architecture resolves. Mark
provisional and unresolved regions explicitly; never present them as frozen.
- Compose may update source files it created or regions explicitly marked as
Compose-managed. It must ask before replacing human-frozen procedure or
changing a public Contract promise.
- Never modify OpenProse framework, standard-library, skill, compiler, adapter,
or documentation source during composition.
- `authority_scope: openprose-maintainer` permits explicit
`maintainer-direction` feedback; it does not bypass the separation or apply
changes automatically.
- In `experimental` maturity, foundational changes are legitimate candidates
and may be based on explicit maintainer direction. Mark uncertainty and
compatibility consequences rather than suppressing the proposal.
- In `stabilizing` maturity, prefer repeated evidence, executable examples,
and migration plans for semantic changes.
- In `stable` maturity, require compatibility analysis and strong evidence for
semantic changes; prefer library or guidance changes when they solve the
pressure without changing the language.
- The OpenProse directory package is the canonical authored truth. Its
`index.prose.md` owns system-level intent and composition; each child Contract
owns its promise and interface. Supporting architecture records explain or
visualize the package but never override it.
- Compose owns only source it created or regions explicitly marked
Compose-managed. Generated `dist/`, run evidence, human-frozen source, and
upstream OpenProse files remain outside its unilateral write boundary.
- The visual map is derived from the program package and decision records. It
is never a second, independently edited source of truth.
- Generated HTML is disposable and derived. It must identify the source
package revision and may never carry architectural facts absent from the
package or its explicitly provisional source markers.
- Static architecture describes what may happen. Runtime traces describe what
did happen. Never present one as the other.
- Ask one highest-leverage question at a time when practical, or at most three
tightly related questions in one interaction. Accept narrative answers that
resolve several gaps at once.
- Do not ask questions whose answers are already available in nearby source,
architecture, configuration, or run evidence.
- Preserve unresolved decisions explicitly. Do not create false architectural
certainty to make the diagram look complete.
- Keep discovered candidate procedure separate from frozen, source-controlled
procedure.
- Contract source crystallizes incrementally. Resolved regions may become full
source while unresolved regions remain explicit proposals or placeholders.
- Do not ask for secrets or include raw environment values in architecture or
feedback artifacts.
### Tools
- `ask_user`: targeted architecture questions when the host supports them
- filesystem read/list/search: read-only landscape and evidence inspection
- filesystem write: limited to `<openprose-root>/architecture/` and explicitly
Compose-managed source regions when `persistence` is `persist`
- public issue search/create: optional; limited to the canonical OpenProse
repository and only for classified OpenProse feedback
### Strategies
- Work backward from desired renders, observable Returns, and maintained
projections before naming Contracts.
- Prefer questions that change a boundary, interface, state owner, authority
boundary, failure policy, or harness requirement.
- Name Contract promises before discussing their procedures.
- For each proposed call, make the downward arguments and upward Returns
explicit; record learnings separately from Returns.
- Identify what each frame must not see as well as what it receives.
- Distinguish semantic work from mechanics that should be deterministic code.
- Reuse standard-library Contracts when their promises and invariants fit;
never select a pattern by name alone.
- Challenge coordination Contracts that also perform their children's work.
- Use scenario walkthroughs to expose hidden coupling: ordinary success, one
child failure, incomplete settlement, partial fan-out, budget exhaustion,
state conflict, prohibited context leakage, and resume/re-entry.
- When a difficulty may be either a weak program design or a framework gap,
state both hypotheses and propose the cheapest discriminating example or run.
- Treat explicit maintainer corrections as important design evidence, while
still recording affected layer, alternatives, and compatibility pressure.
- Keep `next_actions` short. Prefer the one action that resolves the most
architectural uncertainty.
### Execution
```prose
let landscape = call architecture-landscape-scanner
request: request
subjects: subjects
let current = call architecture-loader
landscape: landscape
mode: mode
let gaps = call architecture-gap-modeler
request: request
current: current
landscape: landscape
framework_maturity: framework_maturity
let frontier = call architectural-frontier-selector
gaps: gaps
current: current
request: request
let exploration = call orthogonal-constraint-explorer
frontier: frontier
current: current
landscape: landscape
let sync = call mental-model-synchronizer
current: current
frontier: frontier
exploration: exploration
let elicitation = call architecture-elicitor
frontier: frontier
exploration: exploration
mental_model_sync: sync
current: current
landscape: landscape
interactive: interactive
if elicitation has blocking missing decisions:
throw {
error: "architecture-unresolved",
missing_decisions: elicitation.blocking_missing_decisions,
known_architecture: current.summary,
retry_request_hint: elicitation.retry_request_hint
}
let topology = call topology-profile-selector
current: current
request: request
elicitation: elicitation
exploration: exploration
landscape: landscape
let test_intent = call test-intent-designer
current: current
request: request
elicitation: elicitation
topology: topology
landscape: landscape
let candidate = call architecture-designer
current: current
request: request
elicitation: elicitation
exploration: exploration
topology: topology
test_intent: test_intent
mental_model_sync: sync
landscape: landscape
let test_suite = call test-suite-projector
candidate: candidate
test_intent: test_intent
current: current
landscape: landscape
parallel:
let critique = call architecture-critic
candidate: candidate
test_suite: test_suite
landscape: landscape
subjects: subjects
let feedback = call openprose-feedback-classifier
candidate: candidate
current: current
request: request
landscape: landscape
subjects: subjects
authority_scope: authority_scope
framework_maturity: framework_maturity
let feedback_publication = call openprose-feedback-publisher
feedback: feedback
authority_scope: authority_scope
landscape: landscape
let rendered = call architecture-renderer
candidate: candidate
critique: critique
feedback: feedback_publication
test_suite: test_suite
let source_projection = call contract-source-projector
rendered: rendered
current: current
test_suite: test_suite
let visual_artifact = call architecture-view-renderer
rendered: rendered
source_projection: source_projection
let persisted = call architecture-persister
rendered: rendered
source_projection: source_projection
visual_artifact: visual_artifact
persistence: persistence
landscape: landscape
return {
architecture: rendered.architecture,
architecture_changes: rendered.architecture_changes,
contract_proposals: rendered.contract_proposals,
test_strategy: test_suite.test_strategy,
visual_map: rendered.visual_map,
program_diagnostics: critique.program_diagnostics,
openprose_feedback: feedback_publication.openprose_feedback,
feedback_publication: feedback_publication.feedback_publication,
constraint_lattice: rendered.constraint_lattice,
active_frontier: frontier.active_frontier,
mental_model_sync: sync.mental_model_sync,
source_projection: source_projection.source_projection,
visual_artifact: visual_artifact.visual_artifact,
next_actions: rendered.next_actions,
final_status_summary: persisted.final_status_summary
}
```
+56
View File
@@ -0,0 +1,56 @@
---
name: contract-source-projector
kind: function
version: 0.16.0
---
# Contract Source Projector
Continuously materialize settled design into one readable OpenProse directory
package.
### Parameters
- `rendered`: updated architecture, constraints, proposals, and diagnostics
- `current`: current package source, supporting decisions, and frozen-source facts
- `test_suite`: ordered test sources and readiness gates
### Returns
- `source_projection`: complete source tree containing:
- full Contract source for resolved regions
- explicit architect markers for provisional or unresolved regions
- provenance per changed region: `compose-managed`, `human-frozen`, or
`discovered-candidate`
- source changes proposed for this cycle
- package-level and Contract-level `kind: test` source for resolved behavior
- compile readiness and remaining blockers
### Invariants
- The directory package is the canonical persisted program. The working
architecture proposes changes to it; it does not remain a parallel truth
after persistence.
- The root `index.prose.md` owns system-level intent and composition. Child
Contracts own local promises and interfaces.
- Materialization is progressive, not a final batch generated after all
questions are answered.
- Never fill an unresolved semantic boundary with plausible prose merely to
make a file look complete.
- Never overwrite `human-frozen` procedure without an explicit decision.
- Every public promise change is visible in the mental-model sync before it is
persisted.
- Keep tests beside the package they constrain. A public promise is not resolved
until its package-level test expresses the observable outcome and important
exclusions.
- Resolved source uses current Contract Markdown and remains suitable for
focused refinement through `prose write`.
### Strategies
- Prefer stable filenames and Contract identities as specificity increases.
- Use concise HTML comments for unresolved architect decisions so ordinary
Markdown remains readable.
- Remove a marker when its underlying constraint is resolved; do not retain a
shadow checklist elsewhere.
- Report `compile-ready` only when no blocking markers remain.
+112
View File
@@ -0,0 +1,112 @@
---
name: test-intent-designer
kind: function
version: 0.16.0
---
# Test Intent Designer
Turn the desired render into an outside-in testing intent before internal
decomposition hardens. The first test constrains the package promise, not its
implementation.
### Parameters
- `current`: current program package and prior test evidence
- `request`: current design request
- `elicitation`: resolved purpose, requirements, exclusions, and assumptions
- `topology`: proposed system and regional topology profiles
- `landscape`: existing test source, `kind: test` guidance, harnesses, and run
evidence
### Returns
- `test_intent`: containing:
- public subject: the package-root Contract from `index.prose.md`
- representative fixtures derived from real intended use
- observable desired outcomes
- important prohibited outcomes
- unresolved assertions that still require architect judgment
- topology and harness behaviors that must become observable later
### Invariants
- Start with the package promise: given representative inputs, what observable
result or maintained truth proves that the program did its job?
- Assert semantics, not exact wording or a preferred internal decomposition.
- Include `Expects Not` for the most important forms of plausible but wrong
behavior.
- Do not invent fixtures that hide an unresolved product decision.
- Do not require every internal Contract to exist before the public test can be
drafted.
### Strategies
- Derive the first fixture from the ordinary success scenario, then add the
smallest fixture that distinguishes a dangerous near-miss.
- Keep architectural quality claims observable: isolation becomes prohibited
leakage; bounded work becomes a termination or budget assertion; durable
state becomes an assertion over the maintained projection.
- Mark the test provisional when its public promise is still provisional. A
provisional test guides composition but does not falsely certify readiness.
---
## test-suite-projector
Refine package test intent into an ordered suite that guides implementation and
iteration without freezing internal details too early.
### Parameters
- `candidate`: proposed program architecture and Contract inventory
- `test_intent`: outside-in public test intent
- `current`: existing package tests and prior run evidence
- `landscape`: current `kind: test` semantics and available harnesses
### Returns
- `test_strategy`: an ordered ladder containing:
1. **Package promise** — root `index.prose.md` behavior under ordinary and
distinguishing fixtures
2. **Contract boundaries** — each stable child promise, inputs, Returns or
maintained truth, invariants, and prohibited context or authority
3. **Interaction topology** — fan-out/fan-in, ordering, subscription,
settlement, and state-ownership behavior visible through the root
4. **Failure and recovery** — child failure, partial results, timeout,
retries, budget exhaustion, resume, and side-effect safety where relevant
5. **Harness portability** — the same semantic test corpus under each
supported harness adapter, without provider-specific assertions
6. **Performance and cost** — tracked only after semantic behavior has a
stable baseline
- `test_sources`: complete or provisional `kind: test` files using `subject`,
`### Fixtures`, `### Expects`, and `### Expects Not`
- `readiness`: first failing or missing rung, evidence, and the smallest next
change that can advance it
### Invariants
- Iterate in ladder order. A later performance improvement never outranks a
failing public promise or unsafe failure path.
- Package tests target the root Contract. Contract tests target a child only
after its boundary is stable enough to be meaningful.
- Prefer the smallest test that rules out the largest incorrect region of the
design space.
- A test failure is evidence about the program first. Classify framework
pressure separately and publish it through the feedback obligation.
- Do not encode topology as an implementation snapshot when the same promise
can be tested through observable behavior.
- Do not claim cross-harness portability until the same test sources have run
through each selected adapter.
### Strategies
- Preserve useful failing tests. They are unresolved constraints, not clutter.
- After each material architecture change, run the earliest affected rung
before widening the test scope.
- When a test is flaky, separate ambiguity in the assertion from model
variability and harness nondeterminism before weakening it.
- Use semantic assertions for agent outputs and deterministic checks for file
shape, schemas, bounds, receipts, and side-effect limits.
- Track performance and cost over comparable passing runs; never trade away a
semantic assertion merely to improve the metric.
+49
View File
@@ -0,0 +1,49 @@
---
name: architecture-view-renderer
kind: function
version: 0.16.0
---
# Architecture View Renderer
Render a disposable visual interface over the canonical program package.
### Parameters
- `rendered`: program-package projection and constraint lattice
- `source_projection`: current Contract source projection
### Returns
- `visual_artifact`: self-contained HTML containing:
- zoomable Contract map
- topology profile cards with the standard ASCII thumbnail, fit statement,
selected regions, and links to the full profile and canonical examples
- active-frontier emphasis and deferred-concept dimming
- call, data, state, context, and capability overlays
- settled, provisional, disputed, and unresolved constraint states
- source completeness and compile-readiness indicators
- architecture version and generation timestamp
### Invariants
- HTML is downstream, disposable, and never authoritative.
- Every displayed fact traces to Contract source, an explicit provisional
marker, or a supporting decision record.
- The view must distinguish proposed architecture from observed runtime traces.
### Strategies
- Generate one self-contained file with no service dependency.
- Default to the current zoom level and active frontier rather than displaying
the entire graph at full detail.
- Prefer semantic zoom: system purpose → Contract promises → interfaces →
procedure and evidence.
- Keep the selected topology thumbnail visible as an orientation landmark while
zooming. Highlight the current region instead of redrawing the whole system.
- Keep meaningful layout hints beside the system-level composition in
`index.prose.md`; keep incidental coordinates in the generated artifact.
This renderer remains an internal function initially. Promote it to a separate
downstream Contract only when another program needs the view independently or
when its interface stabilizes enough to reuse.
+10 -3
View File
@@ -36,6 +36,7 @@ After activation, choose the narrowest path that matches the user's intent:
| User Intent | Load First | Then Load If Needed |
|-------------|------------|---------------------|
| Explain OpenProse or answer "how do I..." | `help.md` | `examples/README.md`, then one focused example |
| Initialize or compose an OpenProse program | `guidance/tenets.md` | `guidance/authoring.md`, then run `std/ops/compose` |
| Run a `.prose.md` responsibility or function | `contract-markdown.md` | `state/README.md` and the selected backend (`state/filesystem.md` by default); `forme.md` if responsibilities must be wired (`### Requires``### Maintains`); `prose.md` to execute |
| Inspect or upgrade source layout | `changelog.md` | `contract-markdown.md`, `prosescript.md` if migration details require them |
| Write a new `.prose.md` responsibility or function | `contract-markdown.md` | `guidance/tenets.md`, `guidance/authoring.md` |
@@ -60,9 +61,11 @@ All OpenProse paths are relative to `<openprose-root>`.
| Attached repository | `repo/.agents/prose` |
| User-global | `~/.agents/prose` |
The root contains `src/` for authored intent, `dist/` for compiled intent,
`runs/` for activation receipts, `state/` for durable cross-run state, `deps/`
for installed dependencies, plus `prose.lock` and `.env`.
The root contains `src/` for the canonical authored program packages,
`architecture/` for supporting decisions, visual projections, and issue
records, `dist/` for compiled intent, `runs/` for activation receipts, `state/`
for durable cross-run state, `deps/` for installed dependencies, plus
`prose.lock` and `.env`.
## Proposing This Skill On Your Own Judgment
@@ -123,6 +126,9 @@ executing the contract. The shell executable is the agent runner, e.g.
| Command | Action |
|---------|--------|
| `prose init [request...]` | Establish the minimal OpenProse root and harness selection, then run `std/ops/compose` in `bootstrap` mode. Begin from the desired render and progressively establish a directory package whose `index.prose.md` is the public root |
| `prose compose [request...]` | Load `guidance/tenets.md`, `guidance/authoring.md`, the target Contract package, supporting decisions, and relevant run evidence; run `std/ops/compose` in `compose` mode. Maintain no more than three active conceptual fronts, materialize settled design into source, build tests from package promise through performance, generate a derived HTML view, and route framework pressure to deduplicated public issues when authorized |
| `prose compose --review` / `--reflect <run-id...>` | Run `std/ops/compose` in `review` mode to challenge static design and test coverage, or `reflect` mode to compare it with completed run evidence. Keep program diagnostics distinct from OpenProse issue feedback |
| `prose compile [path] [--out <dir>]` | Load `responsibility-runtime.md`, then `compiler/index.prose.md`; run the pinned ProseScript compiler and emit the compile-phase IR — the topology world-model (nodes, edges, entry points), per-node canonicalizers and postcondition validators, frozen contract fingerprints, and diagnostics — into `<openprose-root>/dist/manifest.next.json` by default |
| `prose compile <image.png\|.svg>` | Load `visual-source.md`. The image is a **typed image** (a visual brief, one rung above markdown). Run the *resolve* render: read the pixels against `visual-source.md`'s requirement tiers, emit `.prose.md` contract(s) into `<openprose-root>/src/` for ratification (the `prose write` discipline — interrupt, do not guess, on safety-bearing blanks), then run the ordinary compile. Compiling **is** the typecheck (acyclic + round-trip-stable) |
| `prose serve` | Load and validate `<openprose-root>/dist/manifest.active.json`, which is promoted from `manifest.next.json` with `cp dist/manifest.next.json dist/manifest.active.json`; register local cron and HTTP trigger adapters; launch ordinary bounded activations |
@@ -283,6 +289,7 @@ another repository uses `repo/.agents/prose`. User-global work uses
| Path | Purpose |
|------|---------|
| `<openprose-root>/architecture/` | Supporting decisions, generated visual map, and OpenProse issue links or drafts; never a second source of truth |
| `<openprose-root>/src/` | Default source root for project, directory, or repository scoped OpenProse |
| `<openprose-root>/src/**/index.prose.md` | Conventional multi-file DAG root for a set of wired responsibilities |
| `<openprose-root>/dist/` | Compiled intent and served manifests |
+14 -2
View File
@@ -26,16 +26,28 @@ plan.
- Native repositories use the repository root as the OpenProse root.
- Attached repositories use `repo/.agents/prose`.
- User-global OpenProse uses `~/.agents/prose`.
- The root contains `src/`, `dist/`, `runs/`, `state/`, `deps/`,
`prose.lock`, and `.env`.
- The root contains `src/`, `architecture/`, `dist/`, `runs/`, `state/`,
`deps/`, `prose.lock`, and `.env`. Canonical authored truth remains in
`src/`; `architecture/` contains supporting Compose decisions and projections.
- Durable cross-run agents live in `state/agents/`.
- Each responsibility's persisted world-model and its signed, append-only
receipt ledger are the durable cross-run truth; there is no separate status or
pressure store (the judge loop is retired).
- Multi-file systems conventionally use `index.prose.md`.
- `prose init` and `prose compose` run the `std/ops/compose` directory package.
Compose progressively materializes a canonical directory package, develops
semantic tests outside-in, and routes framework feedback to public issues
rather than implementing it during composition.
- Generated run internals include the compiled activation manifest,
`root.prose.md`, and `vm.log.md`.
## Unreleased
- Introduces `prose init` / `prose compose` and the obligation-centered
`std/ops/compose` directory package, including bounded architectural fronts,
progressive Contract source, derived visual views, outside-in semantic test
ordering, and issue-routed OpenProse feedback.
## History
- `v0.4.x`: early skill discovery, `prose help`, filesystem state, examples in
+15 -4
View File
@@ -33,7 +33,7 @@ Options:
**After the user responds:**
- **Run a contract**: Ask for the file path, then load `prose.md` and execute
- **Build something new**: Ask them to describe their task, then help write a contract (load `guidance/authoring.md`)
- **Build something new**: Start with `prose init` / `prose compose` when the Contract system is not yet clear; use `prose write` when one Contract is already understood
- **Keep a goal true**: Help author a `kind: responsibility`, then explain `prose compile`, `prose serve`, and `prose status`
- **Learn the syntax**: Show examples from `examples/`, explain the VM model
- **Improve OpenProse**: Run `std/evals/prose-contributor` on relevant run IDs; require explicit user approval before pushing or opening a PR
@@ -45,6 +45,8 @@ Options:
| Command | What it does |
|---------|--------------|
| `prose init [request...]` | Initialize an OpenProse workspace and begin its architecture |
| `prose compose [request...]` | Design and evolve the program's Contracts, relationships, and architecture |
| `prose compile [path] [--out <dir>]` | Compile source into `<openprose-root>/dist/manifest.next.json` |
| `prose serve` | Serve the active IR as local cron and HTTP trigger adapters |
| `prose run <file.prose.md>` | Run a responsibility or function contract |
@@ -75,11 +77,20 @@ prose serve
**Create your first contract:**
```
prose help
-> Select "Build something new"
-> Describe what you want to automate
prose init
prose compose
prose write
```
`prose compose` progressively turns the project architecture into full Contract
source while keeping unresolved regions explicit. It creates semantic tests in
order from the package promise through Contract boundaries, failure behavior,
portability, and performance. It never edits the OpenProse framework during
composition; framework feedback is deduplicated and filed as a public issue
when authorized, or preserved as an issue draft.
Use `prose compose --review` to challenge the current design and
`prose compose --reflect <run-id...>` to compare it with execution evidence.
Default project source lives under `<openprose-root>/src/`. Multi-file systems
conventionally start at `<openprose-root>/src/{system}/index.prose.md`; runs are
written to `<openprose-root>/runs/`.
+2
View File
@@ -37,6 +37,8 @@ codex exec "prose run research.prose.md"
| Command | Action |
| --------------------------- | --------------------------------------------------------------- |
| `prose init [request...]` | Initialize an OpenProse root and invoke the `std/ops/compose` package in bootstrap mode |
| `prose compose [request...]` | Progressively design, test, visualize, and materialize one canonical Contract package |
| `prose compile [path]` | Compile Responsibility Runtime source into validated repository IR |
| `prose serve` | Serve active repository IR as local cron and HTTP trigger adapters |
| `prose run <file.prose.md>` | Execute a local responsibility or function |
+133
View File
@@ -0,0 +1,133 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
const repoRoot = fileURLToPath(new URL("../../../", import.meta.url));
function read(path: string): string {
return readFileSync(join(repoRoot, path), "utf8");
}
describe("prose compose", () => {
const composePackage = [
"index.prose.md",
"compose.test.prose.md",
"architecture.prose.md",
"dialogue.prose.md",
"source.prose.md",
"tests.prose.md",
"view.prose.md",
"feedback.prose.md",
];
const compose = composePackage
.map((path) => read(`packages/std/ops/compose/${path}`))
.join("\n");
it("is a bounded standard-library function behind init and compose", () => {
expect(compose).toMatch(/name: compose/);
expect(compose).toMatch(/kind: function/);
expect(compose).toMatch(/powers `prose compose`/);
expect(compose).toMatch(/`prose init` invokes it in `bootstrap`/);
});
it("is an obligation-centered directory package", () => {
expect(composePackage).toEqual([
"index.prose.md",
"compose.test.prose.md",
"architecture.prose.md",
"dialogue.prose.md",
"source.prose.md",
"tests.prose.md",
"view.prose.md",
"feedback.prose.md",
]);
});
it("resolves every root call within the directory package", () => {
const defined = new Set<string>();
for (const path of composePackage) {
const source = read(`packages/std/ops/compose/${path}`);
for (const match of source.matchAll(/^name:\s+([a-z][a-z0-9-]*)$/gm)) {
defined.add(match[1]);
}
for (const match of source.matchAll(/^##\s+([a-z][a-z0-9-]*)$/gm)) {
defined.add(match[1]);
}
}
const root = read("packages/std/ops/compose/index.prose.md");
const calls = [...root.matchAll(/\bcall\s+([a-z][a-z0-9-]*)/g)].map(
(match) => match[1],
);
expect(calls.length).toBeGreaterThan(0);
expect(calls.filter((name) => !defined.has(name))).toEqual([]);
});
it("orders program tests from public promise toward optimization", () => {
expect(compose).toMatch(/name: test-intent-designer/);
expect(compose).toMatch(/package promise/);
expect(compose).toMatch(/Contract boundaries/);
expect(compose).toMatch(/failure and recovery/i);
expect(compose).toMatch(/harness portability/i);
expect(compose).toMatch(/performance and cost/i);
});
it("keeps program design and framework feedback separate", () => {
expect(compose).toMatch(/Program architecture/);
expect(compose).toMatch(/OpenProse feedback/);
expect(compose).toMatch(/openprose-feedback-publisher/);
expect(compose).toMatch(/filed\s+as an issue on the public OpenProse repository/);
expect(compose).toMatch(/Never implement framework feedback during Compose/);
expect(compose).toMatch(/Never modify OpenProse framework/);
});
it("allows deep early feedback without silently promoting it", () => {
expect(compose).toMatch(/`experimental`, `stabilizing`, or `stable`/);
expect(compose).toMatch(/foundational changes are legitimate candidates/);
expect(compose).toMatch(/maintainer-direction/);
});
it("starts architecture from the render rather than an agent org chart", () => {
expect(compose).toMatch(/Begin from the desired render/);
expect(compose).toMatch(/What should be true after this program runs/);
expect(compose).toMatch(/must earn its existence/);
});
it("bounds the human frontier and triangulates with orthogonal constraints", () => {
expect(compose).toMatch(/no more than three active architectural concepts/i);
expect(compose).toMatch(/orthogonal constraints/i);
expect(compose).toMatch(/mental-model sync/i);
expect(compose).toMatch(/spaced repetition/i);
expect(compose).toMatch(/resurface any deferred commitment/i);
expect(compose).toMatch(/Do not ask for confirmation of a settled decision/);
});
it("progressively materializes source while preserving human-frozen regions", () => {
expect(compose).toContain("<program-root>/index.prose.md");
expect(compose).toContain("<openprose-root>/architecture/decisions.md");
expect(compose).toContain("<openprose-root>/architecture/openprose-feedback.md");
expect(compose).toMatch(/directory package is the canonical authored truth/);
expect(compose).toMatch(/Materialize Contract source continuously/);
expect(compose).toMatch(/human-frozen/);
});
it("keeps the HTML view downstream and disposable", () => {
expect(compose).toMatch(/architecture-view-renderer/);
expect(compose).toContain("<openprose-root>/architecture/view.html");
expect(compose).toMatch(/HTML is downstream, disposable, and never authoritative/);
});
it("is routed consistently across the interpreter docs", () => {
for (const path of [
"skills/open-prose/SKILL.md",
"skills/open-prose/help.md",
"skills/open-prose/prose.md",
"packages/std/ops/README.md",
]) {
const source = read(path);
expect(source, path).toMatch(/prose init/);
expect(source, path).toMatch(/prose compose/);
}
});
});