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
14 changes: 8 additions & 6 deletions ARCHIVE_MANIFEST.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"name": "prophet-cli archive spine",
"version": "0.1.0",
"updated_at": "2026-04-12",
"version": "0.1.1",
"updated_at": "2026-08-03",
"purpose": "Preserve repo memory, handoff continuity, and execution status inside the facade repository.",
"tracks": [
"docs/RUNNING_ARCHIVE.md",
"docs/SESSION_WORKLOG.md",
"docs/IMPLEMENTATION_STATUS.md"
],
"helpers": [
"scripts/init-upstream-repo.sh",
"scripts/package-running-archive.sh"
"runtime_legibility": [
"prophet status"
],
"notes": [
"Facade-first repository; bootstrap business logic remains delegated.",
"This manifest tracks in-repo working memory only and is not a runtime ledger."
"This manifest tracks in-repo working memory only and is not a runtime ledger.",
"The three tracked documents are current-state, not aspiration: if declared here, they exist.",
"'prophet status' is the runtime twin of docs/IMPLEMENTATION_STATUS.md.",
"Command-scoped '--receipt' output is facade-local and is not the estate ProofArtifact spine."
]
}
16 changes: 16 additions & 0 deletions docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@
### Workflow
- `prophet a2a run`

### Diagnostics
- `prophet doctor` — probe delegate engine readiness.
- `prophet status` — façade boundary legibility: enumerates every top-level surface
as `real` / `delegating` / `scaffold`, names each delegate engine, and probes which
engines are installed on PATH. Read-only; the runtime twin of
[IMPLEMENTATION_STATUS.md](IMPLEMENTATION_STATUS.md).

## Delegated-action receipts
Pass `--receipt <path>` on any delegating command to write a small, command-scoped
JSON receipt (schema `prophet-cli/receipt/v0`) recording command, delegate, status,
args, timing, and any error. If `<path>` is a directory it receives a timestamped
file; otherwise it is treated as a file path. Receipts are **façade-local** convenience
artifacts — aligned conceptually with the estate ProofArtifact idea but **not** that
spine and **not** a runtime ledger. A receipt-write failure never masks the delegated
result.

## Hybrid overlay placeholders
- `prophet ask`
- `prophet plan`
Expand Down
62 changes: 62 additions & 0 deletions docs/IMPLEMENTATION_STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Implementation Status

Current-state snapshot of the `prophet-cli` façade. This file is repo-local working
memory: it records what the command surface actually does today — real vs delegating
vs scaffold — so an operator or next agent can orient without re-deriving it from source.

- **Repo role:** façade only. See [REPO_ROLE.md](REPO_ROLE.md). We own command grammar,
wrapper definitions, docs, and surface-shape tests. We do **not** own bootstrap engine
logic, transport internals, receipt/enrollment semantics, or ReleaseSet/ConfigSource/TokenDoor.
- **Language/toolchain:** Go 1.22, Cobra. Build: `go build ./...`. Test: `go test ./...`.
- **Last updated:** 2026-08-03

## Boundary legend

| kind | meaning |
| --- | --- |
| `real` | executes locally in the façade with no external engine required |
| `delegating` | shells out to a named engine binary (or a local-dev repo fallback); reports `not-yet-wired`/`not-yet-installed` when the engine is absent |
| `scaffold` | placeholder surface; emits `status: scaffold` and mutates nothing |

The live boundary is queryable at runtime: `prophet status` enumerates the same surfaces
and probes which delegate engines are installed. This document is the human-readable twin.

## Top-level surface

| command | kind | delegate engine | notes |
| --- | --- | --- | --- |
| `version` / `doctor` / `self-test` / `emit-evidence` | real | — | suite diagnostics, façade-local |
| `status` | real | — | boundary legibility + delegate presence probe |
| `bootstrap` | delegating | `sourceos-bootstrap` | engine home: `sourceos-sdk/cmd/sourceos-bootstrap` |
| `vocab` | delegating | ontogenesis vocab surface | fetch/gate/promote/sr |
| `bindings` | delegating | atomic bindings engine | validate |
| `k8s` | delegating | k8s policy engine | scheduling checks |
| `control-node` | delegating | local control-node | status/local-first |
| `a2a` | scaffold | — | workflow façade skeleton |
| `devtools` / `lab` | delegating | `sourceos-devtools` | profile/lab management; `not-yet-wired` |
| `sourceos install` | delegating | `sourceos-installer` | `not-yet-wired` |
| `sourceos carry` | delegating | `sourceos-ai` | list/validate/doctor/emit-evidence |
| `holmes` | delegating | `holmes` | analyze/search/graph/govern |
| `model route` | delegating | `model-router` | local-dev python fallback |
| `guardrail test` | delegating | `guardrail-fabric` | local-dev python fallback |
| `ledger` | delegating | `model-governance-ledger` | validate/records; local-dev fallback |
| `agent registry` | delegating | `agent-registry` | list; local-dev record fallback |
| `spine` | delegating | per-repo spine gates | validate gates (`--repo`) |
| `enrichment` | delegating | enrichment twin | corpus/lifecycle/gate |
| `ask` / `plan` / `mcp` | scaffold | — | agent-assist / MCP boundary placeholders |

## Delegate engines (external, not owned here)

`sourceos-bootstrap`, `sourceos-ai`, `sourceos-devtools`, `sourceos-installer`, `holmes`,
`model-router`, `guardrail-fabric`, `model-governance-ledger`, `agent-registry`.

Delegating commands resolve engines via `exec.LookPath`, then a local-dev repo fallback
rooted at `$PROPHET_DEV_ROOT` (default `~/dev/<repo>`). Absence is reported, never faked.

## Known gaps / next weakest link

- `devtools`, `lab`, and `sourceos install` are declared but return `not-yet-wired` — the
façade grammar is ahead of engine wiring for these surfaces.
- `a2a`, `ask`, `plan`, `mcp` are scaffolds only.
- Receipts (`--receipt`) are façade-local and command-scoped; they are **not** the estate
ProofArtifact spine and must not be treated as a runtime ledger.
22 changes: 22 additions & 0 deletions docs/RUNNING_ARCHIVE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Running Archive

Index of `prophet-cli` repo-local working memory. This is the umbrella the
[`ARCHIVE_MANIFEST.json`](../ARCHIVE_MANIFEST.json) tracks: it points at the live
current-state and continuity documents so a next agent has one entry point.

## Tracks

- [IMPLEMENTATION_STATUS.md](IMPLEMENTATION_STATUS.md) — current-state snapshot of the
command surface: real vs delegating vs scaffold, delegate engines, known gaps.
- [SESSION_WORKLOG.md](SESSION_WORKLOG.md) — append-only per-session change/verification log.
- RUNNING_ARCHIVE.md — this index.

## Discipline

- **Current-state, not aspiration.** If the manifest declares a track, the file exists.
- **Verify before you commit.** Record the exact green-gate used (build/vet/test invocation).
- **Façade boundary is load-bearing.** This repo owns command grammar and docs only; engine
logic, transport, and receipt/enrollment semantics live in the engine repos. See
[REPO_ROLE.md](REPO_ROLE.md).
- **Runtime vs working memory.** This archive is in-repo working memory. It is **not** a
runtime ledger and not the estate ProofArtifact spine.
40 changes: 40 additions & 0 deletions docs/SESSION_WORKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Session Worklog

Append-only working memory for `prophet-cli`. Newest entries on top. Each entry records
what changed, why, and the verification gate — so continuity survives across agents and
sessions without re-reading the whole git history.

---

## 2026-08-03 — façade legibility uplift (memory spine, `prophet status`, receipts)

**Base:** `origin/main` @ `3eab3eb` (docs(ops): add archive spine manifest, #54).

**Context / verification first:**
- PRs #1–#8 and the governed-runner/enrichment/spine series (#39–#55) confirmed **merged**.
- `main` is a real Go/Cobra façade (`go.mod` → cobra 1.8.1); `go build ./...` green.
- Branch `copilot/enhance-documentation-metadata` is **stale**: 61 commits behind main,
a single 2026-04-09 doc commit, no open PR. Its docs/a2a work is superseded by main's
evolution → **planning mode: supersede, do not duplicate**.
- PR #55 ("unify dev/CLI/SDK tools") merged into `wip/muster-20260630`, **not** main; that
Python lineage is divergent and out of scope for this façade uplift.
- Test note: `go test ./...` aborts under macOS with `dyld: missing LC_UUID` (toolchain/OS
linker issue). Green-gate used here is `go test -ldflags=-linkmode=external ./...` +
`go vet ./...`, both clean.

**Added (narrow, façade-fit only):**
1. Repo-memory spine: this worklog, `docs/IMPLEMENTATION_STATUS.md`, `docs/RUNNING_ARCHIVE.md`
— the three tracks already **declared** by `ARCHIVE_MANIFEST.json` but previously missing.
Manifest updated to reflect reality (helpers list corrected, `updated_at` bumped).
2. `prophet status`: façade diagnostics — enumerates delegation targets, façade vs engine
boundary, and probes which delegate engines are installed (real vs stubbed). No platform
semantics; read-only.
3. Command-scoped delegated-action receipts (`internal/receipt`, opt-in `--receipt <path>`):
small machine-readable JSON aligned *conceptually* with the estate ProofArtifact idea but
kept façade-local. The spine is **not** imported.

**Deliberately excluded (belong in engine repos):** bootstrap business logic, flake/host
mutation, backend/registry/route/io/task ownership, broad policy engine, the ProofArtifact
spine itself.

**Gate:** `go build ./...` OK; `go vet ./...` OK; `go test -ldflags=-linkmode=external ./...` OK.
4 changes: 4 additions & 0 deletions internal/cmd/fabric_fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os/exec"
"path/filepath"
"strings"
"time"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -44,13 +45,16 @@ func delegateOrFallback(tool string, toolArgs []string, command string, fallback
}

func runDelegate(path string, tool string, args []string, command string) error {
started := time.Now()
run := exec.Command(path, args...)
var stdout, stderr bytes.Buffer
run.Stdout = &stdout
run.Stderr = &stderr
if err := run.Run(); err != nil {
emitReceipt(command, tool, "failed", args, started, err)
return emit(map[string]any{"command": command, "status": "failed", "delegate": tool, "stdout": stdout.String(), "stderr": stderr.String(), "error": err.Error()})
}
emitReceipt(command, tool, "ok", args, started, nil)
return emit(map[string]any{"command": command, "status": "ok", "delegate": tool, "stdout": stdout.String(), "stderr": stderr.String()})
}

Expand Down
28 changes: 28 additions & 0 deletions internal/cmd/receipts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"fmt"
"os"
"time"

"github.com/socioprophet/prophet-cli/internal/receipt"
)

// emitReceipt writes a façade-local receipt for a delegated action when the
// operator passed --receipt. It never alters the command's own exit behavior:
// a receipt-write failure is surfaced on stderr but does not mask the delegated
// result. Receipts are convenience artifacts, not the estate ProofArtifact spine.
func emitReceipt(command, delegate, status string, args []string, started time.Time, execErr error) {
if flags.Receipt == "" {
return
}
r := receipt.New(command, delegate, status, args, started, time.Now(), execErr)
path, err := receipt.Write(flags.Receipt, r)
if err != nil {
fmt.Fprintf(os.Stderr, "prophet: receipt not written: %v\n", err)
return
}
if !flags.Quiet {
fmt.Fprintf(os.Stderr, "prophet: receipt %s\n", path)
}
}
3 changes: 3 additions & 0 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type GlobalFlags struct {
Quiet bool
Debug bool
NoPager bool
Receipt string
}

var flags GlobalFlags
Expand All @@ -36,11 +37,13 @@ func NewRootCommand() *cobra.Command {
root.PersistentFlags().BoolVarP(&flags.Quiet, "quiet", "q", false, "suppress non-essential output")
root.PersistentFlags().BoolVar(&flags.Debug, "debug", false, "enable debug output")
root.PersistentFlags().BoolVar(&flags.NoPager, "no-pager", false, "disable pager")
root.PersistentFlags().StringVar(&flags.Receipt, "receipt", "", "write a façade-local JSON receipt for delegated actions (file path or directory)")
root.AddCommand(
newSuiteVersionCmd(),
newSuiteDoctorCmd(),
newSuiteSelfTestCmd(),
newSuiteEvidenceCmd(),
newStatusCmd(),
newBootstrapCmd(),
newVocabCmd(),
newBindingsCmd(),
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "testing"
func TestRootCommandHasExpectedTopLevelCommands(t *testing.T) {
root := NewRootCommand()
want := map[string]bool{
"status": false,
"bootstrap": false,
"vocab": false,
"bindings": false,
Expand Down
123 changes: 123 additions & 0 deletions internal/cmd/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package cmd

import (
"os/exec"
"sort"

"github.com/spf13/cobra"
)

// surfaceKind classifies a façade surface against the engine boundary.
type surfaceKind string

const (
// kindReal executes locally in the façade with no external engine required.
kindReal surfaceKind = "real"
// kindDelegating shells out to a named engine binary (or local-dev fallback).
kindDelegating surfaceKind = "delegating"
// kindScaffold is a placeholder surface that mutates nothing.
kindScaffold surfaceKind = "scaffold"
)

// surfaceDescriptor is the façade's own account of one top-level surface. This is
// curated boundary knowledge (the façade is the source of truth for its own shape),
// kept in one place so it stays reviewable and honest. It is the machine twin of
// docs/IMPLEMENTATION_STATUS.md.
type surfaceDescriptor struct {
Command string `json:"command"`
Kind surfaceKind `json:"kind"`
Delegate string `json:"delegate,omitempty"`
Note string `json:"note"`
}

// facadeSurfaces returns the boundary map for the top-level command surface.
func facadeSurfaces() []surfaceDescriptor {
return []surfaceDescriptor{
{"version", kindReal, "", "suite version, façade-local"},
{"doctor", kindReal, "", "suite readiness checks"},
{"self-test", kindReal, "", "lightweight surface self-test"},
{"emit-evidence", kindReal, "", "suite local evidence"},
{"status", kindReal, "", "façade boundary legibility (this command)"},
{"bootstrap", kindDelegating, "sourceos-bootstrap", "engine home: sourceos-sdk/cmd/sourceos-bootstrap"},
{"vocab", kindDelegating, "ontogenesis", "fetch/gate/promote/sr"},
{"bindings", kindDelegating, "atomic-bindings", "validate"},
{"k8s", kindDelegating, "k8s-policy", "scheduling checks"},
{"control-node", kindDelegating, "control-node", "local-first control-node"},
{"devtools", kindDelegating, "sourceos-devtools", "profile management; not-yet-wired"},
{"lab", kindDelegating, "sourceos-devtools", "functional ML labs; not-yet-wired"},
{"sourceos", kindDelegating, "sourceos-installer", "install; carry delegates to sourceos-ai"},
{"holmes", kindDelegating, "holmes", "analyze/search/graph/govern"},
{"model", kindDelegating, "model-router", "route; local-dev python fallback"},
{"guardrail", kindDelegating, "guardrail-fabric", "test; local-dev python fallback"},
{"ledger", kindDelegating, "model-governance-ledger", "validate/records; local-dev fallback"},
{"agent", kindDelegating, "agent-registry", "registry list; local-dev record fallback"},
{"spine", kindDelegating, "spine-gates", "per-repo validate gates (--repo)"},
{"enrichment", kindDelegating, "enrichment-twin", "corpus/lifecycle/gate"},
{"a2a", kindScaffold, "", "workflow façade skeleton"},
{"ask", kindScaffold, "", "agent assist placeholder"},
{"plan", kindScaffold, "", "agent assist placeholder"},
{"mcp", kindScaffold, "", "MCP boundary placeholder"},
}
}

func newStatusCmd() *cobra.Command {
return &cobra.Command{
Use: "status",
Short: "Show façade boundary: delegation targets, engine presence, stubbed vs real",
Long: "Report the façade's own boundary: which surfaces execute locally (real), " +
"which delegate to an external engine, and which are scaffolds. For delegating " +
"surfaces the delegate engine binary is probed on PATH so an operator can see " +
"what is actually wired vs stubbed. Read-only; no platform semantics.",
RunE: func(cmd *cobra.Command, args []string) error {
surfaces := facadeSurfaces()

// Probe each distinct delegate engine once for presence on PATH.
engineState := map[string]any{}
present, missing := 0, 0
for _, s := range surfaces {
if s.Delegate == "" {
continue
}
if _, seen := engineState[s.Delegate]; seen {
continue
}
if path, err := exec.LookPath(s.Delegate); err == nil {
engineState[s.Delegate] = map[string]any{"status": "present", "path": path}
present++
} else {
engineState[s.Delegate] = map[string]any{"status": "missing"}
missing++
}
}

counts := map[string]int{"real": 0, "delegating": 0, "scaffold": 0}
for _, s := range surfaces {
counts[string(s.Kind)]++
}

engines := make([]string, 0, len(engineState))
for name := range engineState {
engines = append(engines, name)
}
sort.Strings(engines)

return emit(map[string]any{
"command": "prophet status",
"status": "ok",
"repo": "SocioProphet/prophet-cli",
"role": "facade",
"boundary": "Owns command grammar and docs. Delegates engine logic, transport, and receipt/enrollment semantics to engine repos.",
"surfaces": surfaces,
"engines": engineState,
"summary": map[string]any{
"surfaces_total": len(surfaces),
"real": counts["real"],
"delegating": counts["delegating"],
"scaffold": counts["scaffold"],
"engines_present": present,
"engines_missing": missing,
},
})
},
}
}
Loading
Loading