herdr workforce output (6 codex angle-specialists -> claude synthesis): S1 ledger/economy, S2 catalog/registry, S3 storefront (cargstore->M2 Store), S4 Solution Scout (standalone watcher recommended), S5 packaging + 3 seed Solutions (mm-pdf 25cr, agent-scaffold 35cr, competitor-scan 60cr), S6 proposal engine + evidence loop. SPEC-INDEX is the tie-break: 23-row cross-cutting contract table (16 mismatches resolved, e.g. /v1 ledger paths win, m2store://listing/<id> deep link, one m2.market.telemetry.v1 envelope, op_<slug> operator ids, tenant ids from m2-gpt), 8 deduped clarifications with defaults, 4-phase build order where the paid-install wedge does NOT block on fedlearn (local ApplyAdapter until rails land), risk register. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
647 lines
23 KiB
Markdown
647 lines
23 KiB
Markdown
# S5 Spec — Packaging & Seed Solutions
|
|
|
|
Grounded reads: `/tmp/mktspec/BRIEF.md`, `CONCEPT.md`, `context/SYSTEM-MAP.md`,
|
|
`/home/m2/m2o/.planning/federated-learning/PLAN.md`, frozen marketplace schemas/contracts,
|
|
live Docker fleet, live `m2-gpt` and `memory-api` health checks, `mm-pdf` and
|
|
`agent-scaffold` skills.
|
|
|
|
## 1. Scope & non-goals
|
|
|
|
### MVP scope
|
|
|
|
S5 owns the contract for turning a proven outcome into a sellable installable Solution:
|
|
|
|
- builder workflow from either fedlearn `commercialize` or direct `m2-market publish`
|
|
- canonical bundle layout: `solution.yaml`, `solution.json`, `listing.json`, `payload/`,
|
|
`recipe.yaml`, `permissions.yaml`, `invoke.md`, `evidence/`
|
|
- packaging validation and PR review requirements for `m2/market-registry`
|
|
- install/uninstall/upgrade contract through `m2-market` and the `m2core-sync` apply adapter
|
|
- pre-apply license check hook against `m2-ledger`
|
|
- evidence attachment for provenance, cost telemetry, permissions, rollback, and installs
|
|
- concrete seed bundle specs for `mm-pdf`, `agent-scaffold`, and `competitor-scan`
|
|
|
|
The MVP must work with the existing frozen `schemas/solution.schema.json` and
|
|
`schemas/listing.schema.json`. The human-authored source manifest is `solution.yaml`; the
|
|
publish command renders canonical `solution.json` and `listing.json` that pass frozen JSON
|
|
Schema validation.
|
|
|
|
### Later
|
|
|
|
- metered usage pricing and revenue sharing by invocation
|
|
- external public marketplace packaging
|
|
- cryptographic bundle signatures beyond content hash verification
|
|
- automated LLM-based tenant scrub beyond deterministic scanner + human attestations
|
|
- public coin/exchange or external payment settlement
|
|
- service escrow/dispute workflow for job-priced Solutions
|
|
|
|
### Non-goals
|
|
|
|
- Ledger internals, transaction schema, and platform cut mechanics: S1.
|
|
- Catalog indexing/search/ranking and storefront fields beyond package/listing emission: S2/S3.
|
|
- Scout matching/proposal logic: S4.
|
|
- Hermes build-vs-install proposal composition: S6.
|
|
|
|
## 2. User stories + acceptance criteria
|
|
|
|
### Story A — package a direct proven outcome
|
|
|
|
Given a builder has a repeatable skill/playbook and at least one provenance record,
|
|
When they run `m2-market package init --from-skill /home/m2/.claude/skills/mm-pdf --id sol_mm-pdf-report`,
|
|
Then a bundle directory is created with `solution.yaml`, payload files, deploy recipe,
|
|
permissions, invoke docs, and an evidence stub.
|
|
|
|
Given that bundle directory,
|
|
When the builder runs `m2-market publish ./bundle --price 25 --seller <operator_id>`,
|
|
Then the CLI validates schema, permissions, hash, evidence, and tenant firewall rules,
|
|
uploads a release asset, and opens a `m2/market-registry` PR in `in_review`.
|
|
|
|
### Story B — package from fedlearn commercialize
|
|
|
|
Given fedlearn curator marks a cluster disposition `commercialize`,
|
|
When the handoff calls the S5 package importer with the staged cluster/core artifact,
|
|
Then the importer creates a Solution bundle draft preserving fedlearn provenance, cost
|
|
telemetry, applicability, risk class, rollback note, and scrub status.
|
|
|
|
Given the generated draft includes tenant-derived evidence,
|
|
When `tenant_scope != "m2-core"`,
|
|
Then publish fails unless `owner_initiated: true` and
|
|
`scrub_status.double_scrubbed: true` are present and reviewed in the PR.
|
|
|
|
### Story C — install, verify, uninstall, and re-install
|
|
|
|
Given a published fixed-price listing and a buyer with enough credits,
|
|
When `m2-market install <listing_id>` runs,
|
|
Then the CLI checks or purchases a license, verifies bundle hash, calls the apply adapter,
|
|
runs the recipe verify command, records install state, and prints the invocation hint.
|
|
|
|
Given the same listing is already licensed and applied,
|
|
When `m2-market install <listing_id>` runs again,
|
|
Then no duplicate debit occurs and the adapter returns no-op success.
|
|
|
|
Given an installed Solution,
|
|
When `m2-market uninstall <listing_id>` runs,
|
|
Then the adapter executes the recipe uninstall steps, leaves the license grant intact,
|
|
updates install state to `rolled_back`, and emits uninstall telemetry.
|
|
|
|
### Story D — upgrade
|
|
|
|
Given `lst_mm-pdf-report-v1.1.0` is published and the buyer has a major-version license for
|
|
v1,
|
|
When `m2-market upgrade lst_mm-pdf-report`,
|
|
Then the CLI checks license coverage, downloads the new bundle, applies only the versioned
|
|
changeset, verifies, and updates state from `1.0.0` to `1.1.0` without a new debit.
|
|
|
|
Given a new major version `2.0.0`,
|
|
When a v1 license holder upgrades,
|
|
Then the CLI requires a new install purchase unless the listing declares explicit grace
|
|
terms.
|
|
|
|
## 3. Interfaces & data contracts
|
|
|
|
### Registry paths
|
|
|
|
Truth lives in Forgejo `git.machinemachine.ai/m2/market-registry`.
|
|
|
|
```text
|
|
listings/<listing_id>/
|
|
├── listing.json
|
|
├── solution.json
|
|
├── evidence/
|
|
│ ├── provenance.jsonl
|
|
│ ├── cost.json
|
|
│ ├── scrub-attestation.json
|
|
│ └── permissions-diff.md
|
|
└── README.md
|
|
|
|
releases/<install_ref>.tar.gz # Forgejo release asset, not committed as a blob
|
|
```
|
|
|
|
Builder workspaces may live in this repo under `solutions/<slug>/`, but the registry PR is
|
|
the system of record.
|
|
|
|
### Bundle layout
|
|
|
|
Release asset tarball:
|
|
|
|
```text
|
|
solution.json # canonical frozen schema payload
|
|
solution.yaml # source manifest; informational inside release
|
|
listing.json # catalog-facing record for this version
|
|
recipe.yaml # declarative apply/verify/uninstall/upgrade contract
|
|
permissions.yaml # source permission declarations rendered into solution.permissions
|
|
invoke.md # operator-facing invocation docs; no secrets
|
|
payload/
|
|
skills/<skill-name>/...
|
|
scripts/...
|
|
prompts/...
|
|
config/...
|
|
evidence/
|
|
provenance.jsonl
|
|
cost.json
|
|
scrub-attestation.json
|
|
tests.json
|
|
```
|
|
|
|
`content_hash` is `sha256:` over the normalized tarball with `content_hash` blanked before
|
|
hashing. Publish rejects hashes computed from a dirty or non-normalized bundle.
|
|
|
|
### `solution.yaml` source manifest
|
|
|
|
```yaml
|
|
schema_version: m2.solution.source.v1
|
|
solution_id: sol_mm-pdf-report
|
|
version: 1.0.0
|
|
name: MM PDF Report Generator
|
|
summary: Render Machine.Machine branded PDF and HTML reports from Markdown.
|
|
intent: Generate branded PDF/HTML deliverables from operator-authored Markdown.
|
|
seller: op_sdjs
|
|
tenant_scope: m2-core
|
|
price:
|
|
model: fixed
|
|
amount: 25
|
|
currency: m2cr
|
|
license:
|
|
terms: "Per-operator install; commercial use inside owned/client workspaces permitted."
|
|
major_version_coverage: true
|
|
revenue_split:
|
|
platform_pct: 10
|
|
runtime:
|
|
harnesses: ["hermes", "openclaw"]
|
|
surfaces: ["desktop"]
|
|
adapter: m2core-sync
|
|
applicability:
|
|
image_classes: ["primus", "agent-latest"]
|
|
roles: ["operator", "research", "proposal"]
|
|
tool_requirements: ["bash", "docker", "google-chrome-in-target"]
|
|
deployment:
|
|
recipe_ref: recipe.yaml
|
|
entrypoint: "mm-pdf generate <input.md> [--out output.pdf] [--style dark|purple|light]"
|
|
verify_command: "mm-pdf --version || test -x ~/.local/bin/mm-pdf"
|
|
behavior:
|
|
skills:
|
|
- payload/skills/mm-pdf/SKILL.md
|
|
tools:
|
|
- name: docker
|
|
purpose: render inside target m2o container
|
|
permissions_ref: permissions.yaml
|
|
evidence_ref: evidence/provenance.jsonl
|
|
```
|
|
|
|
Publish renders this into frozen `m2.solution.v1` by copying known schema fields and placing
|
|
extra source-only fields such as `version` only in `listing.solution_version` and release tag.
|
|
|
|
### `recipe.yaml`
|
|
|
|
```yaml
|
|
schema_version: m2.recipe.v1
|
|
adapter: m2core-sync
|
|
install_ref: lst_mm-pdf-report-v1.0.0
|
|
targets:
|
|
- id: skill
|
|
type: directory
|
|
source: payload/skills/mm-pdf
|
|
dest: "${AGENT_HOME}/.claude/skills/mm-pdf"
|
|
mode: "0755"
|
|
- id: command
|
|
type: file
|
|
source: payload/scripts/mm-pdf
|
|
dest: "${AGENT_HOME}/.local/bin/mm-pdf"
|
|
mode: "0755"
|
|
config_merge: []
|
|
post_install:
|
|
- "mkdir -p ${AGENT_HOME}/.local/bin"
|
|
verify:
|
|
- "test -f ${AGENT_HOME}/.claude/skills/mm-pdf/SKILL.md"
|
|
- "test -x ${AGENT_HOME}/.local/bin/mm-pdf"
|
|
uninstall:
|
|
- "rm -rf ${AGENT_HOME}/.claude/skills/mm-pdf"
|
|
- "rm -f ${AGENT_HOME}/.local/bin/mm-pdf"
|
|
rollback:
|
|
strategy: restore_backups
|
|
note: m2core-sync records file backups before replacement and restores by changeset_hash.
|
|
```
|
|
|
|
Rules:
|
|
|
|
- destinations must be under `${AGENT_HOME}`, `${M2_HOME}`, or a declared per-solution data
|
|
directory; host-level writes are rejected for marketplace MVP
|
|
- no recipe command may contain inline secrets, tokens, or absolute tenant paths
|
|
- install and uninstall must be idempotent
|
|
- verify commands must be offline-safe and deterministic
|
|
- adapter must run canary-first when installing fleet-wide
|
|
|
|
### `permissions.yaml`
|
|
|
|
```yaml
|
|
schema_version: m2.permissions.v1
|
|
permissions:
|
|
- id: fs-write-agent-home
|
|
kind: filesystem
|
|
scope: "${AGENT_HOME}/.claude/skills/mm-pdf"
|
|
access: write
|
|
reason: install skill files
|
|
- id: docker-exec-local
|
|
kind: command
|
|
scope: "docker exec <selected m2o container>"
|
|
access: execute
|
|
reason: render PDF through Chrome inside a desktop container
|
|
- id: memory-read
|
|
kind: memory
|
|
scope: "market:evidence"
|
|
access: write
|
|
reason: emit install/invoke telemetry
|
|
```
|
|
|
|
Rendered `solution.permissions[]` objects are displayed as the install permissions diff in
|
|
CLI and M2 Store.
|
|
|
|
### Evidence contracts
|
|
|
|
`evidence/provenance.jsonl`:
|
|
|
|
```json
|
|
{"source":"fedlearn:submissions/sub_2026w27_chris_01hxyz","machine":"chris-m2o","session":"herdr-run-2026-07-01T12:00:00Z","excerpt":"Generated branded PDF from Markdown using Chrome headless.","tokens":12000,"wall_time":480}
|
|
```
|
|
|
|
`evidence/cost.json`:
|
|
|
|
```json
|
|
{
|
|
"schema_version": "m2.solution.cost.v1",
|
|
"solution_id": "sol_mm-pdf-report",
|
|
"samples": 3,
|
|
"build_cost": {"tokens": 180000, "wall_time_seconds": 7200, "credits_equivalent": 18},
|
|
"invoke_cost_estimate": {"tokens": 1000, "wall_time_seconds": 90, "credits_equivalent": 1},
|
|
"maintenance_cost_estimate": {"credits_per_minor": 5},
|
|
"source_refs": ["market:evidence/mm-pdf-2026w27"]
|
|
}
|
|
```
|
|
|
|
`evidence/scrub-attestation.json`:
|
|
|
|
```json
|
|
{
|
|
"schema_version": "m2.scrub.v1",
|
|
"tenant_scope": "m2-core",
|
|
"owner_initiated": true,
|
|
"double_scrubbed": true,
|
|
"secret_scan": "passed",
|
|
"pii_scan": "passed",
|
|
"reviewers": ["op_builder", "op_reviewer"],
|
|
"reviewed_at": "2026-07-02T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
Install/invoke telemetry is appended locally, then summarized to `market:evidence`:
|
|
|
|
```json
|
|
{
|
|
"schema_version": "m2.solution.telemetry.v1",
|
|
"event_id": "evt_<uuid>",
|
|
"event": "install|uninstall|upgrade|invoke",
|
|
"operator_id": "op_buyer",
|
|
"tenant": "m2-core",
|
|
"listing_id": "lst_mm-pdf-report",
|
|
"solution_version": "1.0.0",
|
|
"machine": "chris-m2o",
|
|
"result": "success|failed|rolled_back",
|
|
"wall_time": 12.4,
|
|
"tokens": 0,
|
|
"credits": 25,
|
|
"error_class": null
|
|
}
|
|
```
|
|
|
|
### CLI verbs
|
|
|
|
Builder:
|
|
|
|
- `m2-market package init --from-skill <path> --id <solution_id> --name <name>`
|
|
- `m2-market package import-fedlearn --cluster <cluster_id> --out solutions/<slug>`
|
|
- `m2-market package validate <bundle-dir> [--strict-tenant]`
|
|
- `m2-market package build <bundle-dir> --out dist/<install_ref>.tar.gz`
|
|
- `m2-market publish <bundle-dir> --seller <operator_id> --price <credits>`
|
|
|
|
Buyer:
|
|
|
|
- `m2-market install <listing_id> [--yes]`
|
|
- `m2-market uninstall <listing_id> [--yes]`
|
|
- `m2-market upgrade <listing_id> [--to <semver>]`
|
|
- `m2-market invoke <listing_id> -- <args>` optional wrapper that records invoke telemetry
|
|
|
|
Admin/review:
|
|
|
|
- `m2-market package diff-permissions <old-bundle> <new-bundle>`
|
|
- `m2-market package evidence-summary <bundle-dir>`
|
|
- `m2-market package verify-release <install_ref>`
|
|
|
|
### Install/uninstall/upgrade sequence
|
|
|
|
Install:
|
|
|
|
1. Resolve listing from `market:catalog`; fetch registry `solution.json`.
|
|
2. License hook: `GET /licenses/check?operator_id=<op>&listing_id=<listing>&major=<n>`.
|
|
3. If no valid grant: `POST /tx/install` with price, seller, platform cut, and ref.
|
|
4. Download release tarball by `listing.install_ref`.
|
|
5. Verify `content_hash`.
|
|
6. Adapter preflight: `m2-core-sync plan --bundle <tar> --license-grant <grant_id>`.
|
|
7. Apply: `m2-core-sync apply --bundle <tar> --state ~/.m2-market/state.json`.
|
|
8. Verify recipe.
|
|
9. Write install state and telemetry.
|
|
|
|
Uninstall:
|
|
|
|
1. Confirm installed state exists.
|
|
2. Run `m2-core-sync uninstall --install-ref <ref>` or adapter rollback by `changeset_hash`.
|
|
3. Verify declared uninstall checks.
|
|
4. Mark `rolled_back`; do not revoke license by default.
|
|
5. Emit telemetry.
|
|
|
|
Upgrade:
|
|
|
|
1. Resolve latest published listing version with same listing id.
|
|
2. Check major license coverage through ledger.
|
|
3. Compute permission and recipe diff.
|
|
4. Require confirmation if permissions broaden.
|
|
5. Apply upgrade changeset; rollback to prior version on verify failure.
|
|
6. Emit telemetry.
|
|
|
|
### License check hook
|
|
|
|
Required m2-ledger endpoints consumed by S5 install path:
|
|
|
|
```http
|
|
GET /licenses/check?operator_id=op_buyer&listing_id=lst_mm-pdf-report&major=1
|
|
200 {"valid":true,"grant_id":"gr_...","covers_major":1}
|
|
404 {"valid":false}
|
|
|
|
POST /tx/install
|
|
{"buyer":"op_buyer","listing_id":"lst_mm-pdf-report","seller":"op_sdjs","amount":25,"currency":"m2cr","ref":"lst_mm-pdf-report:chris-m2o:<uuid>"}
|
|
200 {"tx_ids":[1,2],"grant":{"grant_id":"gr_...","covers_major":1}}
|
|
|
|
POST /tx/refund
|
|
{"ref":"lst_mm-pdf-report:chris-m2o:<uuid>","reason":"apply_failed"}
|
|
200 {"refunded":true}
|
|
```
|
|
|
|
The adapter must receive `grant_id` during plan/apply. A bundle apply without a valid grant
|
|
must fail before any file writes.
|
|
|
|
## 4. Integration contract with other subsystems
|
|
|
|
- S1 ledger: S5 calls `/licenses/check`, `/tx/install`, `/tx/refund`; ledger grants remain
|
|
authoritative for reinstall/upgrade.
|
|
- S2 catalog: S5 emits valid `listing.json` and `solution.json`; S2 indexes merged registry
|
|
records into `market:catalog` and folds telemetry into stats.
|
|
- S3 store: S3 shows `invoke.md`, evidence, price, and permission diff from S5 bundle
|
|
metadata; install button shells `m2-market install --json`.
|
|
- S4 Scout: S4 proposals deep-link to listing ids; S5 guarantees install refs and invocation
|
|
hints exist after install.
|
|
- S6 proposal engine: S6 consumes `evidence/cost.json`, provenance, price model, and invoke
|
|
docs for build-vs-install comparisons.
|
|
- fedlearn: fedlearn `commercialize` calls `m2-market package import-fedlearn`; staged
|
|
provenance and applicability map directly into `solution.evidence[]` and `applicability`.
|
|
- m2-core-sync: S5 recipe is the marketplace-specific payload fed to the universal runtime
|
|
sync/apply path. Until fedlearn rails land, the existing `ApplyAdapter` local path can
|
|
execute the same recipe shape.
|
|
- memory-api: S5 writes only summarized package evidence to `market:evidence`; raw tenant
|
|
data stays out of shared memory.
|
|
- Forgejo: PR labels are `market:listing`, `status:in_review`, `risk:<low|medium|high>`,
|
|
`veto-until:<timestamp>`, optional `approved`, optional `veto`.
|
|
|
|
## 5. Options compared
|
|
|
|
### Source manifest format
|
|
|
|
- JSON only: aligns with schemas, poor for human packaging.
|
|
- YAML source rendered to JSON: best authoring ergonomics while preserving frozen schema.
|
|
- Python package metadata: too language-specific.
|
|
|
|
Recommendation: YAML source plus canonical JSON output.
|
|
|
|
### Install backend
|
|
|
|
- Direct local file copy: good interim adapter, weak as long-term universal fleet path.
|
|
- m2-core-sync: matches locked runtime-sync decision and mixed image constraint.
|
|
- Container image install: rejected for MVP; local registry route is broken and secrets must
|
|
not be baked.
|
|
|
|
Recommendation: recipe contract targets `m2core-sync`; local adapter may execute same recipe
|
|
while fedlearn rails are incomplete.
|
|
|
|
### Pricing model per package
|
|
|
|
- Fixed install: deterministic and supported by frozen schema.
|
|
- Job price: required by locked decision, but current JSON Schema only enum-validates
|
|
`fixed`.
|
|
|
|
Recommendation: MVP bundles with direct install use `fixed`. Job-priced packages are listed
|
|
as `inventory_type: service` or use `price_ext.model: job` in `solution.yaml` until
|
|
`solution.schema.json` v2 adds `job`.
|
|
|
|
### Evidence storage
|
|
|
|
- Evidence embedded only in `solution.json`: too shallow for audit.
|
|
- Evidence files beside registry listing: reviewable, indexed, and durable.
|
|
- Memory-only evidence: not authoritative.
|
|
|
|
Recommendation: registry evidence files are truth; memory `market:evidence` is derived and
|
|
summarized.
|
|
|
|
## 6. Seed Solution package specs
|
|
|
|
### Seed 1 — `mm-pdf`
|
|
|
|
Source asset: `/home/m2/.claude/skills/mm-pdf`.
|
|
|
|
```yaml
|
|
solution_id: sol_mm-pdf-report
|
|
listing_id: lst_mm-pdf-report
|
|
version: 1.0.0
|
|
name: MM PDF Report Generator
|
|
price: {model: fixed, amount: 25, currency: m2cr}
|
|
category: documents
|
|
tenant_scope: m2-core
|
|
install_targets:
|
|
- "${AGENT_HOME}/.claude/skills/mm-pdf"
|
|
- "${AGENT_HOME}/.local/bin/mm-pdf"
|
|
entrypoint: "mm-pdf generate <input.md> [--out output.pdf] [--style dark|purple|light]"
|
|
```
|
|
|
|
Bundle contents:
|
|
|
|
- `payload/skills/mm-pdf/SKILL.md`
|
|
- `payload/skills/mm-pdf/templates/dark.css`
|
|
- `payload/skills/mm-pdf/templates/purple.css`
|
|
- `payload/scripts/mm-pdf` wrapper that calls skill script `generate.sh`
|
|
- `recipe.yaml`, `permissions.yaml`, `invoke.md`, `evidence/*`
|
|
|
|
Permissions:
|
|
|
|
- write skill directory under `${AGENT_HOME}`
|
|
- write executable under `${AGENT_HOME}/.local/bin`
|
|
- execute `docker ps`, `docker exec`, `docker cp` against local m2o container
|
|
- write output PDFs/HTML only to user-selected working directory
|
|
- no network secrets; no tenant memory reads required
|
|
|
|
Runtime deps:
|
|
|
|
- bash, docker CLI on host/container
|
|
- target m2o container with Node/npm and Google Chrome; observed `nasr-m2o` has this
|
|
- optional Marp path for slides later, not required for MVP
|
|
|
|
Install targets:
|
|
|
|
- primus and agent-latest desktops
|
|
- canaries: `chris-m2o` first, `gunnar-m2o` second
|
|
|
|
Evidence:
|
|
|
|
- skill file path and script provenance from `/home/m2/.claude/skills/mm-pdf`
|
|
- successful local render transcript
|
|
- cost sample for Markdown-to-PDF runs
|
|
|
|
### Seed 2 — `agent-scaffold`
|
|
|
|
Source asset: `/home/m2/.claude/skills/agent-scaffold`.
|
|
|
|
```yaml
|
|
solution_id: sol_agent-scaffold
|
|
listing_id: lst_agent-scaffold
|
|
version: 1.0.0
|
|
name: Agent Workspace Scaffold
|
|
price: {model: fixed, amount: 35, currency: m2cr}
|
|
category: agent-ops
|
|
tenant_scope: m2-core
|
|
install_targets:
|
|
- "${AGENT_HOME}/.claude/skills/agent-scaffold"
|
|
- "${AGENT_HOME}/.local/bin/agent-scaffold"
|
|
entrypoint: "agent-scaffold <agent-name> \"<what this agent does>\" [--out <dir>]"
|
|
```
|
|
|
|
Bundle contents:
|
|
|
|
- `payload/skills/agent-scaffold/SKILL.md`
|
|
- `payload/skills/agent-scaffold/scripts/scaffold.py`
|
|
- `payload/scripts/agent-scaffold` wrapper around `python3 scaffold.py`
|
|
- `payload/templates/PRD.md.j2`, `SOUL.md.j2`, `MEMORY.md.j2` only if extracted from script
|
|
in a future cleanup; MVP may keep script-generated templates inline
|
|
- `invoke.md` documenting env vars `M2_MEMORY_API_URL`, `M2_MEMORY_AGENT_ID`,
|
|
`M2_MEMORY_API_KEY`
|
|
|
|
Permissions:
|
|
|
|
- write `~/agents/<agent-name>/PRD.md`, `SOUL.md`, `MEMORY.md`
|
|
- read memory-api through configured endpoint and `X-API-Key`
|
|
- no raw client data export; memory query runs under buyer tenant/agent id
|
|
- optional write to git is manual, not automated in MVP
|
|
|
|
Runtime deps:
|
|
|
|
- Python 3 standard library
|
|
- memory-api reachable from desktop or host; live endpoint verified healthy
|
|
- `M2_MEMORY_API_KEY` injected at runtime, never packaged
|
|
|
|
Install targets:
|
|
|
|
- primus and agent-latest desktops
|
|
- Hermes/OpenClaw compatible as a CLI/skill, not harness-specific
|
|
|
|
Evidence:
|
|
|
|
- source skill and script from `/home/m2/.claude/skills/agent-scaffold`
|
|
- sample scaffold output with no tenant-specific content
|
|
- wall-time/token estimate from memory query and local file generation
|
|
|
|
### Seed 3 — `competitor-scan`
|
|
|
|
Source asset: no canonical local skill found; package as a new outcome bundle from proven
|
|
research-report workflow, with first implementation as prompts + scripts rather than a
|
|
tenant-derived artifact.
|
|
|
|
```yaml
|
|
solution_id: sol_competitor-scan
|
|
listing_id: lst_competitor-scan
|
|
version: 1.0.0
|
|
name: Competitor Scan Report
|
|
price: {model: fixed, amount: 60, currency: m2cr}
|
|
category: research
|
|
tenant_scope: m2-core
|
|
install_targets:
|
|
- "${AGENT_HOME}/.claude/skills/competitor-scan"
|
|
- "${AGENT_HOME}/.local/bin/competitor-scan"
|
|
entrypoint: "competitor-scan \"<company or market>\" --out report.md [--pdf]"
|
|
```
|
|
|
|
Bundle contents:
|
|
|
|
- `payload/skills/competitor-scan/SKILL.md` with research workflow:
|
|
scope, source collection, competitor matrix, positioning, pricing, risks, citations,
|
|
recommendations
|
|
- `payload/prompts/competitor-scan.md`
|
|
- `payload/scripts/competitor-scan` orchestrator:
|
|
accepts subject, writes `report.md`, optionally calls `mm-pdf` if installed
|
|
- `payload/templates/report.md`
|
|
- `recipe.yaml`, `permissions.yaml`, `invoke.md`, `evidence/*`
|
|
|
|
Permissions:
|
|
|
|
- network egress for web research through approved tools/connectors only
|
|
- read/write local report output directory
|
|
- optional memory read for prior public market research under buyer tenant
|
|
- no raw tenant CRM/doc access by default
|
|
- if using browser automation, permission must be explicit and shown in install diff
|
|
|
|
Runtime deps:
|
|
|
|
- Hermes or OpenAI-wire harness through m2-gpt
|
|
- approved search/browser connector where available
|
|
- optional `mm-pdf` installed for PDF output
|
|
|
|
Install targets:
|
|
|
|
- primus and agent-latest desktops
|
|
- initial canary should be non-client tenant or `m2-core` only until evidence is scrubbed
|
|
|
|
Evidence:
|
|
|
|
- generic public-market sample only
|
|
- citations list in output fixture
|
|
- cost telemetry from a dry-run scan: LLM tokens, wall time, number of sources
|
|
|
|
Pricing note:
|
|
|
|
- fixed install price `60 m2cr` for the reusable workflow
|
|
- a human/operator-delivered bespoke competitor scan should be a separate service listing
|
|
with job pricing once schema v2 supports `price.model: job`
|
|
|
|
## 7. Risks/edge cases
|
|
|
|
- Tenant leakage: reject tenant-scoped bundles without owner initiation and double scrub;
|
|
competitor-scan must not package client-specific examples as seed evidence.
|
|
- Secrets in payload: deterministic scanner blocks API keys, JWTs, SSH keys, high-entropy
|
|
strings, `.env`, browser profiles, and absolute secret paths.
|
|
- License/apply split brain: if debit succeeds and apply fails, CLI must call refund and
|
|
record failed install telemetry; grant without apply remains visible for audit.
|
|
- Upgrade permission creep: any broadened permission requires explicit confirmation and PR
|
|
review note.
|
|
- Uninstall data loss: recipes may remove installed files but must not delete user-created
|
|
output directories unless declared as disposable cache.
|
|
- Host fragility: install recipes are canary-first, idempotent, reversible, and confined to
|
|
agent home paths.
|
|
- Local registry route is broken: packages are Forgejo release assets, not Docker images or
|
|
registry pushes.
|
|
- Job pricing mismatch: locked business decision allows job pricing, but frozen schema only
|
|
validates `fixed`; represent jobs as service inventory until schema v2.
|
|
- Fake evidence: registry PR requires provenance files and at least one reproducible verify
|
|
or sample output; catalog/memory evidence is not authoritative.
|
|
|
|
## 8. [NEEDS CLARIFICATION]
|
|
|
|
1. Which operator id is the seller of record for the three seed Solutions: `op_sdjs`,
|
|
`op_m2bd`, or a platform-owned `op_m2-core`?
|
|
2. Should `competitor-scan` MVP be install-only fixed price, or should it launch as the first
|
|
service/job listing despite the frozen `solution.schema.json` only accepting fixed price?
|
|
3. What exact `m2-core-sync` command names will fedlearn ship for uninstall and upgrade
|
|
(`uninstall`, `rollback`, `apply --upgrade`), so S5 can replace adapter placeholders
|
|
without aliasing?
|