Skip to content

feat(cli,contract): --reviewer and --qa on ceki contract create#7

Merged
iWedmak merged 15 commits into
masterfrom
feature/2465-contract-create-reviewer-qa
Jul 6, 2026
Merged

feat(cli,contract): --reviewer and --qa on ceki contract create#7
iWedmak merged 15 commits into
masterfrom
feature/2465-contract-create-reviewer-qa

Conversation

@iWedmak

@iWedmak iWedmak commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Backend create-contract-event now accepts explicit reviewer and qa objects (task 2465 backed by back/2442). Without them the event stays a clean Hand role. Expose the same surface on the CLI + SDK:

  • ceki contract create CID --benefitable agent:N --reviewer agent:M --qa agent:K attaches both roles.
  • --reviewer / --qa accept the same agent:N / user:N form as --benefitable.
  • They are only forwarded into the payload when supplied; omitted = clean Hand (no auto-attach).
  • ContractClient.create() gets the matching reviewer= / qa= kwargs.

No backwards-incompatible change — every existing call site keeps working.

Test plan

  • ruff check . — All checks passed
  • pytest tests/test_contract.py — 46/46 green; includes 4 new regression cases (reviewer-only, qa-only, both, CLI parser+dispatch)
  • ceki contract create --help shows the two new flags after pip install -e .
  • reviewer: re-verify against a real contract once merged

iWedmak and others added 15 commits June 24, 2026 12:46
Backend create-contract-event now accepts explicit reviewer/qa objects
({type, value}); without them the event stays a clean Hand. Expose the
same surface on the CLI + SDK: matching shape to --benefitable
(agent:N / user:N), only forwarded into the payload when supplied.

Tests: regression cases for the contract client (reviewer-only, qa-only,
both, neither) plus a CLI parser dispatch case wiring all three through.
Backend moved role pivots into a single participants array of
{value, type, role_id} items (reviewer -> role 5, qa -> role 6).
Drop the old top-level reviewer/qa keys, keep --reviewer / --qa
on the CLI as the human-facing shortcut, and add a repeatable
--participant for arbitrary roles.

Version bumped to 2.27.0 - wire format is breaking.
`propose --desc` was being used as a progress report, but the backend
treats --desc as the event description — agents were silently wiping
the spec. Add a dedicated `progress` command that wraps a status
correction (optional --status) and a comment in one call, leaving the
event description untouched.

`propose` semantics are unchanged. SKILL.md updated to recommend
`progress` for status+report; `propose` stays for pure field
corrections.

Version bumped to 2.28.0.
Backend rejects comment events without a `label` ("The label field is
required"). The bare `progress` call hit this on first dogfood. Derive
a short label from the first line of --desc (capped at 60 chars); fall
back to "progress" if desc is empty. The full --desc still goes into
`description` untouched.
Backend rejects {value, type, role_id} with 422 — the wire shape per
EventController validation rules is {participable_id, participable_type,
role_id}. role_id mapping (reviewer=5, qa=6) is unchanged.

Unit tests previously asserted the wrong shape; regression guard
test_create_participants_uses_participable_id_keys() now pins the
correct keys. Patch bump to 2.28.1.
Backend renamed the role-attachment array field from `participants` to
`users` (sync with back/2542). Element shape stays
{participable_id, participable_type, role_id}. CLI flag --participant
keeps its name — it is the human-facing word; only the wire key moves.

Regression guard test_create_uses_users_field_not_participants pins the
field name. Minor bump to 2.29.0.
EventController validator accepts the short tokens `agent` / `user`,
but the downstream membership lookup compares the string against the
contract members' `participable_type` column which stores the
fully-qualified class name. Sending the short token bypasses validation
yet trips the misleading 422 "Participant must be a member of the
contract".

Send `App\\Models\\Agent` / `App\\Models\\User` instead. Tests follow.
Patch bump to 2.29.1.
The create-contract-event MCP tool schema declares the element as
{participable_id, type, role_id} — `type` is the short token
'agent' / 'user'. Sending `participable_type` (FQCN) is silently dropped
by the MCP layer, which collapses the type to user and trips the
misleading 422 "Participant must be a member of the contract".

Live smoke (contract 43, --reviewer agent:10 --qa agent:12) now returns
event.id=2587 with the two role pivots materialized server-side
(participants role_id 5 + 6).

Patch bump to 2.29.2.
The web app renders both `label` and `description` on a comment event,
but the human-typed path only ever writes to `label`. The SDK derived
a 60-char `label = desc[:60]` AND also sent the full text as
`description`, producing a visible duplicate in the UI.

events.label is unbounded TEXT — long multi-line reports go in there
whole. `comment()`, `progress()`, and `--desc` on the comment CLI all
write the FULL body to `label` and never set `description`.

Minor bump to 2.30.0.
…asks

Backend swapped:
  get-my-jobs  (contract tasks)       → get-my-events
  get-hire-jobs (posted hire jobs)    → get-my-jobs

Consumer-side rename: ContractClient.my_events() pulls contract tasks
via get-my-events; ContractClient.my_jobs() now pulls posted hire
schedules via the (newly-reused) get-my-jobs wire name. CLI subcommands
match. Regression guards pin both wire names.

Minor bump to 2.31.0.
Thin wrapper around the existing /mcp/agent call-human tool: escalate
an event to a human up the event→parent→contract→schedule chain,
delivered via telegram + push + in-app.

CLI: `ceki contract call-human <eid> --kind input|review|stuck --desc "..."`
SDK: `ContractClient.call_human(event_id, kind, desc)`

kind is client-side validated against the enum before we hit the wire.
Minor bump to 2.32.0.
Two new browser-control methods layered on the existing CDP passthrough:
  - copy() returns window.getSelection().toString() via Runtime.evaluate
  - paste(selector, text) focuses the input via querySelector(...).focus()
    then dispatches Input.insertText, so controlled React/Vue inputs see
    the update

selector is JSON-escaped — safe against quotes / backticks / newlines /
unicode.

Minor bump to 2.33.0.
The insertText-based impl from the previous release did NOT touch the
OS clipboard — it was direct DOM insertion. Rewrite copy() and paste()
to dispatch synthetic Ctrl+C / Ctrl+V via Input.dispatchKeyEvent so
the OS clipboard is actually engaged and controlled inputs see a
real ClipboardEvent with inputType=insertFromPaste.

Arbitrary-text paste stages the text through an offscreen <textarea>
+ Ctrl+C to seed the clipboard, then focus target + Ctrl+V.
selector + text are JSON-escaped in the Runtime.evaluate expressions.

Verified against a real headed Chromium: OS clipboard flipped
(xclip readback matches), paste event fires with inputType=insertFromPaste.

Minor bump to 2.34.0.
CLI/SDK had no way to attach project tags on create — they had to be
hand-crafted into the raw --data JSON. Add a --tags flag (and create()
tags kwarg) that parses comma-separated key[:label[:color]] items into
the settings.tags[] shape the create-contract-event tool persists.

Only create accepts tags on the wire (propose-correction/comment do
not), so the sugar is create-scoped.
propose() now forwards a settings object (tags, reply_to, blocked_by,
do_after) verbatim onto the propose-correction wire — back/2796
persists it onto the event. CLI gains --tags <key[:label[:color]]>
(comma-separated sugar → settings.tags[]), mirroring the js-sdk 1.20.0
parity (task 2825).

create() already had the tags sugar; propose now matches. Regression
guards: propose forwards settings.tags verbatim, omits settings when
not supplied, CLI sugar parses into the right shape.

Minor bump to 2.35.0.
@iWedmak
iWedmak merged commit ac37e0d into master Jul 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant