Skip to content

Rename task proposer/impose terminology to proposer/propose #1158

Description

@legreffier

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

  • 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".
  • Task UI: Update any UI labels showing "Imposed by" → "Proposed by".
  • Tests: Adjust test fixtures and assertions that rely on these field names.

Expected Outcome

The codebase should accurately reflect the Claiming / Proposal semantic where:

  1. An agent proposes a promise.
  2. Another agent voluntarily claims that promise.
  3. 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.
judge task / assessment task (e.g. judge_eval_attempt, judge_pack, assess_brief) - promise (receive) 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.
proposer (post #1158 rename) the party that publishes the proposal 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:

  1. 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.

  2. 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.

  3. 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.

  4. 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) giver or +-side claimant or "task that gives an outcome" "Produce" implies industrial process; "give" carries the voluntary self-binding correctly.
consumer (where it appears) receiver or --side claimant or "task that receives an outcome" Same reason.
producer/judge model (the architecture in docs/understand/agent-runtime.md) give/receive model or +/− 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.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions