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
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,59 @@ Retirement is a one-time manual cleanup. There is no helper script: this stack o

After this, the only outbound message path is `agents/dispatch-message` → DMC CLI runtime → bridge CLI. If you weren't running the legacy webhook to begin with (every install of wp-coding-agents from v0.5.x onward), skip the migration entirely — the bridge registrations land on a clean disk.

## Worktree Session Attribution (Runtime Signatures)

When a coding-agent session asks Data Machine Code to create a worktree, DMC captures **origin-session metadata** so the worktree carries a breadcrumb back to the session that spawned it (Discord thread URL, opencode session ID, run ID, etc.). DMC reads that metadata from environment variables the runtime sets on the worktree-creating process.

The env-var names are vendor-specific (`KIMAKI_SESSION_ID`, `OPENCODE_SESSION_ID`, `OPENCODE_RUN_ID`, …) so DMC cannot enumerate them without knowing about kimaki and opencode — a layer-purity violation per the platform's coding rules. The fix (Extra-Chill/data-machine-code#416) moves the env-var → field map out of DMC into a filter:

```php
apply_filters( 'datamachine_code_worktree_runtime_signatures', [] );
```

wp-coding-agents is the integration layer that knows about kimaki and opencode — it installs both, writes the systemd units that pass those env vars into the spawned processes, and is the only honest place those brand names live. So **wp-coding-agents owns the registration.**

### How it wires up

On install (and every `upgrade.sh` run), each runtime/bridge writes its signature into a mu-plugin file at:

```
$WP_PATH/wp-content/mu-plugins/wp-coding-agents-runtimes.php
```

The file is owned end-to-end by wp-coding-agents installers: created on first registration, each runtime contributes a marker-delimited block (`// BEGIN runtime:<id>` … `// END runtime:<id>`), and the same install path can rewrite or remove its block idempotently. The file registers entries via the filter:

```php
$signatures['kimaki'] = [
'session_id' => 'KIMAKI_SESSION_ID',
'thread_id' => 'KIMAKI_THREAD_ID',
'thread_url' => 'KIMAKI_THREAD_URL',
];

$signatures['opencode'] = [
'session_id' => 'OPENCODE_SESSION_ID',
'run_id' => 'OPENCODE_RUN_ID',
];
```

DMC reads the map, walks each runtime's subkeys, and sniffs the named env vars at worktree-create time. The subkey set is open — DMC does not validate against a closed schema. Conventional subkeys are `session_id`, `thread_id`, `thread_url`, `run_id`; integrations may add more.

### Registered signatures

| Runtime ID | Subkey | Env var | What it identifies |
|-------------|--------------|------------------------|-----------------------------------------------------|
| `kimaki` | `session_id` | `KIMAKI_SESSION_ID` | Kimaki session (1:1 with a Discord thread) |
| `kimaki` | `thread_id` | `KIMAKI_THREAD_ID` | Discord thread the session lives in |
| `kimaki` | `thread_url` | `KIMAKI_THREAD_URL` | Deep link to that Discord thread |
| `opencode` | `session_id` | `OPENCODE_SESSION_ID` | opencode session inside the kimaki/opencode runtime |
| `opencode` | `run_id` | `OPENCODE_RUN_ID` | Specific opencode run within that session |

Adding a new runtime is a one-liner: register a new block in the relevant `runtimes/<name>.sh` or `bridges/<name>.sh` via `runtime_signature_register <runtime_id> <signature_json>` (see `lib/runtime-signature.sh`).

### Layer purity

**The brand names live here on purpose.** wp-coding-agents is the integration plugin and the only place in the stack that should know about specific coding-agent runtimes. If you ever see DMC ship code that names `kimaki`, `opencode`, `KIMAKI_*`, or `OPENCODE_*` directly, **that is a layer-purity violation and should be filed against DMC, not patched here.** DMC must stay runtime-agnostic; vendor naming is wp-coding-agents' job.

## Requirements

**VPS:**
Expand Down
26 changes: 26 additions & 0 deletions bridges/kimaki.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ bridge_install() {

_kimaki_sync_bin_helpers
_kimaki_register_cli_channel
_kimaki_register_runtime_signature
}

# _kimaki_register_cli_channel
Expand Down Expand Up @@ -88,6 +89,26 @@ _kimaki_register_cli_channel() {
"600"
}

# _kimaki_register_runtime_signature
#
# Publish kimaki's worktree session-attribution env-var contract for the Data
# Machine Code worktree-attribution code (Extra-Chill/data-machine-code#416).
# kimaki sets KIMAKI_SESSION_ID, KIMAKI_THREAD_ID, and KIMAKI_THREAD_URL on
# the opencode-serve children it spawns (see Kimaki source). DMC reads those
# env vars at worktree-create time to record which kimaki session originated
# the worktree, what Discord thread the session lives in, and the deep link
# to that thread.
#
# The registration is data, not config: the runtime ID 'kimaki' is what
# wp-coding-agents *calls* the runtime here, and the env-var names are what
# the kimaki binary actually sets. DMC stays naive — it doesn't know kimaki
# exists; it just sniffs whatever env vars the filter map tells it to.
_kimaki_register_runtime_signature() {
runtime_signature_register \
"kimaki" \
'{"session_id":"KIMAKI_SESSION_ID","thread_id":"KIMAKI_THREAD_ID","thread_url":"KIMAKI_THREAD_URL"}'
}

_kimaki_sync_bin_helpers() {
[ -d "$SCRIPT_DIR/bridges/kimaki/bin" ] || return 0

Expand Down Expand Up @@ -400,6 +421,11 @@ bridge_sync_config() {
# the latest adapter path (npm-global moves between hosts).
_kimaki_register_cli_channel

# Refresh the worktree runtime-signature registration. Idempotent — only
# touches disk when the env-var map drifts (e.g. a new subkey is added in
# a future kimaki release).
_kimaki_register_runtime_signature

log " Done."

# Export resolved paths so print_summary can reference them
Expand Down
Loading
Loading