feat(config): wire protocols.md into every worker as shared behavioral contract
This commit is contained in:
@@ -43,6 +43,17 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocolsPrompt, err := os.ReadFile(cfg.ConfigDir + "/protocols.md")
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("read protocols.md", "path", cfg.ConfigDir+"/protocols.md", "err", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// prependProtocols prepends the shared protocols to a skill discipline file.
|
||||||
|
prependProtocols := func(skillPrompt []byte) string {
|
||||||
|
return string(protocolsPrompt) + "\n---\n\n" + string(skillPrompt)
|
||||||
|
}
|
||||||
|
|
||||||
tddPrompt, err := os.ReadFile(cfg.ConfigDir + "/tdd.md")
|
tddPrompt, err := os.ReadFile(cfg.ConfigDir + "/tdd.md")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("read tdd.md", "path", cfg.ConfigDir+"/tdd.md", "err", err)
|
logger.Error("read tdd.md", "path", cfg.ConfigDir+"/tdd.md", "err", err)
|
||||||
@@ -114,7 +125,7 @@ func main() {
|
|||||||
reg := registry.New()
|
reg := registry.New()
|
||||||
reg.Register(tdd.New(tdd.Config{
|
reg.Register(tdd.New(tdd.Config{
|
||||||
SystemPrompt: string(systemPrompt),
|
SystemPrompt: string(systemPrompt),
|
||||||
SkillPrompt: string(tddPrompt),
|
SkillPrompt: prependProtocols(tddPrompt),
|
||||||
DefaultModel: models.ChainFor("tdd", "")[0],
|
DefaultModel: models.ChainFor("tdd", "")[0],
|
||||||
ExecutorFn: buildOrch("tdd"),
|
ExecutorFn: buildOrch("tdd"),
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
@@ -130,35 +141,35 @@ func main() {
|
|||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
}))
|
}))
|
||||||
reg.Register(retrospective.New(retrospective.Config{
|
reg.Register(retrospective.New(retrospective.Config{
|
||||||
SkillPrompt: string(retroPrompt),
|
SkillPrompt: prependProtocols(retroPrompt),
|
||||||
DefaultModel: models.ChainFor("retrospective", "")[0],
|
DefaultModel: models.ChainFor("retrospective", "")[0],
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
ExecutorFn: buildOrch("retrospective"),
|
ExecutorFn: buildOrch("retrospective"),
|
||||||
}))
|
}))
|
||||||
reg.Register(review.New(review.Config{
|
reg.Register(review.New(review.Config{
|
||||||
SkillPrompt: string(reviewPrompt),
|
SkillPrompt: prependProtocols(reviewPrompt),
|
||||||
DefaultModel: models.ChainFor("review", "")[0],
|
DefaultModel: models.ChainFor("review", "")[0],
|
||||||
ExecutorFn: buildOrch("review"),
|
ExecutorFn: buildOrch("review"),
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
IngestBaseURL: cfg.IngestBaseURL,
|
IngestBaseURL: cfg.IngestBaseURL,
|
||||||
}))
|
}))
|
||||||
reg.Register(skilldebug.New(skilldebug.Config{
|
reg.Register(skilldebug.New(skilldebug.Config{
|
||||||
SkillPrompt: string(debugPrompt),
|
SkillPrompt: prependProtocols(debugPrompt),
|
||||||
DefaultModel: models.ChainFor("debug", "")[0],
|
DefaultModel: models.ChainFor("debug", "")[0],
|
||||||
ExecutorFn: buildOrch("debug"),
|
ExecutorFn: buildOrch("debug"),
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
IngestBaseURL: cfg.IngestBaseURL,
|
IngestBaseURL: cfg.IngestBaseURL,
|
||||||
}))
|
}))
|
||||||
reg.Register(spec.New(spec.Config{
|
reg.Register(spec.New(spec.Config{
|
||||||
SkillPrompt: string(specPrompt),
|
SkillPrompt: prependProtocols(specPrompt),
|
||||||
DefaultModel: models.ChainFor("spec", "")[0],
|
DefaultModel: models.ChainFor("spec", "")[0],
|
||||||
ExecutorFn: buildOrch("spec"),
|
ExecutorFn: buildOrch("spec"),
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
IngestBaseURL: cfg.IngestBaseURL,
|
IngestBaseURL: cfg.IngestBaseURL,
|
||||||
}))
|
}))
|
||||||
reg.Register(trainer.New(trainer.Config{
|
reg.Register(trainer.New(trainer.Config{
|
||||||
ReaderPrompt: string(trainerReaderPrompt),
|
ReaderPrompt: prependProtocols(trainerReaderPrompt),
|
||||||
WriterPrompt: string(trainerWriterPrompt),
|
WriterPrompt: prependProtocols(trainerWriterPrompt),
|
||||||
DefaultModel: models.ChainFor("trainer", "")[0],
|
DefaultModel: models.ChainFor("trainer", "")[0],
|
||||||
ExecutorFn: buildOrch("trainer"),
|
ExecutorFn: buildOrch("trainer"),
|
||||||
SessionsDir: cfg.SessionsDir,
|
SessionsDir: cfg.SessionsDir,
|
||||||
|
|||||||
@@ -1,27 +1,55 @@
|
|||||||
# The Hyperguild Way
|
# The Hyperguild Way — Worker Protocols
|
||||||
|
|
||||||
These protocols are injected into every worker invocation. They define how you behave as a member of the hyperguild.
|
Injected into every worker invocation alongside the skill discipline file.
|
||||||
|
Defines the behavioral contract all workers must follow regardless of skill or model.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Output contract
|
## Output contract
|
||||||
|
|
||||||
Every response is raw JSON matching the response schema. No preamble, no prose, no markdown. Malformed output is treated as a failed invocation.
|
Every response is raw JSON matching the skill's output schema.
|
||||||
|
- No preamble, no explanation, no prose before or after the JSON
|
||||||
|
- No markdown code fences around the JSON
|
||||||
|
- Malformed output is treated as a failed invocation
|
||||||
|
- If uncertain, return valid JSON anyway — put uncertainty in `message`
|
||||||
|
|
||||||
## Quality gate
|
## Quality gate
|
||||||
|
|
||||||
`verified: true` only when a subprocess exit code confirms the outcome. Never self-assess. "I think the tests pass" is not verified.
|
`verified: true` means the artifact was independently confirmed correct:
|
||||||
|
- For code: the test runner exited 0
|
||||||
|
- For files: the file exists at the path you wrote
|
||||||
|
- Never set `verified: true` based on self-assessment — only on external confirmation
|
||||||
|
- "I think the tests pass" is not verified. Run them.
|
||||||
|
|
||||||
## Escalation
|
## Escalation
|
||||||
|
|
||||||
If stuck after 3 attempts, return `status: error` with a clear `message` explaining why. Do not retry silently. Do not fabricate a passing result.
|
If stuck after a genuine attempt:
|
||||||
|
- Return `status: error` with a clear reason in `message`
|
||||||
|
- Do not retry silently or produce low-confidence output labelled as a pass
|
||||||
|
- Do not hallucinate file paths, test results, or exit codes
|
||||||
|
- Maximum 3 attempts per phase — if output is identical across two consecutive attempts, stop immediately
|
||||||
|
|
||||||
## Working offline
|
## Context usage
|
||||||
|
|
||||||
If brain context is absent from your prompt, proceed using your discipline file only. Note the gap in your `message` field: "no brain context available".
|
You may receive a `## Relevant knowledge` block and/or a `## Session history` block before your task.
|
||||||
|
- **Relevant knowledge**: patterns, decisions, and conventions from past sessions. Let them inform your approach — do not contradict them without reason.
|
||||||
|
- **Session history**: what has already happened in this session. Build on it, do not repeat it.
|
||||||
|
- If either block is absent, proceed with the skill discipline file only. Note the absence in `message` if it materially affects quality.
|
||||||
|
|
||||||
## Handoff format
|
## Handoff discipline
|
||||||
|
|
||||||
Structure your output so the next worker in a chain can consume it without transformation. Use the standard result schema. Do not add extra fields.
|
Structure output so the next worker in a chain can consume it without transformation:
|
||||||
|
- `file_path`: absolute path to the primary artifact you produced
|
||||||
|
- `runner_output`: verbatim stdout+stderr from the last command you ran (truncate to 2000 chars if longer)
|
||||||
|
- `message`: one sentence — what you did and whether it worked
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
You have access to `Bash`, `Read`, and `Write` only.
|
||||||
|
- Do not attempt to call MCP tools or make HTTP requests
|
||||||
|
- Do not modify files outside `project_root` without explicit instruction
|
||||||
|
- If the task requires capabilities you do not have, return `status: error`
|
||||||
|
|
||||||
## Session logging
|
## Session logging
|
||||||
|
|
||||||
The Go skill handler records your invocation in the session log automatically. You do not need to do this yourself.
|
The Go skill handler records your invocation automatically. You do not need to log anything yourself.
|
||||||
|
|||||||
Reference in New Issue
Block a user