Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7d354ec
feat: add experimental OPC company lab
runesleo Aug 28, 2026
4568b18
feat: add OPC lab English guide
runesleo Aug 28, 2026
bcc3dd3
feat: add OPC governance schemas
runesleo Aug 28, 2026
b083c64
feat: add OPC semantic disposition schema
runesleo Aug 28, 2026
7c36cff
feat: add OPC role schema
runesleo Aug 28, 2026
afeabd3
feat: add OPC receipt schema
runesleo Aug 28, 2026
9ee042d
feat: add OPC handoff schema
runesleo Aug 28, 2026
8a47e5a
feat: add OPC organization schema
runesleo Aug 28, 2026
18761bd
feat: add OPC task schema
runesleo Aug 28, 2026
d3354cf
feat: add OPC verifier CLI
runesleo Aug 28, 2026
074bee3
test: cover OPC receipts ACK and failover
runesleo Aug 28, 2026
bb4f9ed
docs: add synthetic OPC company
runesleo Aug 28, 2026
bd99866
docs: add synthetic OPC roles
runesleo Aug 28, 2026
07492b1
docs: add synthetic OPC tasks
runesleo Aug 28, 2026
c0945ce
docs: add synthetic handoff task
runesleo Aug 28, 2026
994a604
docs: add valid OPC receipt
runesleo Aug 28, 2026
cc1f398
test: add false completion fixture
runesleo Aug 28, 2026
a0b712d
test: add rejected false completion receipt
runesleo Aug 28, 2026
2d9087e
test: add semantic ACK fixture
runesleo Aug 28, 2026
942285a
test: add missing semantic ACK receipt
runesleo Aug 28, 2026
fca1fc9
test: add quota failover fixture
runesleo Aug 28, 2026
5d995f1
test: add failover successor state
runesleo Aug 28, 2026
e8a8cf3
test: document quota failover invariant
runesleo Aug 28, 2026
f36ce34
fix: make OPC first-success commands portable
runesleo Aug 28, 2026
510d11f
fix: make OPC first-success commands portable
runesleo Aug 28, 2026
b4f64af
ci: verify experimental OPC company lab
runesleo Aug 28, 2026
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
35 changes: 35 additions & 0 deletions .github/workflows/opc-lab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: OPC Lab

on:
pull_request:
paths:
- 'labs/opc-company/**'
- 'scripts/verify.sh'
- 'README.md'
- 'README.en.md'
- '.github/workflows/opc-lab.yml'
workflow_dispatch:

jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify QuietHarness repository
run: ./scripts/verify.sh
- name: Verify OPC fixtures
run: python3 labs/opc-company/tests/run.py
- name: Parse OPC JSON
run: |
find labs/opc-company -name '*.json' -print0 | while IFS= read -r -d '' file; do
python3 -m json.tool "$file" >/dev/null
done
- name: Reject private or production identifiers
run: |
hits="$(grep -REn '(/(Users|home)/[^/]+|leo[-]vault|_[i]nventory|active[-]tasks|T[0-9]{3,}|thread[_ -]?id|session[_ -]?id|0x[a-fA-F0-9]{40})' labs/opc-company 2>/dev/null || true)"
if [ -n "$hits" ]; then
echo 'OPC_VERIFY_FAIL private or production pattern detected' >&2
echo "$hits" >&2
exit 1
fi
echo OPC_PRIVATE_SCAN_OK
30 changes: 30 additions & 0 deletions labs/opc-company/README.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# OPC Company Layer (experimental)

This is QuietHarness's company-scale governance lab, not another multi-agent framework.

QuietHarness focuses on reliable execution by one or a few agents. The OPC Company Layer focuses on durable ownership, canonical state, handoffs, acceptance, semantic ACKs, and worker failover across multiple long-lived agents.

## 10-minute first success

```bash
cd labs/opc-company
python3 scripts/opc.py status examples/synthetic-company

python3 scripts/opc.py verify \
--task fixtures/false-completion/task.json \
--receipt fixtures/false-completion/receipt.json
# expected: rejected

python3 scripts/opc.py verify \
--task examples/synthetic-company/tasks/product-release.json \
--receipt examples/synthetic-company/receipts/product-release.valid.json
# expected: PASS

python3 scripts/opc.py failover \
--before fixtures/quota-failover/task.before.json \
--after fixtures/quota-failover/task.after.json
# expected: same task, same owner, new worker, PASS
```

Public: protocols, schemas, synthetic fixtures, verifier.
Private: live business tasks, production topology, account bindings, schedulers, exact quota routing, trading alpha, credentials.
37 changes: 37 additions & 0 deletions labs/opc-company/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OPC Company Layer(实验性)

这是 QuietHarness 的公司级治理实验层,不是另一个“多 Agent 框架”。

QuietHarness 解决单个或少量 Agent 的可靠执行;OPC Company Layer 解决多个长期 Owner / Worker 如何共享事实、交接、验收,并在换模型或额度耗尽后继续同一任务。

## 10 分钟 First Success

```bash
cd labs/opc-company

python3 scripts/opc.py status examples/synthetic-company

# 1) Agent 自述完成,但没有 artifact / validation / owner writeback
python3 scripts/opc.py verify \
--task fixtures/false-completion/task.json \
--receipt fixtures/false-completion/receipt.json
# 预期:拒绝

# 2) 真实 receipt
python3 scripts/opc.py verify \
--task examples/synthetic-company/tasks/product-release.json \
--receipt examples/synthetic-company/receipts/product-release.valid.json
# 预期:PASS

# 3) Worker 额度耗尽,但任务不迁移
python3 scripts/opc.py failover \
--before fixtures/quota-failover/task.before.json \
--after fixtures/quota-failover/task.after.json
# 预期:同 task / 同 owner / 新 worker,PASS
```

## 公开边界

公开的是协议、schema、synthetic fixture 和 verifier。

不公开真实业务任务、生产 Owner 拓扑、账号绑定、scheduler、MCPX production 配置、额度路由、交易策略和其他 operational alpha。
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"organization_id":"synthetic-opc","roles":["ops","research","content","product"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"receipt_id":"receipt-product-release-1","task_id":"product-release","worker":"worker-b","outcome":"completed","artifacts":["artifacts/product-change.diff"],"validation":["tests: PASS"],"owner_writeback":true,"downstream_ack":null,"created_at":"2026-01-01T10:00:00Z"}
1 change: 1 addition & 0 deletions labs/opc-company/examples/synthetic-company/roles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"schema_version":1,"role_id":"ops","name":"Ops Owner","owner":"ops-owner","responsibilities":["governance","acceptance","recovery"]},{"schema_version":1,"role_id":"research","name":"Research Owner","owner":"research-owner","responsibilities":["research","source verification"]},{"schema_version":1,"role_id":"content","name":"Content Owner","owner":"content-owner","responsibilities":["drafting","release readiness"]},{"schema_version":1,"role_id":"product","name":"Product Owner","owner":"product-owner","responsibilities":["implementation","tests"]}]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"product-release","title":"Implement and verify a small product change","status":"active","owner":"product","primary_worker":"worker-a","claimed_by":"worker-a","claimed_at":"2026-01-01T09:00:00Z","next_action":"Implement the change and produce validation evidence.","updated_at":"2026-01-01T09:00:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":false}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"research-to-content","title":"Turn verified research into a content draft","status":"active","owner":"research","primary_worker":"worker-a","claimed_by":"worker-a","claimed_at":"2026-01-01T09:00:00Z","next_action":"Produce verified research artifact and hand it to Content Owner.","updated_at":"2026-01-01T09:00:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":true}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/false-completion/receipt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"receipt_id":"receipt-false-done","task_id":"product-release","worker":"worker-a","outcome":"completed","artifacts":[],"validation":[],"owner_writeback":false,"downstream_ack":null,"created_at":"2026-01-01T09:30:00Z"}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/false-completion/task.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"product-release","title":"Implement and verify a small product change","status":"active","owner":"product","primary_worker":"worker-a","claimed_by":"worker-a","claimed_at":"2026-01-01T09:00:00Z","next_action":"Implement the change and produce validation evidence.","updated_at":"2026-01-01T09:00:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":false}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/missing-ack/receipt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"receipt_id":"receipt-research-1","task_id":"research-to-content","worker":"worker-a","outcome":"completed","artifacts":["artifacts/research.md"],"validation":["sources: verified"],"owner_writeback":true,"downstream_ack":null,"created_at":"2026-01-01T09:30:00Z"}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/missing-ack/task.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"research-to-content","title":"Turn verified research into a content draft","status":"active","owner":"research","primary_worker":"worker-a","claimed_by":"worker-a","claimed_at":"2026-01-01T09:00:00Z","next_action":"Produce verified research artifact and hand it to Content Owner.","updated_at":"2026-01-01T09:00:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":true}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/quota-failover/failover.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"reason":"worker_quota_exhausted","from_worker":"worker-a","to_worker":"worker-b","same_task_id":true,"new_task_created":false,"canonical_state_preserved":true}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/quota-failover/task.after.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"product-release","title":"Implement and verify a small product change","status":"active","owner":"product","primary_worker":"worker-b","claimed_by":"worker-b","claimed_at":"2026-01-01T09:45:00Z","next_action":"Resume the same implementation batch from canonical task state; do not repeat completed work.","updated_at":"2026-01-01T09:45:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":false}
1 change: 1 addition & 0 deletions labs/opc-company/fixtures/quota-failover/task.before.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schema_version":1,"id":"product-release","title":"Implement and verify a small product change","status":"active","owner":"product","primary_worker":"worker-a","claimed_by":"worker-a","claimed_at":"2026-01-01T09:00:00Z","next_action":"Implement the change and produce validation evidence.","updated_at":"2026-01-01T09:00:00Z","artifacts":[],"decision_gate":null,"hard_gates_pending":[],"downstream_requires_ack":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/disposition.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/disposition.schema.json","title":"OPC Semantic Disposition","type":"object","required":["schema_version","message_id","consumer","status","decided_at"],"properties":{"schema_version":{"const":1},"message_id":{"type":"string","minLength":1},"consumer":{"type":"string","minLength":1},"status":{"enum":["ADOPTED","REJECTED","DEFERRED","DUPLICATE","UNKNOWN"]},"reason":{"type":"string"},"decided_at":{"type":"string","minLength":1}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/gate.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/gate.schema.json","title":"OPC Gate","type":"object","required":["schema_version","gate_id","kind","status"],"properties":{"schema_version":{"const":1},"gate_id":{"type":"string","minLength":1},"kind":{"enum":["human_approval","account","funds","publish","production","unknown"]},"status":{"enum":["OPEN","PASS","BLOCKED","UNKNOWN"]},"evidence":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/handoff.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/handoff.schema.json","title":"OPC Handoff","type":"object","required":["schema_version","handoff_id","task_id","from","to","body","created_at"],"properties":{"schema_version":{"const":1},"handoff_id":{"type":"string","minLength":1},"task_id":{"type":"string","minLength":1},"from":{"type":"string","minLength":1},"to":{"type":"string","minLength":1},"body":{"type":"string","minLength":1},"created_at":{"type":"string","minLength":1},"receipt_ref":{"type":["string","null"]}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/organization.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/organization.schema.json","title":"OPC Organization","type":"object","required":["schema_version","organization_id","roles"],"properties":{"schema_version":{"const":1},"organization_id":{"type":"string","minLength":1},"roles":{"type":"array","minItems":1,"items":{"type":"string","minLength":1},"uniqueItems":true}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/receipt.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/receipt.schema.json","title":"OPC Completion Receipt","type":"object","required":["schema_version","receipt_id","task_id","worker","outcome","artifacts","validation","owner_writeback","created_at"],"properties":{"schema_version":{"const":1},"receipt_id":{"type":"string","minLength":1},"task_id":{"type":"string","minLength":1},"worker":{"type":"string","minLength":1},"outcome":{"enum":["completed","blocked","negative_result","partial"]},"artifacts":{"type":"array","items":{"type":"string"}},"validation":{"type":"array","items":{"type":"string"}},"owner_writeback":{"type":"boolean"},"downstream_ack":{"type":["object","null"]},"created_at":{"type":"string","minLength":1}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/role.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/role.schema.json","title":"OPC Role","type":"object","required":["schema_version","role_id","name","owner","responsibilities"],"properties":{"schema_version":{"const":1},"role_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"owner":{"type":"string","minLength":1},"responsibilities":{"type":"array","minItems":1,"items":{"type":"string","minLength":1}}},"additionalProperties":false}
1 change: 1 addition & 0 deletions labs/opc-company/schemas/task.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://example.invalid/opc/task.schema.json","title":"OPC Task","type":"object","required":["schema_version","id","status","owner","primary_worker","next_action","updated_at","artifacts"],"properties":{"schema_version":{"const":1},"id":{"type":"string","minLength":1},"title":{"type":"string"},"status":{"enum":["active","waiting","monitoring","parked","archived"]},"owner":{"type":"string","minLength":1},"primary_worker":{"type":["string","null"]},"claimed_by":{"type":["string","null"]},"claimed_at":{"type":["string","null"]},"next_action":{"type":"string","minLength":1},"updated_at":{"type":"string","minLength":1},"artifacts":{"type":"array","items":{"type":"string"}},"decision_gate":{"type":["object","null"]},"hard_gates_pending":{"type":"array","items":{"type":"string"}},"downstream_requires_ack":{"type":"boolean","default":false}},"additionalProperties":true}
73 changes: 73 additions & 0 deletions labs/opc-company/scripts/opc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse, json
from pathlib import Path

VALID_STATUSES = {"active","waiting","monitoring","parked","archived"}

def read_json(path):
return json.loads(Path(path).read_text(encoding="utf-8"))

def lint_task(task):
errors=[]
for k in ("schema_version","id","status","owner","primary_worker","next_action","updated_at","artifacts"):
if k not in task: errors.append(f"missing:{k}")
if task.get("status") not in VALID_STATUSES: errors.append("invalid:status")
if task.get("claimed_by") and not task.get("claimed_at"): errors.append("claim_without_time")
if task.get("status") == "archived" and task.get("claimed_by"): errors.append("archived_but_claimed")
return errors

def cmd_lint(args):
errors=[]
for p in args.files:
obj=read_json(p)
if isinstance(obj, dict) and "status" in obj and "id" in obj:
errors += [f"{p}:{e}" for e in lint_task(obj)]
if errors:
for e in errors: print("OPC_LINT_ERROR", e)
return 1
print(f"OPC_LINT_OK files={len(args.files)}")
return 0

def cmd_status(args):
d=Path(args.company); tasks=[]
for p in sorted((d/"tasks").glob("*.json")): tasks.append(read_json(p))
active=[t for t in tasks if t.get("status")=="active"]
out={"task_count":len(tasks),"active_tasks":[t["id"] for t in active],"active_owners":sorted(set(t.get("owner") for t in active)),"pending_ack_tasks":[t["id"] for t in tasks if t.get("downstream_requires_ack")],"work_continuing":bool(active)}
print(json.dumps(out, indent=2)); return 0

def cmd_verify(args):
task=read_json(args.task); receipt=read_json(args.receipt); errors=[]
if receipt.get("task_id") != task.get("id"): errors.append("task_id_mismatch")
if receipt.get("outcome") == "completed":
if not receipt.get("artifacts"): errors.append("missing_artifact")
if not receipt.get("validation"): errors.append("missing_validation")
if receipt.get("owner_writeback") is not True: errors.append("missing_owner_writeback")
if task.get("downstream_requires_ack"):
ack=receipt.get("downstream_ack")
if not isinstance(ack, dict) or ack.get("status") not in {"ADOPTED","REJECTED","DEFERRED","DUPLICATE"}: errors.append("missing_semantic_ack")
if errors:
for e in errors: print("OPC_VERIFY_REJECT", e)
return 1
print("OPC_VERIFY_PASS"); return 0

def cmd_failover(args):
before=read_json(args.before); after=read_json(args.after); errors=[]
if before.get("id") != after.get("id"): errors.append("task_id_changed")
if before.get("owner") != after.get("owner"): errors.append("owner_changed")
if before.get("artifacts") != after.get("artifacts"): errors.append("artifacts_changed_during_failover")
if before.get("primary_worker") == after.get("primary_worker"): errors.append("worker_not_changed")
if errors:
for e in errors: print("OPC_FAILOVER_REJECT", e)
return 1
print(f"OPC_FAILOVER_PASS task={before.get('id')} from={before.get('primary_worker')} to={after.get('primary_worker')}"); return 0

def main():
ap=argparse.ArgumentParser(prog="opc"); sp=ap.add_subparsers(dest="cmd",required=True)
p=sp.add_parser("lint"); p.add_argument("files",nargs="+"); p.set_defaults(fn=cmd_lint)
p=sp.add_parser("status"); p.add_argument("company"); p.set_defaults(fn=cmd_status)
p=sp.add_parser("verify"); p.add_argument("--task",required=True); p.add_argument("--receipt",required=True); p.set_defaults(fn=cmd_verify)
p=sp.add_parser("failover"); p.add_argument("--before",required=True); p.add_argument("--after",required=True); p.set_defaults(fn=cmd_failover)
args=ap.parse_args(); raise SystemExit(args.fn(args))

if __name__=="__main__": main()
17 changes: 17 additions & 0 deletions labs/opc-company/tests/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env python3
from pathlib import Path
import subprocess, sys, json
ROOT=Path(__file__).resolve().parents[1]; OPC=ROOT/"scripts/opc.py"
def run(args, expected):
p=subprocess.run([sys.executable,str(OPC),*args],text=True,capture_output=True)
if p.returncode != expected:
print("TEST_FAIL",args,"expected",expected,"got",p.returncode); print(p.stdout,p.stderr); raise SystemExit(1)
return p.stdout
for p in ROOT.rglob("*.json"): json.loads(p.read_text())
out=run(["status",str(ROOT/"examples/synthetic-company")],0); assert '"work_continuing": true' in out
out=run(["verify","--task",str(ROOT/"fixtures/false-completion/task.json"),"--receipt",str(ROOT/"fixtures/false-completion/receipt.json")],1); assert "missing_artifact" in out and "missing_validation" in out and "missing_owner_writeback" in out
out=run(["verify","--task",str(ROOT/"fixtures/missing-ack/task.json"),"--receipt",str(ROOT/"fixtures/missing-ack/receipt.json")],1); assert "missing_semantic_ack" in out
out=run(["verify","--task",str(ROOT/"examples/synthetic-company/tasks/product-release.json"),"--receipt",str(ROOT/"examples/synthetic-company/receipts/product-release.valid.json")],0); assert "OPC_VERIFY_PASS" in out
out=run(["failover","--before",str(ROOT/"fixtures/quota-failover/task.before.json"),"--after",str(ROOT/"fixtures/quota-failover/task.after.json")],0); assert "OPC_FAILOVER_PASS" in out
task_files=[str(p) for p in (ROOT/"examples/synthetic-company/tasks").glob("*.json")]; out=run(["lint",*task_files],0); assert "OPC_LINT_OK" in out
print("OPC_TEST_OK")
Loading