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
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# agentplane

Agentplane is the tenant-side control and execution plane for local-first and hybrid agents.

This repository is not the local supervisor and it is not the canonical wire-spec repository. Instead, it is the remote control-plane and worker-plane complement to the device-local runtime.

## What already exists here

The current repository already contains useful runtime artifact scaffolds and local-state conventions:

- `schemas/session-artifact.schema.v0.1.json`
- `schemas/promotion-artifact.schema.v0.1.json`
- `schemas/reversal-artifact.schema.v0.1.json`
- `schemas/bundle.schema.patch.json`
- `state/pointers/.keep`
- `.gitignore` rules for local `artifacts/` and machine-local pointer state

Those files tell us two important things:

1. Agentplane already assumes evidence-bearing runtime artifacts.
2. Agentplane already assumes machine-local pointer state should not be committed.

## Repository role

Agentplane owns the **tenant-side** parts of the first local-hybrid slice:

- gateway and ingress policy handoff for remote-eligible tasks
- capability resolution from logical capability ID to worker binding
- worker runtime envelopes for remote execution
- promotion and reversal semantics for future side-effecting flows
- tenant-side evidence handoff hooks

Agentplane does **not** own:

- the local supervisor runtime (`sociosphere`)
- the canonical deterministic transport and fixtures (`TriTRPC`)
- the shared cross-repo contract canon (`socioprophet-standards-storage`)

## Planned layout

- `docs/` — architecture notes, slice definitions, repo map
- `gateway/` — tenant ingress and policy-gated dispatch adapters
- `capability-registry/` — logical capability descriptors and bindings
- `worker-runtime/` — tenant execution wrappers and runtime contracts
- `schemas/` — artifact schemas and patch fragments used by runtime flows

## Current implementation stance

The first slice is deliberately narrow:

- local-first planning and retrieval
- optional tenant execution only after policy approval
- typed capability resolution
- evidence append and replay/cairn materialization
- no public-provider egress by default
- no generic multi-agent prompt soup

See `docs/local_hybrid_slice_v0.md` for the execution slice and `docs/repository_map.md` for cross-repo boundaries.
12 changes: 12 additions & 0 deletions capability-registry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# capability-registry

Logical capability descriptors and runtime bindings live here.

Initial responsibilities:

- map capability IDs to execution bindings
- record execution-lane constraints
- record timeout and context limits
- record side-effect posture and credential scope requirements

The first concrete example to support is a narrow capability such as `summarize.abstractive.v1`.
33 changes: 33 additions & 0 deletions capability-registry/examples/summarize.abstractive.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"capabilityId": "summarize.abstractive.v1",
"version": "1.0.0",
"kind": "analysis",
"description": "Deterministic stub binding for abstractive summarization with risk extraction.",
"inputSchemaRef": "org.socioprophet.capabilities.v1.SummarizeInput",
"outputSchemaRef": "org.socioprophet.capabilities.v1.SummarizeOutput",
"execution": {
"supportedLanes": ["local", "tenant"],
"defaultLane": "local",
"requiresGpu": false,
"maxContextBytes": 16384,
"timeoutSeconds": 60
},
"trust": {
"egressDefault": "deny",
"sideEffectsDefault": "deny",
"dataLabelsAllowed": ["public", "internal", "tenant_confidential"],
"dataLabelsDenied": ["regulated_export_controlled"]
},
"policyHooks": {
"preExec": ["policy.v1.Decision/Evaluate"],
"postExec": ["evidence.v1.Event/Append"]
},
"binding": {
"capabilityInstanceId": "capinst.summarize.abstractive.v1.stub",
"executionLane": "tenant",
"workerEndpoint": "tritrpc://tenant/summarize-01",
"workerContract": "worker.v1.Capability/Execute",
"credentialScope": "task-scoped",
"bindingTtlSeconds": 120
}
}
53 changes: 53 additions & 0 deletions capability-registry/resolve_binding_stub.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Minimal capability resolution stub for the first local-hybrid slice.

This script resolves a logical capability descriptor into a runtime binding.
It intentionally uses only the Python standard library so it can run in a bare
repository checkout.
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


def load_descriptor(path: Path) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8"))


def resolve_binding(descriptor: dict[str, Any], requested_lane: str | None = None) -> dict[str, Any]:
execution = descriptor.get("execution", {})
binding = descriptor.get("binding", {})
supported_lanes = execution.get("supportedLanes", [])
lane = requested_lane or binding.get("executionLane") or execution.get("defaultLane")
if lane not in supported_lanes:
raise ValueError(f"unsupported lane: {lane!r}; supported={supported_lanes!r}")
return {
"resolved": True,
"binding": {
"capabilityInstanceId": binding["capabilityInstanceId"],
"executionLane": lane,
"workerEndpoint": binding["workerEndpoint"],
Comment on lines +32 to +33
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep execution lane consistent with worker endpoint

When requested_lane is provided, this code rewrites executionLane but always keeps the single binding["workerEndpoint"] value. For descriptors that advertise multiple lanes (for example local + tenant), requesting local currently returns a binding labeled local that still points at the tenant endpoint, which can route work to the wrong execution environment and produce incorrect policy/provenance signals. The resolver should either select lane-specific endpoint data or reject lane overrides when only one lane-specific binding exists.

Useful? React with 👍 / 👎.

"workerContract": binding["workerContract"],
"credentialScope": binding["credentialScope"],
"bindingTtlSeconds": binding["bindingTtlSeconds"],
},
}


def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("descriptor", type=Path)
parser.add_argument("--lane", default=None)
args = parser.parse_args()
descriptor = load_descriptor(args.descriptor)
result = resolve_binding(descriptor, requested_lane=args.lane)
print(json.dumps(result, indent=2, sort_keys=True))
return 0


if __name__ == "__main__":
raise SystemExit(main())
98 changes: 98 additions & 0 deletions docs/local_hybrid_slice_v0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Local-Hybrid Slice v0

## Purpose

This document freezes the first end-to-end execution slice for Agentplane.

The slice is intentionally narrow. It exists to prove the architecture, not to implement every capability class at once.

## Scope

The first slice is:

- a local-first request enters the device-local supervisor
- local retrieval and local task planning run first
- policy decides whether any remote execution is permitted
- Agentplane resolves a remote capability when policy allows it
- a tenant worker executes the bound capability
- evidence is appended
- a replay/cairn handle is materialized

## Seven-method lifecycle

1. `supervisor.v1.Session/Open`
2. `supervisor.v1.Task/Plan`
3. `policy.v1.Decision/Evaluate`
4. `control.v1.Capability/Resolve`
5. `worker.v1.Capability/Execute`
6. `evidence.v1.Event/Append`
7. `replay.v1.Cairn/Materialize`

Agentplane owns the tenant-side responsibilities for steps 4 and 5 directly, and may mirror or participate in 3 and 6 where tenant policy and evidence relays are required.

## What Agentplane already has

The repo already contains artifact schema scaffolds for:

- session artifacts
- promotion artifacts
- reversal artifacts
- bundle spec patch fields for runtime behavior

These are useful because they establish the repo as a runtime artifact plane rather than only a conceptual architecture bucket.

## What Agentplane must add next

### Gateway

The gateway is the tenant ingress for remote-eligible work. It should:

- accept already-classified and policy-scoped work from the local supervisor
- validate capability binding requests
- reject out-of-policy egress or side-effect requests
- emit tenant-side evidence handoff events

### Capability registry

The capability registry maps a logical capability ID to an execution binding. A binding should minimally describe:

- capability instance ID
- worker endpoint
- supported execution lanes
- timeout and context limits
- side-effect posture
- required credentials or scopes

### Worker runtime

The worker runtime wraps the remote execution contract. It should:

- execute only typed capability payloads
- run with scoped credentials
- record input and output digests
- emit provenance metadata suitable for evidence append

## Relation to existing schemas

The existing artifact schemas are not wasted work. They align with the future execution lifecycle as follows:

- `session-artifact.schema.v0.1.json` supports session-level receipts and replay references
- `promotion-artifact.schema.v0.1.json` supports later promotion/review flows for side-effecting actions
- `reversal-artifact.schema.v0.1.json` supports rollback/reversal for promoted changes
- `bundle.schema.patch.json` already introduces runtime-oriented fields such as `sessionPolicyRef`, `skillRefs`, `memoryNamespace`, `worktreeStrategy`, `rolloutFlags`, `telemetrySink`, and `receiptSchemaVersion`

## Non-goals for v0

- generalized autonomous multi-agent swarms
- unconstrained public-provider model egress
- long-lived secret material inside workers
- untyped prompt-only worker contracts
- cloud-first session authority

## Immediate follow-on work

1. Add gateway scaffolding.
2. Add capability-registry scaffolding.
3. Add worker-runtime scaffolding.
4. Add examples that bind a single capability such as `summarize.abstractive.v1`.
5. Align shared schemas and fixtures with `TriTRPC` and `socioprophet-standards-storage`.
66 changes: 66 additions & 0 deletions docs/repository_map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Agentplane Repository Map

## Cross-repo ownership

### Agentplane

Tenant-side control and execution responsibilities:

- gateway and remote ingress
- capability resolution and binding
- tenant worker runtime wrappers
- promotion and reversal runtime artifacts
- tenant-side evidence relay hooks

### Sociosphere

Device-local orchestration responsibilities:

- local supervisor
- local planning, retrieval, and execution precedence
- deterministic multi-repo orchestration

### TriTRPC

Deterministic transport and fixture responsibilities:

- method and envelope canon
- fixture vectors
- verification and repack invariants
- cross-language interoperability surface

### socioprophet-standards-storage

Shared contracts and measurement responsibilities:

- shared schemas
- benchmark definitions
- storage and interface standards
- governance and portability measurements

## Internal layout for Agentplane

### `schemas/`
Runtime artifact schemas and patch fragments.

### `docs/`
Architecture notes and slice definitions.

### `gateway/`
Tenant ingress for remote-eligible work.

### `capability-registry/`
Logical capability descriptors and runtime bindings.

### `worker-runtime/`
Tenant worker execution wrappers and contract adapters.

## First-slice sequence boundary

- `supervisor.v1.Session/Open` — local
- `supervisor.v1.Task/Plan` — local
- `policy.v1.Decision/Evaluate` — local first, tenant mirror optional
- `control.v1.Capability/Resolve` — tenant
- `worker.v1.Capability/Execute` — tenant
- `evidence.v1.Event/Append` — shared with local precedence
- `replay.v1.Cairn/Materialize` — local first
42 changes: 42 additions & 0 deletions evidence/append_event_stub.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""Deterministic evidence append stub for the first local-hybrid slice."""

from __future__ import annotations

import argparse
import hashlib
import json
from pathlib import Path
from typing import Any


def load_json(path: Path) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8"))


def canonical_bytes(value: Any) -> bytes:
return json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")


def append_event(payload: dict[str, Any]) -> dict[str, Any]:
event = payload.get("event", payload)
digest = hashlib.sha256(canonical_bytes(event)).hexdigest()
journal_offset = int(digest[:12], 16)
return {
"appended": True,
"journalOffset": journal_offset,
"evidenceDigest": f"sha256:{digest}",
}


def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("payload", type=Path)
args = parser.parse_args()
result = append_event(load_json(args.payload))
print(json.dumps(result, indent=2, sort_keys=True))
return 0


if __name__ == "__main__":
raise SystemExit(main())
12 changes: 12 additions & 0 deletions gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# gateway

Tenant ingress for policy-scoped remote work.

Initial responsibilities:

- accept remote-eligible work only after policy approval upstream
- validate capability binding requests
- reject side-effecting or out-of-policy execution attempts
- emit tenant-side evidence relay events

This directory is a scaffold for the first local-hybrid slice and should stay narrow until the typed execution path is implemented.
Loading
Loading