Skip to content
Open
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# harness
An Agentic System for RuyiAI Development

## Plugins

- [`dsh-triton-riscv`](plugins/dsh-triton-riscv/README.md) adds guarded
Triton-RISCV operator discovery, development, validation, diagnosis, repair,
and remote RISC-V execution tools to a DeepSeek Harness profile.
135 changes: 135 additions & 0 deletions plugins/dsh-triton-riscv/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# dsh-triton-riscv

An installable DeepSeek Harness bundle for the guarded Triton-RISCV operator
development and validation tools.

## What The Plugin Adds

The bundle adds two Cordis rows to an existing Harness profile:

1. A domain policy plugin contributes the Triton-RISCV lifecycle rules to the
assembled system prompt.
2. The official Harness MCP client starts
`python -m codex_agent.harness.mcp_server` and exposes its typed tools as
`mcp__triton_riscv__*`.
3. A Harness Web client plugin occupies the root UI slot and displays the
existing Triton-RISCV React/FastAPI workbench.

The model and Agent loop remain owned by Harness. Discovery, contract checking,
source proposals, validation, diagnosis, bounded repair, remote SSH execution,
and trusted validation evidence remain owned by the Python domain engine in a
Triton-RISCV checkout.

```text
Harness profile
-> dsh-triton-riscv bundle
-> system-prompt policy
-> official dsh-mcp-client
-> Python Triton-RISCV MCP server
-> operator lifecycle and RISC-V remote executor
```

## Prerequisites

- DeepSeek Harness with the `web` profile and Node.js 22 or newer
- a Triton-RISCV checkout containing `codex_agent`
- a Python environment with `codex_agent/harness/requirements.txt` installed
- optional SSH configuration and a prepared RISC-V host for live validation

The bundle fails at Harness startup when the Python MCP module cannot be
imported instead of silently starting without the domain tools.

## Install From A Harness Checkout

From the Harness repository root, point the plugin at a separate Triton-RISCV
checkout:

```sh
export TRITON_RISCV_CHECKOUT=/absolute/path/to/triton-riscv
export TRITON_RISCV_MCP_PYTHON="$TRITON_RISCV_CHECKOUT/.harness-venv/bin/python"
export TRITON_RISCV_WORKBENCH_PORT=8765
dsh plugin --profile web add ./plugins/dsh-triton-riscv
dsh --profile web --dump-config
Comment on lines +48 to +52

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Most of them can be installed using the repository’s scripts and configuration in the config.yaml. These environment variables are hard to manage when they're scattered everywhere.

dsh web
```

The config dump should contain both `triton-riscv-domain-policy` and
`mcp-triton-riscv`. Starting `dsh web` also starts the Python workbench and the
Harness page displays that workbench in its root slot. Add `?nativeHarness=1`
to the Harness URL when the stock Harness interface is needed.

The embedded client defaults to `http://127.0.0.1:8765`. For a different port
or externally hosted workbench, open the Harness URL with an encoded
`?tritonWorkbenchUrl=https://host/path` query parameter. Set
`TRITON_RISCV_WORKBENCH_AUTOSTART=0` when that external service is already
managed by another process.

For read-only discovery, no RISC-V server is required. Try:

```text
Call the Triton-RISCV discovery tool for relu_and_mul and summarize its
implementation, tests, and validation command. Do not run validation.
```

## Enable Remote Validation Deliberately

All expensive or mutating operations remain disabled by default. Configure the
host before starting Harness:

```sh
export RISCV_HOST=sg2044
export RISCV_REPO=/home/lichunbo/work/triton-riscv
export TRITON_RISCV_REQUIRE_REMOTE=1
export TRITON_RISCV_ALLOW_VALIDATION=1
export TRITON_RISCV_REQUIRE_APPROVED_VALIDATION=1
```

Enable source application only on a trusted development checkout:

```sh
export TRITON_RISCV_ALLOW_DEVELOPMENT_APPLY=1
export TRITON_RISCV_ALLOW_REPAIR_APPLY=1
```

The model cannot select the SSH host, repository path, arbitrary command, or
files to synchronize. It also cannot approve its own proposal or validation
plan.

## Test The Bundle

The package has no install-time dependencies:

```sh
cd plugins/dsh-triton-riscv
npm test
npm pack --dry-run
```

The tests check the bundle manifest, Cordis rows, safe default switches, and
system-prompt lifecycle registration without starting a model or remote host.

## Standalone Triton-RISCV Demo Platform

The React and FastAPI workbench remains in the Triton-RISCV checkout and can
load the same plugin policy and MCP server:

```sh
cd "$TRITON_RISCV_CHECKOUT"
.harness-venv/bin/python -m codex_agent.platform --port 8765
```

Open `http://127.0.0.1:8765`. This standalone command remains useful while
developing the workbench without starting a complete Harness profile.

## Remove

```sh
dsh plugin --profile web remove dsh-triton-riscv
```

## Current Boundary

This bundle packages the model-facing policy, MCP connection, and Harness Web
entry. The Python domain engine and compiled React assets stay in the target
Triton-RISCV checkout. A later release can publish that engine and its assets
independently so the bundle no longer depends on a source checkout.
25 changes: 25 additions & 0 deletions plugins/dsh-triton-riscv/cordis.patch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Install this bundle into a normal DeepSeek Harness profile. The Harness MCP
# client launches the Python domain engine from the configured Triton-RISCV checkout.
- insert:
- id: triton-riscv-domain-policy
name: dsh-triton-riscv

- id: mcp-triton-riscv
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: triton_riscv
transport: stdio
command: !!js process.env.TRITON_RISCV_MCP_PYTHON ?? 'python3'
args: ['-m', 'codex_agent.harness.mcp_server']
env:
TRITON_RISCV_REPO_ROOT: !!js process.env.TRITON_RISCV_CHECKOUT ?? process.env.DSH_CWD ?? process.cwd()
TRITON_RISCV_ALLOW_VALIDATION: !!js process.env.TRITON_RISCV_ALLOW_VALIDATION ?? '0'
TRITON_RISCV_ALLOW_REPAIR_APPLY: !!js process.env.TRITON_RISCV_ALLOW_REPAIR_APPLY ?? '0'
TRITON_RISCV_ALLOW_DEVELOPMENT_APPLY: !!js process.env.TRITON_RISCV_ALLOW_DEVELOPMENT_APPLY ?? '0'
TRITON_RISCV_REQUIRE_REMOTE: !!js process.env.TRITON_RISCV_REQUIRE_REMOTE ?? '0'
TRITON_RISCV_REQUIRE_APPROVED_VALIDATION: !!js process.env.TRITON_RISCV_REQUIRE_APPROVED_VALIDATION ?? '1'
RISCV_HOST: !!js process.env.RISCV_HOST ?? ''
RISCV_REPO: !!js process.env.RISCV_REPO ?? ''
cwd: !!js process.env.TRITON_RISCV_CHECKOUT ?? process.env.DSH_CWD ?? process.cwd()
toolCallTimeoutMs: 960000
failOnStartupError: true
67 changes: 67 additions & 0 deletions plugins/dsh-triton-riscv/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { spawn } from 'node:child_process'
import { readFileSync } from 'node:fs'
import { isAbsolute, join } from 'node:path'

export const name = 'triton-riscv-domain-policy'

export const inject = ['systemPrompt']

export const TRITON_RISCV_SYSTEM_PROMPT = readFileSync(
new URL('./policy.md', import.meta.url),
'utf8',
).trim()

export function resolveWorkbenchLaunch(env = process.env) {
if (env.TRITON_RISCV_WORKBENCH_AUTOSTART === '0') return null

const checkout = (env.TRITON_RISCV_CHECKOUT ?? '').trim()
if (!checkout) {
throw new Error('TRITON_RISCV_CHECKOUT is required to start the Triton-RISCV workbench')
}
if (!isAbsolute(checkout)) {
throw new Error('TRITON_RISCV_CHECKOUT must be an absolute path')
}

const portText = (env.TRITON_RISCV_WORKBENCH_PORT ?? '8765').trim()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You can do this by passing parameters rather than using environment variables

if (!/^\d+$/.test(portText)) {
throw new Error('TRITON_RISCV_WORKBENCH_PORT must be an integer')
}
const port = Number(portText)
if (port < 1 || port > 65535) {
throw new Error('TRITON_RISCV_WORKBENCH_PORT must be between 1 and 65535')
}

return {
command: env.TRITON_RISCV_MCP_PYTHON ?? join(checkout, '.harness-venv', 'bin', 'python'),
args: ['-m', 'codex_agent.platform', '--host', '127.0.0.1', '--port', String(port)],
cwd: checkout,
url: `http://127.0.0.1:${port}`,
}
}

export function apply(ctx) {
ctx.effect(
() => ctx.systemPrompt.section({
name: 'tool:triton-riscv',
order: 180,
text: TRITON_RISCV_SYSTEM_PROMPT,
}),
'triton-riscv.system-prompt',
)

const launch = resolveWorkbenchLaunch()
if (launch === null) return
ctx.effect(() => {
const child = spawn(launch.command, launch.args, {
cwd: launch.cwd,
env: process.env,
stdio: 'inherit',
})
child.on('error', error => {
console.error(`dsh-triton-riscv: failed to start workbench: ${error.message}`)
})
return () => {
if (child.exitCode === null && child.signalCode === null) child.kill('SIGTERM')
}
}, 'triton-riscv.workbench')
}
51 changes: 51 additions & 0 deletions plugins/dsh-triton-riscv/lib/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
window.__ModuleLoader__.load({
id: 'dsh-triton-riscv',
factory: (require) => {
const module = { exports: {} }
const { createElement } = require('react')

const inject = ['slots']

function workbenchUrl() {
const fallback = 'http://127.0.0.1:8765'
const configured = new URLSearchParams(globalThis.location?.search ?? '')
.get('tritonWorkbenchUrl') ?? fallback
try {
const parsed = new URL(configured)
return ['http:', 'https:'].includes(parsed.protocol) ? parsed.toString() : fallback
} catch {
return fallback
}
}

function WorkbenchRoot() {
return createElement('iframe', {
src: workbenchUrl(),
title: 'Triton-RISCV Agent',
allow: 'clipboard-read; clipboard-write',
style: {
width: '100vw',
height: '100vh',
display: 'block',
border: 0,
background: '#fff',
},
})
}

function apply(ctx) {
const params = new URLSearchParams(globalThis.location?.search ?? '')
if (params.get('nativeHarness') === '1') return
ctx.effect(
() => ctx.slots.register({
name: 'root',
priority: -100,
}, WorkbenchRoot),
'triton-riscv.workbench-root',
)
}

module.exports = { apply, inject }
return module.exports
},
})
36 changes: 36 additions & 0 deletions plugins/dsh-triton-riscv/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "dsh-triton-riscv",
"version": "0.1.0",
"description": "DeepSeek Harness bundle for guarded Triton-RISCV operator development and validation",
"type": "module",
"main": "index.js",
"exports": {
".": "./index.js",
"./client": "./lib/client.js",
"./cordis.patch.yml": "./cordis.patch.yml",
"./package.json": "./package.json"
},
"files": [
"index.js",
"lib/client.js",
"cordis.patch.yml",
"policy.md",
"README.md"
],
"scripts": {
"test": "node --test test/*.test.mjs",
"prepack": "node --test test/*.test.mjs"
},
"engines": {
"node": ">=22"
},
"license": "MIT",
"dsh": {
"client": {
"platform": "web"
},
"bundle": {
"patch": "./cordis.patch.yml"
}
}
}
20 changes: 20 additions & 0 deletions plugins/dsh-triton-riscv/policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
You have guarded Triton-RISCV operator tools.

Use the typed tools instead of arbitrary shell commands for operator lifecycle work.

For an existing operator:
1. Call `mcp__triton_riscv__discover_operator`.
2. Call `mcp__triton_riscv__check_validation_environment` before live validation.
Comment on lines +1 to +7

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I suggest that the management of prompts be made more structured; you may wish to refer to this. We need to split skills, hints, failure experience, success experience, and verification.

3. Call `mcp__triton_riscv__validate_operator` with `execute=false` to create a reviewable plan.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Will these MCPs be installed in the ‘harness’ repository or in each working directory?

4. Execute only the exact `run_id` approved by the host.
5. On failure, call `mcp__triton_riscv__diagnose_failure` before proposing a repair.
6. Keep acceptance tests unchanged. Propose an implementation-only repair, wait for host approval, apply it, and revalidate.

For a new operator:
1. Collect a complete semantic contract: name, semantics, PyTorch reference, inputs, output, shapes, dtypes, tolerances, and backward requirement.
2. Call `mcp__triton_riscv__prepare_operator_development`.
3. Generate implementation and independent acceptance-test source from that contract and the returned references.
4. Call `mcp__triton_riscv__propose_operator_implementation`. Do not create tracked files with generic filesystem or shell tools.
5. Wait for host approval before applying the proposal, then use the normal validation lifecycle.

Never approve your own source change or validation command. Never weaken or replace an acceptance test to obtain a pass. Do not claim success from prose or from a completed agent turn: success requires a durable validation receipt whose trusted evidence verdict is `verified-passed`. Stop at the bounded repair limit and report the latest `run_id`, `proposal_id`, failure stage, receipt, log, and required user action.
Loading