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
46 changes: 43 additions & 3 deletions .agents/skills/sdp-agent-surface/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ is `spec:consumers.agent-surface`, realized by the front door
`spec:decisions.agent-front-door` (MD-22): the package exports the reader, and the CLI carries one
evaluation sink. There is no verb wall — you script the graph.

## The shape of the graph

The graph is flat: one array of nodes, one array of edges, nothing nested. Hierarchy is edges, so
every question is a filter or a join, never a tree walk. Four node types exist:

- `Primitive` — one authored Spec, positioned by `specKind` × `altitude` × `readiness`, carrying
its title, narrative, reified section content, and the derived `deliveryFacts`. Use case, NFR,
decision record, epic, and story are coordinates on this one type, never separate node types.
- `Pack` — the review grouping: title, framing prose, `modelRefs`. Membership is `belongsTo`
edges. A Pack states no system truth.
- `Anchor` — a test or oracle binding, with the `file` and `line` of the binding itself.
- `CodeNode` — the code identity a `codeAnchor` mints; structural `memberOf` and `uses` edges run
between these.

Eleven edge types exist, and the list is closed. Six are authored Spec relations: `refines`,
`dependsOn`, `constrainedBy`, `decidedBy`, `verifies`, `supersedes`. Five are derived by
extraction: `belongsTo` (Pack membership), `satisfies` (code realization), `models` (oracle
binding), `memberOf` and `uses` (anchored structure). A relation name outside this list is a bug
in whatever prose named it, not a query to attempt. IDs are namespaced (`spec:` · `pack:` ·
`impl:` · `api:` · `component:` · `test:` · `oracle:`), and an edge whose target does not resolve
confers no delivery fact. Every node and edge carries exactly one claim; the edge contract is
`spec:extraction.derive-graph`, the claim law is `spec:extraction.claim-taxonomy`.

## How delivery state derives

Every fact enters the graph through one of three claims, and the claims are never collapsed.
Carrier prose, relations, and stated readiness are `declared` intent. Source anchors are `anchored`
bindings: a `codeAnchor` records that this code realizes that Spec, a `specTest` records that this
test verifies its target Spec, a `specOracle` records that this function models that example space.
Structure the extractor computes on its own enters as `inferred`.

Delivery facts fall out of those edges. A Spec is `implemented` when a `satisfies` edge resolves to
it directly; the fact never travels through refinement. A Spec has `has-verifier` through either of
two routes: a resolving `specTest` anchor verifies the Spec directly, or a verifying example is an
enabled verifier, meaning that example is itself backed by a resolving `specTest` anchor. The
test's anchored `verifies` edge and the example's declared `verifies` edge share one relation type
under two claims. Stated readiness, derived readiness, and delivery facts are three
independent coordinates, and the standing queries (build backlog, drift alarm, readiness
divergence) are intersections of them. Runtime liveness would be `observed`, a designed-and-deferred
fact the graph does not derive today.

## Bootstrap discipline

For any corpus question, **query the graph before reading spec files**.
Expand All @@ -23,8 +64,7 @@ pnpm exec sdp q 'return g.specs().length' --root PATH --exclude PATH
pnpm exec sdp q 'return g.specContext("spec:example.id")' --root PATH --exclude PATH --json
```

`PATH` is a placeholder, not a universal exclusion. For example, the origin adopter uses its
`pnpm sdp:q` wrapper and excludes only `deps-packages`.
`PATH` is a placeholder, not a universal exclusion.

When working in the **Protocol source checkout itself**, use its repository script, which supplies
the exact three fixture exclusions:
Expand Down Expand Up @@ -99,7 +139,7 @@ read the carrying Spec.
- **Do not read `has-verifier` as "the tests pass."** It says a resolving verifier binding _exists_.
Pass, fail, skip, and quarantine are CI's.
- **Do not read `implemented` as "it is live."** It says a code anchor binds to the Spec. Runtime
evidence would be `observed`, which is not tracked.
evidence would be `observed`, the designed-and-deferred liveness fact the graph does not derive.
- **Do not use raw `ready ∧ ¬implemented` as the operational backlog.** Under the example realization
posture and the decision readiness posture it also includes ready example evidence and ready
decision records; recipe 1 excludes both kinds, reports the excluded counts, and audits example
Expand Down
130 changes: 109 additions & 21 deletions .agents/skills/sdp-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@ description: Author and mature Protocol Specs through the graph-first workflow.
# Author Specs through the graph

Treat the canonical carrier as the write surface and the derived graph as the read model. Start every
session with the build-backlog and drift-alarm recipes. In the Protocol repository the catalog is
`docs/agent-surface/recipes.md`; in an adopter, read the same shipped catalog at
`node_modules/@libar-dev/software-delivery-protocol/docs/agent-surface/recipes.md`.
session with the build-backlog and drift-alarm recipes, recipe 1 and recipe 2, run verbatim from the
catalog. In the Protocol repository the catalog is `docs/agent-surface/recipes.md`; in an adopter,
read the same shipped catalog at
`node_modules/@libar-dev/software-delivery-protocol/docs/agent-surface/recipes.md`. The catalog is the
sole owner of the bodies; copy from it, never from session notes or earlier prompts.

At this repository root, use the exact self-hosting exclusions:
At this repository root, the `sdp:q` wrapper supplies the exact self-hosting exclusions. Paste each
recipe body between the quotes:

```sh
pnpm --silent sdp:q 'const ready = g.specs().filter((spec) => spec.statedReadiness === "ready"); const backlog = ready.filter((spec) => spec.specKind !== "example" && spec.specKind !== "decision" && !spec.deliveryFacts.includes("implemented")); const excludedExamples = ready.filter((spec) => spec.specKind === "example" && !spec.deliveryFacts.includes("implemented")); const excludedDecisions = ready.filter((spec) => spec.specKind === "decision" && !spec.deliveryFacts.includes("implemented")); return {backlog: backlog.map((spec) => spec.id), excludedReadyExamples: excludedExamples.length, excludedWithoutVerifier: excludedExamples.filter((spec) => !spec.deliveryFacts.includes("has-verifier")).map((spec) => spec.id), excludedReadyDecisions: excludedDecisions.length}'
pnpm --silent sdp:q 'return g.specs().filter((spec) => spec.deliveryFacts.includes("implemented") && spec.statedReadiness !== "ready").map((spec) => spec.id)'
pnpm --silent sdp:q '<body>'
```

For an adopter, select its root and exclusions explicitly:

```sh
pnpm exec sdp q 'return g.specs().map((spec) => spec.id)' --root PATH
pnpm exec sdp q 'return g.specs().map((spec) => spec.id)' --root PATH --exclude PATH --exclude PATH
pnpm exec sdp q '<body>' --root PATH
pnpm exec sdp q '<body>' --root PATH --exclude PATH --exclude PATH
```

The Protocol wrapper supplies the root's three exclusions; run `npm run build` first if `dist/` is
Expand Down Expand Up @@ -107,13 +109,81 @@ Use a Markdown `*.pack.sdp.md` manifest with frontmatter closed to `id`, `specs`
`modelRefs`. The H1 is the Pack title; the remaining body prose is its framing. Preserve authored
membership order and point to `spec:carrier.markdown-pack-authoring` for the complete carrier law.

## Bind code, tests, and oracles

Anchors are the only write path from code into the graph, and the two ways to get them wrong are
both silent: nothing fails, the binding just never exists. Three builders exist, each carrying
identity, an optional label, and one realization target:

- `codeAnchor` binds implementation code through `satisfies`, with IDs in the `impl:`, `api:`, or
`component:` namespaces.
- `specTest` binds a test through a non-empty `verifies`, in the `test:` namespace. A resolving
`specTest` anchor is the sole `has-verifier` source, conferring the fact directly on the Spec it
verifies or, through an enabled example, on the Spec that example verifies.
- `specOracle` binds an oracle through `models`, in the `oracle:` namespace. It records that
expected-outcome semantics exist and confers no delivery fact.

The anchor-constant form, written out once:

```ts
import {
codeAnchor,
codeAnchorId,
componentAnchorId,
ref,
} from "@libar-dev/software-delivery-protocol";

const createOrderAnchor = codeAnchor({
id: codeAnchorId("impl:orders.create-order"),
label: "realizes order creation",
satisfies: ref("spec:orders.create-order"),
component: componentAnchorId("component:orders.api"),
uses: [codeAnchorId("impl:orders.repository")],
});
void createOrderAnchor;
```

A top-level `const`, a trusted package import, one realization target, and optional structure. The
`void` reference keeps the unused constant past lint without exporting it.

The first hazard is form. The extractor reifies only the anchor-constant form above: a top-level
`const` initialized with the builder call. The decorator and JSDoc forms remain unextracted
representations and mint nothing.

The second hazard is trust. The builder import must be a Protocol builder binding: from the public
package, or from a relative import that resolves to the package's `ids` or `model/code-anchor`
module. A consumer-local lookalike mints nothing and reports nothing, because a source file that
never bound to the Protocol is not authoring drift to report. On the CommonJS package surface the
trusted relative-module set is empty, so relative bindings mint no anchors there while package
imports stay trusted. When an authored anchor fails to appear in the graph, suspect the import
before the syntax.

An anchor never carries behavior, rationale, readiness, acceptance criteria, or delivery facts; a
field beyond that contract is an extraction error. The law is `spec:model.anchors` and
`spec:decisions.binding-not-liveness`.

A `codeAnchor` may also declare structure through two fields: one `component?: ComponentAnchorId`
and a non-empty, unique `uses?: readonly CodeAnchorId[]`. Both are closed graph-ID references that
must resolve to an existing `CodeNode`, and they derive only anchored `memberOf` and `uses` edges.
`memberOf` runs from an `impl:` or `api:` node to a `component:` node with at most one component
per source, structural self-reference is refused, and a malformed structural field refuses the whole
anchor. There is no `implements` field; contract realization stays `satisfies`. Multi-node `uses`
cycles remain data, never findings, and structural edges confer no intent, delivery fact, or
readiness effect. The law is `spec:decisions.structural-anchor-semantics`.

A Markdown deliverable cannot carry an in-code anchor. Bind it through the document-realization
convention: the test suite that asserts the shipped document carries the code anchor, its label
names the document realization rather than the test body, and file-level blast radius stays
coverage-unknown for the Markdown file. This repository binds its own skills exactly this way in
`test/skills.test.ts`.

## Make an example executable

1. Put the typed `gwt-vocabulary` example space on the parent.
2. Put one concrete `gwt` bound point on each example child, following
`spec:decisions.point-per-example`.
3. Generate contracts from the extraction root. In this source checkout use the repository
scripts, which supply the three fixture exclusions:
3. Generate contracts and registrars from the extraction root. In this source checkout use the
repository scripts, which supply the three fixture exclusions:

```sh
npm run generate:self-hosting
Expand All @@ -131,28 +201,46 @@ membership order and point to `spec:carrier.markdown-pack-authoring` for the com
Diagnose contract refusals from `sdp build`; `sdp q` receives graph-validation findings, not
codegen findings.

The build emits one registrar per bindable example, named `<spec-id-path>.test.generated.ts`
and placed beside the authored suite whose `specTest` anchor verifies that example; the Spec ID
owns the filename, so one consolidated suite can bind many examples without collisions.
Repository generation also publishes the independent Design Review, census, Mermaid, and
Gherkin-shaped read roots. Use the repository generate/check scripts to certify the complete
projection suite; do not treat the Gherkin read root as an authored carrier.

4. In the verifier suite, colocate `bindExample(generatedContract, world, bindings)` with a
`specTest` anchor targeting that example. In this repository, registering every suite that
imports a generated contract in `contract-dependent-suites.mjs` is part of binding.
5. Mutate one expected result and prove the new point goes red, then restore it. Keep runner
4. Author the oracle for the space and bind it with a top-level `specOracle` anchor whose `models`
names the parent. Eligibility follows example-space ownership, not kind: a missing target, a
wrong namespace, an absent space, or a competing oracle is a conformance error, and consumers
fail closed. Type the oracle against the generated space contract and treat `unspecified` as a
first-class answer. Follow `spec:validation.oracle-target-eligibility`.
5. Activate the registrar from the authored suite. Keep one top-level `specTest` anchor with a
non-empty `verifies` naming the example. Import the generated registrar sibling and make one
activation call passing the five adapters: `createWorld`, `invoke`, `observe`, `expected`, and
optional `assertions`. Import direction is authored to generated only; the generated module never
imports authored code. The registrar owns runner registration, step dispatch, the three-way
comparator, and failure rendering. The law is `spec:extraction.runnable-modules`.
6. Commit an adopted registrar. A registrar becomes adopted the moment tracked authored code
imports it, and adopted registrars are committed and byte-checked against fresh generation;
unadopted siblings stay ignored, regenerable output. The law is
`spec:decisions.adopted-registrars-committed`. In this repository, listing every suite that
imports a generated contract, adopted registrar siblings included, in
`contract-dependent-suites.mjs` is part of binding.
7. Mutate one expected result and prove the new point goes red, then restore it. A Spec mutation
must redden through the comparator, never through actual-equals-oracle alone. Keep runner
execution and pass state outside the graph.

The graph can report a resolving `specTest` binding. It cannot detect a generated contract that no
suite binds because `bindExample` call sites are not extracted graph data.
`bindExample(generatedContract, world, bindings)` from the `./vitest` subpath is the low-level
adapter beneath the registrar. Reach for it only when the registrar cannot serve.

The graph can report a resolving `specTest` binding. It cannot detect a generated contract or
registrar that no authored suite activates, because activation call sites are not extracted graph
data.

Ready examples normally carry verification evidence rather than build-backlog work. The canonical
backlog recipe excludes them while reporting their count and any missing verifier binding; it does
not infer `implemented` through their parent.

## Bind implementation and review

Add a `codeAnchor` beside the code that realizes the Spec, following
`spec:decisions.binding-not-liveness` and `spec:model.anchors`. An anchor states identity and one
target only; it never carries intent, readiness, or runtime truth.
## Review and state ready

Regenerate the Design Review, inspect the Spec in context, and run recipes 7–11. Tooling never
confers `ready`: after the floor clears and the evidence is reviewed, a human may state it by
Expand Down
7 changes: 4 additions & 3 deletions .agents/skills/sdp-sessions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ not an automatic `ready` statement.
Use the build backlog (recipe 1) to orient the available ready work and the target Spec context
(recipe 3) to read guarantees, relations, implementation bindings, and verifiers. When the work
lives in a declared seam, use component membership (recipe 12) and uses fan-in/fan-out (recipe 13)
to see the units and neighbors before binding. Bind anchors
and executable examples through `sdp-authoring`; an `implemented` fact names a binding, not a
passing or live system.
to see the units and neighbors before binding. Bind code, test, and oracle anchors, the structural
`component` and `uses` fields included, and executable examples through `sdp-authoring`, which owns
the registrar-first executable transition; an `implemented` fact names a binding, not a passing or
live system.

### Review

Expand Down
17 changes: 15 additions & 2 deletions .omo/boulder.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": 2,
"active_work_id": null,
"active_work_id": "sdp-skills-gen1-parity-unslop",
"works": {
"pr-17-gherkin-carrier-hardening": {
"work_id": "pr-17-gherkin-carrier-hardening",
Expand Down Expand Up @@ -58,11 +58,24 @@
"plan_name": "sdp-skills-gen1-parity",
"session_ids": [],
"status": "completed",
"completed_at": "2026\u002d08\u002d20T13:07:13+02:00",
"current_commit": "8df0d8096b476408ec364b884155537d74c7603e",
"worktree_path": null,
"delivery_mode": "direct",
"make_pr": false
},
"sdp-skills-gen1-parity-unslop": {
"work_id": "sdp-skills-gen1-parity-unslop",
"active_plan": ".omo/plans/sdp-skills-gen1-parity-unslop.md",
"plan_name": "sdp-skills-gen1-parity-unslop",
"session_ids": [
"senpi:01A01EF7-DEC3-787C-A72D-C792A28A2C2F"
],
"status": "completed",
"worktree_path": "/home/darkomijic/dev-libar/software-delivery-protocol-sdp-skills-gen1-parity-unslop",
"delivery_mode": "make-pr",
"make_pr": true,
"active_task": null,
"completed_todo": 6
}
}
}
35 changes: 35 additions & 0 deletions .omo/plans/sdp-skills-gen1-parity-unslop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# sdp-skills-gen1-parity-unslop - Work Plan

## TL;DR

Remove AI-generated slop from the three files delivered by `sdp-skills-gen1-parity`: `.agents/skills/sdp-agent-surface/SKILL.md`, `.agents/skills/sdp-authoring/SKILL.md`, and `README.md`. Preserve every machine-consumed value and command form already covered by tests. Verify with focused tests, the full green gate, and package dry-run.

## Scope

### Must have
- Identify and remove obvious comments, redundant prose, over-defensive wording, needless repetition, and any AI-tells in the three target files.
- Keep every required frontmatter field, command form, recipe count, skill name, and machine-tested token intact.
- Preserve the three-skill topology (`sdp-agent-surface`, `sdp-authoring`, `sdp-sessions`).
- Keep `sdp-sessions` byte-for-byte unchanged.
- Ensure `npx vitest run test/skills.test.ts test/recipes.test.ts test/cli-q.test.ts test/package-smoke.test.ts` passes.
- Ensure `npm run check` passes.
- Ensure `npm pack --dry-run --json` lists the same three skill files and recipe catalog.

### Must NOT have
- No edit under `src/`, `specs/`, `docs/agent-surface/`, `generated/`, `package.json`, or `AGENTS.md`.
- No new skill, recipe, product law, or runtime behavior.
- No prose tests; rely on existing machine-checked contracts.

## Verification strategy
- Behavior lock: existing test suites cover frontmatter, command forms, recipe cardinality, and package assets. Run them first.
- Cleanup: one parallel batch of deep agents for the three files (≤5 files).
- Quality gates: focused tests, `npm run check`, package dry-run, `git diff --check`.
- Final review: adversarial verifier checks the diff for scope fidelity and slop removal.

## Todos
- [x] 1. Lock behavior with existing tests
- [x] 2. Remove slop from sdp-agent-surface skill
- [x] 3. Remove slop from sdp-authoring skill
- [x] 4. Remove slop from README recipe count context
- [x] 5. Run merged verification gates
- [x] F1. Final scope and quality review
Loading
Loading