Two pre-existing issues surfaced during sim e2e of a full debate:
1. **secret-mgr env injection**: backend-client's resolveApiKey ran
execSync('secret-mgr get dialectic-agent-apikey') without setting
AGENT_ID/AGENT_WORKSPACE/AGENT_VERIFY in the child env. The plugin
process inherits the openclaw gateway env (no agent context), so
secret-mgr refused with 'AGENT_VERIFY mismatch' and the error
surfaced to agents as the generic 'dialectic api key not provisioned'
(stderr was swallowed by stdio:'ignore'). Now we explicitly inject
the pcexec trio plus PATH=~/.openclaw/bin:..., capture stderr so
underlying failures are visible, and use the standard
~/.openclaw/workspace/workspace-<id> layout if AGENT_WORKSPACE
isn't already set.
2. **DIALECTIC_PLUGIN_BYPASS_HF=1 sim escape hatch**: HarborForge's
hasOnCallCovering returns false on sim (sim agents have no real
on_call slots), which blocks dialectic_signup before it ever reaches
the backend. Added an env-gated skip so sim/test environments can
run the full debate flow without provisioning real schedules.
Bypass is opt-in via env, so prod is unaffected.
E2e verified on sim dind-t2 (openclaw) + dind-t3 (backend):
- recruiter/main/simdev minted dialectic-agent-apikey
- propose_topic created topic
- 3 signups all 201
- ticker allocated pro=main, con=simdev, judge=recruiter
- pro+con posted arguments to round 0
- judge submitted binary verdict after debate_end_at, topic→completed
- view_verdict round-trips
Deploy note: jiti loader prefers .js over .ts when both are present in
src/, so updates that only change .ts need the colocated .js removed
(or properly rebuilt) before they take effect. The plugin still ships
src/*.js as pre-built artifacts; consider switching to .ts-only
sources or running 'npm run build' before deploy.
Operator decision: backend env hard-coding a single guild/channel was
wrong. Center can host multiple guilds, each can have multiple
announce channels for different purposes. The proposing agent picks
which one this topic broadcasts to.
dialectic_propose_topic tool schema adds:
- announce_guild_base_url (string, optional)
- announce_channel_id (string, optional)
- both or neither - one-of-two rejected at backend POST time
- omit both - topic has no broadcasts (agents must poll detail)
Tool description points agents at "Fabric channel-list tools" for
candidate discovery. Workflow docs spell out the discovery pattern.
7 tools total now:
- dialectic_list_topics
- dialectic_topic_detail
- dialectic_propose_topic
- dialectic_signup
- dialectic_post_argument
- dialectic_submit_verdict (NEW — POST /api/topics/{id}/verdict)
- dialectic_view_verdict
Also added contracts.tools entry for the new tool, updated README +
startup log line. Sim smoke verified the other 4 (list/propose/signup/
detail) via direct plugin import; submit_verdict not yet smoke-tested
end-to-end (requires running through a full debate to debate_end_at).
Code path is identical to other write tools — bearer + JSON body +
shape-coerced response.
Phase 3 of DIALECTIC-V2. Six tools wired to the Go backend running on
server.t3:
- dialectic_list_topics GET /api/topics
- dialectic_topic_detail GET /api/topics/{id}
- dialectic_propose_topic POST /api/topics
- dialectic_signup POST /api/topics/{id}/signups (HF pre-check)
- dialectic_post_argument POST /api/topics/{id}/arguments
- dialectic_view_verdict GET /api/topics/{id}/verdict
All tools return MCP {content:[{type:text,text}]} shape. Errors caught
and surfaced as text payload so agents see actionable failure messages.
Per-agent API key resolved via secret-mgr key dialectic-agent-apikey
(cached in memory; AGENT_VERIFY env required). HF on_call coverage
check degrades gracefully to skipped if HarborForge.OpenclawPlugin
does not yet expose hasOnCallCovering() — backend stores pre_validated
flag as audit signal.
openclaw.plugin.json declares both contracts.tools (the 6 names) AND
activation.onStartup:true per loader gotchas memory; missing either
silently drops the plugin.
Plain export default {id, name, register} entry shape matching
prism-facet. No openclaw SDK imports (jiti runtime resolution of
openclaw was flaky in HF-style entries; structurally simpler avoids
the lookup entirely).
Defaults backendUrl to https://dialectic-api.hangman-lab.top; override
via openclaw.json plugins.entries.dialectic.config.backendUrl for sim.
Phase 3 deferred items (in README): agent key provisioning workflow,
HF window-coverage accessor, SSE subscription tool, token-cost
reporting.