You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This refactor aligns our task model terminology with the philosophy of Mark Burgess's "Thinking in Promises".
In this framework, a task is not a command imposed on an agent. Instead, a task is a proposal about the future state of the system, which other agents voluntarily claim to satisfy within a specific time horizon. The imperative word "imposed" misrepresents this voluntary, promise-based relationship.
Goals
Replace the "imposer" / "impose" vocabulary with "proposer" / "propose".
Scope of Changes
Database Schema: Rename imposed_by_agent_id and imposed_by_human_id columns to proposed_by_agent_id and proposed_by_human_id.
TypeScript Types & API: Update imposedByAgentId / imposedByHumanId to proposedByAgentId / proposedByHumanId in @moltnet/tasks, REST API schemas, and any generated API client types.
Keto Permissions & Audit: Rename the impose permission/role logic to propose.
Documentation: Update all references in docs/ (e.g., docs/use/tasks.md, docs/understand/architecture.md, docs/understand/agent-runtime.md). Change terms like "imposer" → "proposer", "imposed by agent" → "proposed by agent".
Tests: Adjust test fixtures and assertions that rely on these field names.
Expected Outcome
The codebase should accurately reflect the Claiming / Proposal semantic where:
An agent proposes a promise.
Another agent voluntarily claims that promise.
The system simply provides the marketplace for this promise exchange.
Addendum — + give / - receive promises (give/receive, not produce/consume)
Beyond the imposer→proposer rename, the codebase carries a second vocabulary debt from Burgess's framework. We talk about producers of promises that produce an outcome (e.g. run_eval "producer" runs, the producer/judge model in docs/understand/agent-runtime.md). In Thinking in Promises, that side of the relationship is give, not produce.
Specifically, Burgess distinguishes:
+ promise (give) — an agent voluntarily binds itself to offer something. Notation: A +X→ B. The offering may or may not be used.
- promise (receive) — an agent voluntarily binds itself to accept and use what is offered. Notation: B -X→ A. The acceptance may or may not happen.
Both sides are voluntary self-bindings; neither party can impose on the other. A + without a matching - is an unused offering; a - without a matching + is unmet demand. Useful work happens only when both sides have promised.
What this means for our task model
Today's term
Burgess vocabulary
What it actually does
producer task (e.g. run_eval, fulfill_brief)
+ promise (give)
Claiming agent promises to give an outcome — code, response, artifact. The outcome may or may not be used downstream.
Claiming agent promises to receive and use a prior outcome — to inspect it, render a verdict, score it. The acceptance is what gives the upstream + its value.
Not itself a claimant; publishes a proposal that other agents may + or - against.
claim
the act of promising (either direction)
A claim on a producer task is a +; a claim on a judge task is a -.
A few consequences worth noting before any rename lands:
Judge tasks are not "consumers." "Consumer" implies passive use; - promises are active commitments to receive. The judge promises to do the receiving work — fetching producer state, inspecting artifacts, rendering a verdict. The judge_eval_attempt rework on PR feat(#943): Phase 0 eval substrate dogfood — SDK, pi-extension, prompts, daemon, imposers #1151 (per-attempt judging, producer-context attach) is exactly the substrate-side support for the judge's - promise being keepable.
Most real interactions are bidirectional. A judge task --promises to receive a producer's output, but also +-promises to give a verdict downstream (recorded as the judge's structured output, possibly consumed by a meta-judge or aggregation step). Modeling judge_* as purely - loses that. The same agent, in the same attempt, holds both a - and a + promise — just over different artifacts.
Pack tasks are similarly bidirectional.render_pack--promises to receive a set of entries (claimed scope), then +-promises to give a rendered artifact. curate_pack is the same shape. judge_pack is - on the pack + + on the verdict.
successCriteria is a self-imposed + on a --side promise, or vice versa. When a producer claims a run_eval task, the criteria carry the producer's own bound checks on its own + promise. This is the same shape as Make submit-tool call a successCriteria gate, not a substrate enforcement #1176 (submit-output as a successCriteria gate): the agent's promise carries its own acceptance criteria.
Vocabulary to adopt
Replace
With
Rationale
producer (in docs, prose, internal types)
giveror+-side claimant or "task that gives an outcome"
"Produce" implies industrial process; "give" carries the voluntary self-binding correctly.
consumer (where it appears)
receiveror--side claimant or "task that receives an outcome"
Same reason.
producer/judge model (the architecture in docs/understand/agent-runtime.md)
give/receive modelor+/− model
Names the relationship type, not just the two roles in one specific shape.
I'd avoid using the + / - symbols in code identifiers (hard to grep, easy to mistake for arithmetic). Prose and docs are the right place for the symbols; code should use giver / receiver or domain-specific terms.
Scope additions to this issue
In addition to the imposer→proposer rename already listed:
Documentation: in docs/understand/agent-runtime.md, retitle and rework the "producer/judge model" section as "give/receive model" with the +/− notation as a sidebar. Update prose throughout docs/ that talks about "the producer" / "producer task" to use "giver" / "task that gives an outcome" where the framing matters. Leave domain-specific terms (run_eval, judge_eval_attempt) untouched — they name shapes, not roles.
TypeScript types & internal docs: audit libs/agent-runtime/, libs/pi-extension/, apps/agent-daemon/ for prose comments using "producer" / "consumer" / "producer task". Code identifiers like producerWorkspace, producerSlot are well-rooted in the per-attempt-judging design; renaming them is invasive and the win is mostly documentary. I'd leave them and rename only when the surrounding code is being touched anyway.
Task UI & prose-level surfaces: any user-visible label that says "producer" or "consumer" should adopt the give/receive vocabulary. Internal admin tooling is fine to leave alone.
Open question
Some task types don't fit cleanly into either + or -. pr_review claims to receive a diff and give a review — same bidirectional shape as judge_*. fulfill_brief claims to receive a brief and give an implementation. The give/receive labeling needs to apply to promises, not tasks: a single claimed task can carry one + promise and one - promise, both bound by the same claim.
Worth deciding before any code-level rename: do we model each task type as a pair of promises (give-side and receive-side, each with its own success criteria), or do we keep modeling "the task" as one thing and just describe its dual nature in prose? Burgess would say the former — promises are the unit, agents and tasks are the carriers. But that's a bigger architectural shift than this issue's current scope.
Context
This refactor aligns our task model terminology with the philosophy of Mark Burgess's "Thinking in Promises".
In this framework, a task is not a command imposed on an agent. Instead, a task is a proposal about the future state of the system, which other agents voluntarily claim to satisfy within a specific time horizon. The imperative word "imposed" misrepresents this voluntary, promise-based relationship.
Goals
Replace the "imposer" / "impose" vocabulary with "proposer" / "propose".
Scope of Changes
imposed_by_agent_idandimposed_by_human_idcolumns toproposed_by_agent_idandproposed_by_human_id.imposedByAgentId/imposedByHumanIdtoproposedByAgentId/proposedByHumanIdin@moltnet/tasks, REST API schemas, and any generated API client types.imposepermission/role logic topropose.docs/(e.g.,docs/use/tasks.md,docs/understand/architecture.md,docs/understand/agent-runtime.md). Change terms like "imposer" → "proposer", "imposed by agent" → "proposed by agent".Expected Outcome
The codebase should accurately reflect the Claiming / Proposal semantic where:
Addendum —
+give /-receive promises (give/receive, not produce/consume)Beyond the imposer→proposer rename, the codebase carries a second vocabulary debt from Burgess's framework. We talk about producers of promises that produce an outcome (e.g.
run_eval"producer" runs, the producer/judge model indocs/understand/agent-runtime.md). In Thinking in Promises, that side of the relationship is give, not produce.Specifically, Burgess distinguishes:
+promise (give) — an agent voluntarily binds itself to offer something. Notation:A +X→ B. The offering may or may not be used.-promise (receive) — an agent voluntarily binds itself to accept and use what is offered. Notation:B -X→ A. The acceptance may or may not happen.Both sides are voluntary self-bindings; neither party can impose on the other. A
+without a matching-is an unused offering; a-without a matching+is unmet demand. Useful work happens only when both sides have promised.What this means for our task model
run_eval,fulfill_brief)+promise (give)judge_eval_attempt,judge_pack,assess_brief)-promise (receive)+its value.+or-against.claimon a producer task is a+; aclaimon a judge task is a-.A few consequences worth noting before any rename lands:
Judge tasks are not "consumers." "Consumer" implies passive use;
-promises are active commitments to receive. The judge promises to do the receiving work — fetching producer state, inspecting artifacts, rendering a verdict. Thejudge_eval_attemptrework on PR feat(#943): Phase 0 eval substrate dogfood — SDK, pi-extension, prompts, daemon, imposers #1151 (per-attempt judging, producer-context attach) is exactly the substrate-side support for the judge's-promise being keepable.Most real interactions are bidirectional. A judge task
--promises to receive a producer's output, but also+-promises to give a verdict downstream (recorded as the judge's structured output, possibly consumed by a meta-judge or aggregation step). Modelingjudge_*as purely-loses that. The same agent, in the same attempt, holds both a-and a+promise — just over different artifacts.Pack tasks are similarly bidirectional.
render_pack--promises to receive a set of entries (claimed scope), then+-promises to give a rendered artifact.curate_packis the same shape.judge_packis-on the pack ++on the verdict.successCriteriais a self-imposed+on a--side promise, or vice versa. When a producer claims arun_evaltask, the criteria carry the producer's own bound checks on its own+promise. This is the same shape as Make submit-tool call a successCriteria gate, not a substrate enforcement #1176 (submit-output as a successCriteria gate): the agent's promise carries its own acceptance criteria.Vocabulary to adopt
producer(in docs, prose, internal types)giveror+-side claimant or "task that gives an outcome"consumer(where it appears)receiveror--side claimant or "task that receives an outcome"producer/judge model(the architecture indocs/understand/agent-runtime.md)give/receive modelor+/− modelI'd avoid using the
+/-symbols in code identifiers (hard to grep, easy to mistake for arithmetic). Prose and docs are the right place for the symbols; code should usegiver/receiveror domain-specific terms.Scope additions to this issue
In addition to the imposer→proposer rename already listed:
docs/understand/agent-runtime.md, retitle and rework the "producer/judge model" section as "give/receive model" with the+/−notation as a sidebar. Update prose throughoutdocs/that talks about "the producer" / "producer task" to use "giver" / "task that gives an outcome" where the framing matters. Leave domain-specific terms (run_eval,judge_eval_attempt) untouched — they name shapes, not roles.libs/agent-runtime/,libs/pi-extension/,apps/agent-daemon/for prose comments using "producer" / "consumer" / "producer task". Code identifiers likeproducerWorkspace,producerSlotare well-rooted in the per-attempt-judging design; renaming them is invasive and the win is mostly documentary. I'd leave them and rename only when the surrounding code is being touched anyway.Open question
Some task types don't fit cleanly into either
+or-.pr_reviewclaims to receive a diff and give a review — same bidirectional shape asjudge_*.fulfill_briefclaims to receive a brief and give an implementation. The give/receive labeling needs to apply to promises, not tasks: a single claimed task can carry one+promise and one-promise, both bound by the same claim.Worth deciding before any code-level rename: do we model each task type as a pair of promises (give-side and receive-side, each with its own success criteria), or do we keep modeling "the task" as one thing and just describe its dual nature in prose? Burgess would say the former — promises are the unit, agents and tasks are the carriers. But that's a bigger architectural shift than this issue's current scope.
Related
successCriteriagate. Once promises are the unit,successCriteriais the natural place to record what the agent self-binds to when claiming.