# The tools *Every tool the service exposes, from its own table (24 in all), grouped by the loop an agent walks. Descriptions are the service's own, in full.* **Why some tools count as context.** A late report about a run is worth more when the reporter was not the session that did the work. So the server remembers which tools a session called for a recipe, and classes a later report by it. Beside each tool below: **context** — calling it makes the session a context session for that recipe; **brief** — the assessment brief, the one read that earns a fresh-session class instead; **none** — no effect on that bookkeeping. This says nothing about whether a tool writes or retains data; read each description for its actual effects. *Publication snapshot: web-eef8292b2fbc2ddd* ## Find a method ### `list_recipes` List the recipes available in your organization: the ones labbel serves and the ones authored here — slug, title, status and step count, and nothing of what any of them contains. This is how you find a recipe slug. Unlike every other read about a recipe, calling it is not recorded as context, so an examiner can look up a slug here and still earn an independent provenance class when it reports. *Counts as: none.* ### `get_recipe` Retrieve a recipe's main document with its step overview — recipes authored in your organization, drafts included, and the recipes labbel serves. Use this when running a recipe: it gives the whole structure and the list of steps. *Counts as: context.* ### `get_step` Retrieve a single step. Load steps one at a time as the learner progresses — no need to load them all upfront. *Counts as: context.* ### `get_eval_criteria` Returns the evaluation criteria document for a domain and a level — structural checks (automated) and qualitative rubrics (your judgment). Use it to self-assess your work before submitting. Pass the domain a recipe declares in its own frontmatter — a built-in one, or a domain your own organization authored, answered with the newest edition a person on your bench has stamped, never a draft; omitted, it answers with education's. `level: meta` returns what a recipe itself is held to, `level: object` what work done from a recipe is held to. *Counts as: none.* ### `get_recipe_template` Returns the recipe guide for a domain — instructions for writing a well-structured recipe: the main document's YAML frontmatter and markdown body. Read this before writing your first recipe. `domain` names which guide: `code-review` (the guide reviewers work from), a domain your own organization authored, or `domain-authoring` — not a domain but the guide to creating one of your own; omitted, it returns education's. Always the meta level, so there is no level to choose. Any other word is answered with a document naming the words there are. *Counts as: none.* ## Do the work and hand it in ### `submit_step` Submit the work a recipe asks for. On an education recipe that is one step of it: a document with its own frontmatter, stored, every structural finding reported back and only severity `block` refusing the save. On the code review recipe the work is a review of a change: the domain's structural checks run as conformance, every one a `block`, and a review that holds them all mints the trace. The review itself is never stored. On a recipe in a domain your own organization authored you send the work itself; it is never stored either, not as a document and not on the trace. There the server checks only that something was handed in, so the record carries an empty conformance list. The trace is minted all the same, and if no edition is in force the submit is refused and nothing is stored. Every receipt carries the run reference to keep beside the original, and says when the follow-up falls due on a run that keeps a window. In your own domain `criteria_version` is the version word you read: with another edition in force the submit is refused with both words, nothing minted; without it the mint is against the edition in force, named on the receipt. *Counts as: context.* ### `save_progress` Save a learner's progress for one step. not_started stores nothing and opens no enrollment; the enrollment opens by itself on the first in_progress or completed save. Once the recipe is finished the writing stops: a save against a completed enrollment is answered rather than stored. Working through a recipe again is a round, opened with `open_round: true` on a save once the round that stands is finished, and the finished round is never written over. Never put personal data about an individual learner in context_note — it describes the state of the work, not the person, and must contain no names, contact details, or verbatim conversation content. Education's tool: on a code-review recipe, or one in a domain your own organization authored, it stores nothing and says so — the record there is the trace submit_step mints. *Counts as: context.* ### `get_progress` Get the learner's progress across the steps: status (not_started, in_progress, completed) and context notes per step, with one section per round, oldest first. Use it to resume a session or see where a learner left off. Education's tool: on a code-review recipe, or one in a domain your own organization authored, there is no progress to read and the answer says so — the record there is the trace submit_step mints. *Counts as: context.* ### `submit_recipe` Submit the recipe's main document (YAML frontmatter + markdown body): it is parsed, validated and stored as a draft. Every structural finding comes back, but only severity `block` refuses the save. The slug is derived from the title, so a resubmit under a title with the same slug replaces that recipe. Submit the steps separately via submit_step. `domain` names a built-in domain or one your own organization authored — the latter only once a person on your bench has stamped it: a drafted, unsigned word is refused with what it is waiting for, and the recipe is held to that domain's form, its single step minted from this same document. *Counts as: context.* ### `validate_recipe` Validate a recipe and all of its steps. Returns every structural finding with a severity — `block`, `should_fix` or `note` — and the qualitative rubrics for self-assessment. Use this after submitting every step. For a recipe in a domain your own organization authored it reports that domain's form instead and says which checks did not run: your own criteria are named here, never applied. *Counts as: context.* ## Report what happened later, and read it back ### `report_signals` Report what you observed during a run of the recipe, as signals. Which types you may send follows from the domain: For a recipe in the education domain: checkpoint_result, calibration, transfer_outcome, session_pattern, completion (observations); bloom_achieved, independence_trend (judgements); recipe_reflection (your reflection on the recipe). For a recipe in the code-review domain: review_issued, change_outcome, finding_outcome, criterion_status (observations); finding_accuracy, review_usefulness (judgements); review_reflection (your reflection on the recipe). For a recipe in a domain your own organization authored: criterion_status, review_reflection. Provenance is stamped by the server from what this session did; a role declared in assessor_claimed is stored beside the stamp, never as it. On an education recipe a delayed report from a fresh session lands on the earliest round still owed one; every other report on the round that stands. recipe_reflection's fields: worked_well, needs_improvement, hypothesis, not_assessed. session_pattern and completion are also observed by the server from saved progress. Signals must be aggregated and anonymous — no names, contact details or verbatim conversation content, nothing identifying an author or a codebase. E-mail addresses, URLs, phone numbers and @-handles in reflections are removed before storage and reported back, each field capped at 2000 characters; names are not detectable this way, so keeping them out is yours. *Counts as: none.* ### `get_trace` Read back the traces the server minted for a recipe's steps. A trace is what the server stamped when the work was received: every criterion it checked and whether each one held, how the gate is known (`observed`, or `reported` for one the server cannot see, whose declared state is stored beside the stamp, never as it), the tier and versions, and whatever the submitting session declared at the mint. A trace is minted by `submit_step` and by nothing else: there is no `submit_trace`, and nothing you send can write one. What you report afterwards through `report_signals` is folded in beside those stamps, per domain: in education what a delivery declared it did not assess and its transfer, checkpoint and calibration results, counted per enrollment; in code review what became of the change and each finding, counted per review; in your organization's own domain each criterion's status, counted per run. A review's outcome hangs on the review it was reported against rather than on the step. `trace` reads one run by the number on its run reference — what the mint froze, whether its follow-up fell due, and the decisions behind its versions. Reading this counts as context: read it after you report if you want an independent stamp. *Counts as: context.* ### `get_insights` Retrieve your organization's own signal picture, counted live from the signals reported so far — each aggregate with its n and the provenance class behind it. What an n counts follows from the domain the recipe declares: distinct enrollments in education, distinct reviews in code review, distinct runs in a domain your own organization authored, with the reported rows beside it. Which aggregates there are follows from the domain too: in the education domain, checkpoint_result, calibration, transfer_outcome, session_pattern, completion, bloom_achieved, independence_trend; in the code-review domain, review_issued, change_outcome, finding_outcome, criterion_status, finding_accuracy, review_usefulness. Session pattern and completion are read by the server from saved progress and stand beside that reading rather than counted. Reading this counts as context: read it after you report if you want an independent stamp. *Counts as: context.* ### `get_assessment_brief` Get the brief for an independent transfer assessment of one recipe: the transfer scenarios and which steps this learner completed — and none of the teaching material, so that reading it does not make you the agent that taught. Run the assessment before you retrieve any recipe or step content. The call is recorded once the brief is handed over, which is what lets a later report from this session be stamped independent. It names which round it is about — the earliest still owed a delayed assessment, else the one that stands. On a `code-review` recipe it hands over that domain's own brief: the reviews on record by ordinal, date, age and outcome horizons, and the outcome question — never the verdict or the findings. In a domain your own organization authored it is one run's brief: the criteria that run was frozen to, by number, and its follow-up rule — never earlier reports. Name the run with `trace`. *Counts as: brief.* ### `list_due_runs` Which of your organization's runs have passed their follow-up window with nothing reported against them — reviews on the `code-review` recipe, and runs in a domain your own organization authored. Teaching's runs are never listed; an enrollment is the anchor there. Each entry is the run's own address, when it was received, the versions it was held to, every window it keeps with whether it has fallen due or been answered, and where the report goes. It carries nothing anybody has already reported, and no person and no identifier. `cursor` is the reference line the previous page ended on, copied exactly; anything else is refused without listing. Your organization comes from this connection and cannot be sent. Nothing is stored and nothing is recorded: asking earns this session no class and makes it no less a fresh observer than it was, so a later report is stamped exactly as it would have been. labbel reminds nobody — this is the question you ask us, never a message we send you. *Counts as: none.* ## Author your own domain ### `validate_domain` Run a domain draft against the deterministic gate. A domain is a kind of recurring work your organization wants this service to hold — read the guide first with `get_recipe_template` and `domain: "domain-authoring"`. Send the whole draft as markdown with YAML frontmatter and this answers with every structural finding and its severity. Nothing you send is stored — the draft is read, answered and let go. What the gate settles is form; whether a criterion is phrased so it can be assessed is your expert's judgment. *Counts as: none.* ### `submit_domain` File a domain draft and open the bench case for it — the step after `validate_domain` says the form holds. Send the whole draft, your own reading of the material, and one verdict per real case you ran the draft against. What it stores is an edition, numbered by the server and frozen: a revision is a new edition, never an edit. Your reading and your verdicts are attached as *your* declarations, kept apart from the server's own record. Who is submitting comes from the connection. It does not stamp: a person at your bench puts their name to the edition, or does not. *Counts as: none.* ## Your account and organization ### `get_my_profile` Returns your user profile — id, name, email, role, organization — and the ledger of the exchange so far: runs held here, reports that came back, and which side is ahead, a line per domain. Call this first to confirm your identity and permissions. *Counts as: none.* ### `claim_trial` Lift a trial into your organization: everything it authored moves in, the identity that wrote it becomes a member here, the runs it made become *yours*, round numbers and all, and the trial's key stops working — all in one transaction. Called from the *receiving* side: `trial_key` is the trial's own key. It says nothing about you — your organization, identity and role come from this connection and cannot be sent. The key is hashed on arrival and never appears in any answer, log or error. Safe to call again: a claim you are not sure arrived comes back as the claim it already made. The whole claim is refused for a shared recipe slug, a shared domain slug, or a recipe you have already taken — taking one twice is a round you open yourself with `open_round`. *Counts as: none.* ### `list_members` List the people in your organization: for each one the e-mail address, the name, the role, the status, the tier and when the row was created — owners first, then admins, then members, oldest first inside each role, with your own row marked. No arguments: the organization is this connection's. It changes nothing and writes nothing to the session history. *Counts as: none.* ### `invite_member` Invite someone into your organization by e-mail address: the account is created in Supabase Auth and the user row here, in that order. `member_role` is the role the *invited* person gets (admin or member); `owner` is not offered. Your own organization, identity and role come from this connection and cannot be sent. The answer never carries an invitation link, a password or a token. Safe to call again: an address already a user here comes back as a success that changed nothing, and one held elsewhere in labbel is refused without saying where. *Counts as: none.* ### `set_member_role` Promote a member of your organization to `admin`, or put an admin back to `member`. `member_role` is the role that person gets from now on (admin or member); `owner` is not offered. Your own organization, identity and role come from this connection and cannot be sent. An owner may act on an admin or a member, an admin on a member only, nobody on an owner and nobody on themselves. Every door reads the row per request, so the new role is in force from that member's next call. An address that is not a member of your own organization is answered as if there were nobody there at all. *Counts as: none.* ### `set_member_status` Suspend or reactivate a member. Set `member_status` to `suspended` or `active`; your identity, role and organization come from the connection. Suspension stops MCP tools and bench access on the next call, but RLS still permits reads of the person's own account row, enrollments, progress and personal signals. It revokes no credentials: setting `active` again lets them back in with the credential they already had. An owner may act on an admin or a member, an admin on a member only, nobody on an owner and nobody on themselves. An address that is not a member of your own organization is answered as if there were nobody there at all. *Counts as: none.* ### `remove_member` Remove a member of your organization for good: the account in Supabase Auth is deleted and then the user row, in that order, so a half-finished removal can always be finished by calling again. Their own rows go with them and the places they were only referenced keep the work and lose the name. An owner may remove an admin or a member, an admin a member only, nobody an owner and nobody themselves. Safe to call again, and the answer never reads as something lost. Not reversible. *Counts as: none.* The orientation the service itself gives on connection: ### What this service is labbel keeps methods for recurring work, and the record of how they turned out. A method lives here as a *recipe*: what the work should achieve, its constraints and how anyone would know afterwards, with room to decide how to carry it out. No model runs here; the thinking is yours. A *domain* is one kind of recurring work, with its own criteria and its own clock for when the truth arrives. Two come built in — code review, where labbel serves a recipe, and education, where labbel serves the guide for writing one — and your organization can author its own, held to criteria a person at its bench stamped. Each tool below says what it does in which domain. A run goes: - `list_recipes` — what is here, and what is yours. - `get_recipe` — the method, in its own words. - `get_step` — what the step asks for. - Do the work, in your own tools. - `submit_step` — hand it in, with what you declare about how you worked. What is kept is the *trace* of that run: what happened, your declarations beside the server's own stamps. The conversation is never stored. The criteria the work is held to are readable before you write anything, through `get_eval_criteria`. They explain themselves rather than gate, and reading them is also how you decide whether this is work you want to take on. The outcome arrives late — a fix, a revert, what a learner still had a month later. `report_signals` is the way back when it does.