{"server":"io.github.snowbikemike/tascan-mcp","count":33,"changes":[{"tool":"tascan_delegate_to_agent","kind":"changed","observed_at":"2026-10-12T00:51:52.192Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"0aae9862f44674e7651ed9203cc28414","after_hash":"bdb001deb7e088992fae747a7c664281"},{"tool":"tascan_control_fanout","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["description"],"description_before":"Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops the orphan pass from re-firing them; resume releases them again; cancel supersedes every unclaimed task and closes once quiescent; close_barrier drops unsettled or named exclude_seats and forces the synth barrier now instead of waiting for more seats; retry_synth (migration 232) mints a new synth revision from the current synth's own stored inputs, correctly ordered, when every one of its failed runs is input_ref_mismatch -- refused otherwise (not_synthesizing, no_synth_task, no_failed_runs, not_input_ref_mismatch). No amend and no answer in phase 1. Every action mints a signed control-child completion FIRST, as the org's own system worker (coord_fanout_control_receipt) — never coord_dispatcher_action, so a control action can never sign into another org's Chief of Staff identity. idempotency_key replays the prior outcome (replayed:true) and applies nothing twice; a replayed resume after a later pause leaves the fan-out paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.","description_after":"Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops re-firing; resume releases them; cancel supersedes every unclaimed task and closes once quiet; close_barrier drops unsettled (or named exclude_seats) seats and forces the synth now; retry_synth mints a new synth revision from the stored inputs of the current synth when every failed run is input_ref_mismatch, refused otherwise (not_synthesizing, no_synth_task, no_failed_runs, not_input_ref_mismatch). No amend or answer yet. Every action first records a signed control completion as the system worker of this org, never as another org identity. idempotency_key replays the prior outcome (replayed true) and applies nothing twice; a replayed resume after a later pause stays paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.","description_similarity":0.729,"before_hash":"3c53b7a39b7db1e30caff43ef752b27e","after_hash":"0d465accc46d6d17a581c3a3e52427f7"},{"tool":"tascan_create_fanout","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["description"],"description_before":"Create a fan-out: 1-30 seats (RESEARCH by default, or LOCAL subagent seats) plus one synthesizer under ONE cycle root T_F (POST /coord/fanouts). Zero Decision cards, zero Parked cards, zero pages per seat -- only a control action or the closing roll-up reaches a human. Requires an API key with agent:dispatch:code -- an admin session has no dispatch budget (key_required). dry_run true runs the same validation plus the ceiling/cap pre-check and returns {dry_run:true, plan_sha256, seats, problems:[]} WITHOUT consuming budget or creating anything -- a real preflight, not a real create. Otherwise consumes seats.length + 1 dispatch units BEFORE the authoritative create; a refusal only the RPC can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails closed fanout_ceiling_unset until the owner sets a ceiling; over_ceiling when cap exceeds it. idempotency_key replays duplicate within 24h on the same plan, else idempotency_body_mismatch. Leaves fanout_created; every seat, the synth and the roll-up leave their own signed completion. Track with tascan_get_fanout.","description_after":"Create a fan-out: 1-30 seats (RESEARCH by default, or LOCAL subagent seats) plus one synthesizer under ONE cycle root (POST /coord/fanouts). No Decision cards, Parked cards or pages per seat: only a control action or the closing roll-up reaches a human. Needs an API key with agent:dispatch:code (an admin session has no dispatch budget: key_required). dry_run true runs the same validation and ceiling/cap pre-check and returns dry_run, plan_sha256, seats and problems without spending budget or creating anything. Otherwise it consumes seats + 1 dispatch units BEFORE the create; a refusal only the database can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails fanout_ceiling_unset until the owner sets a ceiling, over_ceiling when cap exceeds it. idempotency_key replays a duplicate within 24h on the same plan, else idempotency_body_mismatch. Every seat, the synth and the roll-up leave a signed completion. Track with tascan_get_fanout.","description_similarity":0.855,"before_hash":"d083d058b08b48103ec99b7eca6d08f3","after_hash":"23d93605e6f4690d8e8c424bbc5e0dbf"},{"tool":"tascan_get_task_trail","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["description","inputSchema"],"description_before":"Read a task's trail messages (protocol v0.2 trail_messages, GET /tasks/:id/messages): question, answer, handoff and note/discussion entries, last 100, newest last (reading order). Optionally filter to a comma-separated set of kinds. Read tier. Post with tascan_post_message.","description_after":"Read a task's trail messages (protocol v0.2 trail_messages, GET /tasks/:id/messages): question, answer, handoff and note/discussion entries, last 100, newest last (reading order). Optionally filter to a comma-separated set of kinds, and with since=<ISO time> read only messages newer than the last one you saw. Read tier. Post with tascan_post_message.","description_similarity":0.787,"before_hash":"b65de544e6ade78a06b5061ebd03b843","after_hash":"37bfa2ed61ddff8e63be62dc80e5f593"},{"tool":"tascan_list_tasks","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["description","inputSchema"],"description_before":"List all tasks in an event (task list)","description_after":"List the tasks in an event (task list). status \"open\" returns only tasks with no completion yet: use it when checking for work to do, so a long list is not re-read in full. \"done\" returns only completed tasks; \"all\" (default) returns every task.","description_similarity":0.194,"before_hash":"fc9d25c6483b47b11a68e990949d5c77","after_hash":"410a28bd34ec3cb69e22a59babc8e959"},{"tool":"tascan_get_signature_bundle","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["description"],"description_before":"Fetch the signature bundle for one signed document by signature assertion id (the signature_assertion_id inside the response value of a completed signature task). Returns the self-contained JSON an auditor can verify offline without trusting TaScan: the signed challenge preimage, clientDataJSON, authenticatorData, signature, public key, the user-verification and backup flags, the document SHA-256, task id, completion id and time. Contains no signed URL, phone number or email. Read tier, organization-scoped.","description_after":"Fetch the signature bundle for one signed document by signature assertion id (the signature_assertion_id inside the response value of a completed signature task). Returns the self-contained JSON an auditor can verify offline without trusting TaScan: the signed challenge preimage (v 2 also carries the typed name the signer entered, signer_typed_name), clientDataJSON, authenticatorData, signature, public key, the user-verification and backup flags, the document SHA-256, task id, completion id and time. Check it with: npx tascan-verify --signature bundle.json [--doc the-document.pdf]. Contains no signed URL, phone number or email. Read tier, organization-scoped.","description_similarity":0.8,"before_hash":"eb15a9b895ab8762c11ec9ed833c0ccb","after_hash":"e862d3b966104bc9aae9b53e9193cb95"},{"tool":"tascan_add_tasks","kind":"changed","observed_at":"2026-10-07T21:35:48.142Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"86d955e7e541d99fdd434260ecd49e99","after_hash":"ab6d71c4fc9e829b86e606f7d11b0e3b"},{"tool":"tascan_update_task","kind":"changed","observed_at":"2026-10-06T22:28:24.122Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"f8876934f1592945745265c1ff5fcf85","after_hash":"86732edfe25f384b16a0f26ef941f131"},{"tool":"tascan_get_signature_bundle","kind":"added","observed_at":"2026-10-06T22:28:24.122Z","fields":[],"description_before":null,"description_after":"Fetch the signature bundle for one signed document by signature assertion id (the signature_assertion_id inside the response value of a completed signature task). Returns the self-contained JSON an auditor can verify offline without trusting TaScan: the signed challenge preimage, clientDataJSON, authenticatorData, signature, public key, the user-verification and backup flags, the document SHA-256, task id, completion id and time. Contains no signed URL, phone number or email. Read tier, organization-scoped.","description_similarity":null,"before_hash":null,"after_hash":"eb15a9b895ab8762c11ec9ed833c0ccb"},{"tool":"tascan_add_tasks","kind":"changed","observed_at":"2026-10-06T22:28:24.122Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"cffa4452d4e3653b028783fdeff4784a","after_hash":"86d955e7e541d99fdd434260ecd49e99"},{"tool":"tascan_send_sms","kind":"changed","observed_at":"2026-10-05T22:27:06.722Z","fields":["description","inputSchema"],"description_before":"Send a transactional TaScan SMS text to a worker (by worker_id, using their phone on file) or to a raw phone number. Optionally attach a task list — the recipient gets a tap-to-open checklist link. Sends from TaScan's carrier-registered A2P number (or the org's own Twilio if BYOK). Counts against the org's monthly SMS quota unless BYOK. Messages are auto-prefixed with \"TaScan:\" per carrier registration; transactional/work-related content only, no marketing.","description_after":"Send a transactional TaScan SMS text to a worker (by worker_id, using their phone on file) or to a raw phone number. Optionally attach a task list — the recipient gets a tap-to-open checklist link. Attach images (MMS) with media_url (public https image URL) or media_base64 + media_type (jpeg/png/gif, max 3.5 MB) — e.g. a diagram, a tutorial photo or a site photo; the message text is optional when an image is attached. Sends from TaScan's carrier-registered A2P number (or the org's own Twilio if BYOK). Counts against the org's monthly SMS quota unless BYOK. Messages are auto-prefixed with \"TaScan:\" per carrier registration; transactional/work-related content only, no marketing.","description_similarity":0.674,"before_hash":"5fdd681ebed5d915cfd5bbeffd590b06","after_hash":"7fd3f4f4f5ab80c40f782c0b81f386e6"},{"tool":"tascan_quickstart","kind":"added","observed_at":"2026-09-28T23:39:35.607Z","fields":[],"description_before":null,"description_after":"One action to a genuinely verified receipt (POST /quickstart). Under your org it reuses-or-creates the project \"TaScan Quickstart\", its list \"Quickstart\" and the worker \"Quickstart executor\", adds a NEW task \"Reply with the exact text: <expected>\", completes it with your key, has the named policy quickstart_exact_output v1 compare the response to the expected text (verified or refuted, signed into the receipt), and publishes the receipt's public profile. expected defaults to \"VERIFIED\" (max 200 chars); response defaults to expected — pass a different response to see a refuted receipt. Returns the receipt URL and the public verify URL. Write tier.","description_similarity":null,"before_hash":null,"after_hash":"d8fc958acca3f9617d5571ea81729af4"},{"tool":"tascan_finish_run","kind":"added","observed_at":"2026-09-28T17:23:16.005Z","fields":[],"description_before":null,"description_after":"Finish a claimed local run (POST /runs/:run_id/finish). outcome='completed' stores `document` (and optional `verification`) as the seat's own build artifacts under EXACTLY the artifact_paths the fan-out named for this seat, hashes them into build_ref, and finishes the run -- this mints a real task_completions row and a SIGNED TASCAN RECEIPT for your work (tascan_get_receipt), the same as any other build; `document` is your deliverable and IS what gets hashed, so send the real content, not a summary. Zero changes to coord_fanout_settle / the barrier / the roll-up -- your completion releases the next held seat and, once every seat settles, feeds the fan-out's own synthesizer and rollup exactly like a cloud research seat's would. outcome='failed' finishes the run failed with your `error` text and stores nothing. Requires agent:dispatch:code. A run outside your org, or already finished, is refused (404 / the RPC's own not_live).","description_similarity":null,"before_hash":null,"after_hash":"e29cb3c9258795b88c48c56807b8b042"},{"tool":"tascan_heartbeat_run","kind":"added","observed_at":"2026-09-28T17:23:16.005Z","fields":[],"description_before":null,"description_after":"Extend a claimed local run's lease and mark it running (POST /runs/:run_id/heartbeat -> heartbeat_agent_run). ok false with reason not_live means the run is no longer yours -- the sweep expired it, or it was never yours to begin with -- STOP, do not finish it. Never mints a completion or a receipt. Requires agent:dispatch:code. A run outside your org is 404, never 403.","description_similarity":null,"before_hash":null,"after_hash":"d47599baa6f66f1b0ef2356d5a3ea576"},{"tool":"tascan_claim_run","kind":"added","observed_at":"2026-09-28T17:23:16.005Z","fields":[],"description_before":null,"description_after":"Claim a fan-out seat task as a LOCAL subagent run (POST /runs/claim -> claim_agent_run(p_runner='local')). Only admitted when instance starts with \"<your registered agent_id>:\" -- the seat's own coord.agent_id, set when the fan-out was created (tascan_create_fanout seats[i].runner='local'). Any other instance is refused, claimed false with reason seat_not_yours -- this tool never claims a seat that is not yours, and never claims a cloud (research) seat at all (refused not_routable). Never mints a completion or a receipt by itself -- claiming only opens the run; work happens after, and tascan_finish_run is what leaves the signed receipt. Requires agent:dispatch:code. A foreign or unknown task_id is 404, never 403 (S2: another org's task never even appears to exist).","description_similarity":null,"before_hash":null,"after_hash":"16cd5b918e64baee609b9725cafac06f"},{"tool":"tascan_control_fanout","kind":"changed","observed_at":"2026-09-28T17:23:16.005Z","fields":["description","inputSchema"],"description_before":"Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops the orphan pass from re-firing them; resume releases them again; cancel supersedes every unclaimed task and closes once quiescent; close_barrier drops unsettled or named exclude_seats and forces the synth barrier now instead of waiting for more seats. No amend and no answer in phase 1. Every action mints a signed control-child completion FIRST, as the org's own system worker (coord_fanout_control_receipt) — never coord_dispatcher_action, so a control action can never sign into another org's Chief of Staff identity. idempotency_key replays the prior outcome (replayed:true) and applies nothing twice; a replayed resume after a later pause leaves the fan-out paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.","description_after":"Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops the orphan pass from re-firing them; resume releases them again; cancel supersedes every unclaimed task and closes once quiescent; close_barrier drops unsettled or named exclude_seats and forces the synth barrier now instead of waiting for more seats; retry_synth (migration 232) mints a new synth revision from the current synth's own stored inputs, correctly ordered, when every one of its failed runs is input_ref_mismatch -- refused otherwise (not_synthesizing, no_synth_task, no_failed_runs, not_input_ref_mismatch). No amend and no answer in phase 1. Every action mints a signed control-child completion FIRST, as the org's own system worker (coord_fanout_control_receipt) — never coord_dispatcher_action, so a control action can never sign into another org's Chief of Staff identity. idempotency_key replays the prior outcome (replayed:true) and applies nothing twice; a replayed resume after a later pause leaves the fan-out paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.","description_similarity":0.821,"before_hash":"fedd15043f1e983c9b53a773410f9b26","after_hash":"3c53b7a39b7db1e30caff43ef752b27e"},{"tool":"tascan_create_fanout","kind":"changed","observed_at":"2026-09-28T17:23:16.005Z","fields":["description","inputSchema"],"description_before":"Create a fan-out: 1-30 RESEARCH seats plus one synthesizer under ONE cycle root T_F (POST /coord/fanouts). Zero Decision cards, zero Parked cards, zero pages per seat -- only a control action or the closing roll-up reaches a human. Requires an API key with agent:dispatch:code -- an admin session has no dispatch budget (key_required). Consumes seats.length + 1 dispatch units BEFORE the authoritative create; a refusal only the RPC can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails closed fanout_ceiling_unset until the owner sets a ceiling; over_ceiling when cap exceeds it. idempotency_key replays duplicate within 24h on the same plan, else idempotency_body_mismatch. dry_run is forwarded as-is; the route has no preflight mode yet, so dry_run true still creates for real -- never a way to avoid creating. Leaves fanout_created; every seat, the synth and the roll-up leave their own signed completion. Track with tascan_get_fanout.","description_after":"Create a fan-out: 1-30 seats (RESEARCH by default, or LOCAL subagent seats) plus one synthesizer under ONE cycle root T_F (POST /coord/fanouts). Zero Decision cards, zero Parked cards, zero pages per seat -- only a control action or the closing roll-up reaches a human. Requires an API key with agent:dispatch:code -- an admin session has no dispatch budget (key_required). dry_run true runs the same validation plus the ceiling/cap pre-check and returns {dry_run:true, plan_sha256, seats, problems:[]} WITHOUT consuming budget or creating anything -- a real preflight, not a real create. Otherwise consumes seats.length + 1 dispatch units BEFORE the authoritative create; a refusal only the RPC can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails closed fanout_ceiling_unset until the owner sets a ceiling; over_ceiling when cap exceeds it. idempotency_key replays duplicate within 24h on the same plan, else idempotency_body_mismatch. Leaves fanout_created; every seat, the synth and the roll-up leave their own signed completion. Track with tascan_get_fanout.","description_similarity":0.801,"before_hash":"b1bf966ae2c4f28ed906cbe843d8ec2d","after_hash":"d083d058b08b48103ec99b7eca6d08f3"},{"tool":"tascan_control_fanout","kind":"added","observed_at":"2026-09-28T11:12:10.053Z","fields":[],"description_before":null,"description_after":"Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops the orphan pass from re-firing them; resume releases them again; cancel supersedes every unclaimed task and closes once quiescent; close_barrier drops unsettled or named exclude_seats and forces the synth barrier now instead of waiting for more seats. No amend and no answer in phase 1. Every action mints a signed control-child completion FIRST, as the org's own system worker (coord_fanout_control_receipt) — never coord_dispatcher_action, so a control action can never sign into another org's Chief of Staff identity. idempotency_key replays the prior outcome (replayed:true) and applies nothing twice; a replayed resume after a later pause leaves the fan-out paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.","description_similarity":null,"before_hash":null,"after_hash":"fedd15043f1e983c9b53a773410f9b26"},{"tool":"tascan_get_fanout","kind":"added","observed_at":"2026-09-28T11:12:10.053Z","fields":[],"description_before":null,"description_after":"Read a fan-out (GET /coord/fanouts/:id?view=). view=status (default): state, seat counts, spend, cap, synth_deadline_at, poll_after_s. view=report: the full cycle report (get_cycle_report) — every seat, review and control step. view=rollup: the exact roll-up response_value plus its leaves (path, sha256, completion_id) once closed. view=verify: the server recomputes rollup_ref over the frozen leaves and returns ok / mismatches — the same check scripts/verify-fanout.js performs independently from another machine, which is the trusted proof; this view is a convenience, not a substitute. A foreign org's fanout_id answers 404, never 403, so another org's fan-out never even appears to exist. Read tier, no dispatch permission required.","description_similarity":null,"before_hash":null,"after_hash":"8ce9ec8e738348f3ad9e58e6e7679c62"},{"tool":"tascan_create_fanout","kind":"added","observed_at":"2026-09-28T11:12:10.053Z","fields":[],"description_before":null,"description_after":"Create a fan-out: 1-30 RESEARCH seats plus one synthesizer under ONE cycle root T_F (POST /coord/fanouts). Zero Decision cards, zero Parked cards, zero pages per seat -- only a control action or the closing roll-up reaches a human. Requires an API key with agent:dispatch:code -- an admin session has no dispatch budget (key_required). Consumes seats.length + 1 dispatch units BEFORE the authoritative create; a refusal only the RPC can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails closed fanout_ceiling_unset until the owner sets a ceiling; over_ceiling when cap exceeds it. idempotency_key replays duplicate within 24h on the same plan, else idempotency_body_mismatch. dry_run is forwarded as-is; the route has no preflight mode yet, so dry_run true still creates for real -- never a way to avoid creating. Leaves fanout_created; every seat, the synth and the roll-up leave their own signed completion. Track with tascan_get_fanout.","description_similarity":null,"before_hash":null,"after_hash":"b1bf966ae2c4f28ed906cbe843d8ec2d"},{"tool":"tascan_revoke_delegation","kind":"added","observed_at":"2026-09-27T23:33:48.002Z","fields":[],"description_before":null,"description_after":"Revoke a delegated child key immediately (DELETE /delegations/:key_id) — self-revoke, revoke by an ancestor key, or by an admin session of the org; any other caller is refused. Revoking cascades to every key IT delegated, in turn (the database trigger, not application code). Idempotent: revoking an already-revoked key reports already_revoked, no error.","description_similarity":null,"before_hash":null,"after_hash":"c68f343afd3188e1d3bc2e507ea76b20"},{"tool":"tascan_list_delegations","kind":"added","observed_at":"2026-09-27T23:33:48.002Z","fields":[],"description_before":null,"description_after":"List delegated child keys (GET /delegations): this key's own direct children (id, label, scopes, active/revoked, depth, expires_at) — never the raw credential. An admin session sees every delegated key in the org. Read tier.","description_similarity":null,"before_hash":null,"after_hash":"a718f64b908f4bf033b899b603a99eff"},{"tool":"tascan_delegate_to_agent","kind":"added","observed_at":"2026-09-27T23:33:48.002Z","fields":[],"description_before":null,"description_after":"Mint a time-limited, NARROWER child API key (POST /delegations, roadmap #11) — only read/write scopes may be requested; full, agent:dispatch, agent:dispatch:code, device:admin, delegate and webhooks:manage are always refused by name (I-6). TTL defaults to 1 hour (3600s), clamps to [60 seconds, 24 hours], and clamps further to THIS key's own expiry if it has one — a delegated key can never outlive its grantor. The child's tier is always a SUBSET of this key's own effective tier, never wider or lateral. Requires the delegate permission (owner-only to grant, requires full). The returned raw key is shown to you exactly ONCE — it is never stored server-side and cannot be retrieved again (I-10). Revoking this key (or any ancestor) cascades immediately to every key it delegated.","description_similarity":null,"before_hash":null,"after_hash":"0aae9862f44674e7651ed9203cc28414"},{"tool":"tascan_get_budget","kind":"added","observed_at":"2026-09-27T23:33:48.002Z","fields":[],"description_before":null,"description_after":"Read THIS credential's own per-key action budget (GET /budget): daily limits (sms, invites, payment-request cents per day and per request, dispatch, human pages) and today's spend against them. A NULL limit (or no budget row at all) means unlimited on that counter. A key can only ever see its OWN budget, never another key's (I-3, no tool or key ever reads another key's row). Read tier.","description_similarity":null,"before_hash":null,"after_hash":"c734fbcdda2e6551141c962c9125361a"},{"tool":"tascan_get_usage","kind":"added","observed_at":"2026-09-27T23:33:48.002Z","fields":[],"description_before":null,"description_after":"Read your organization's usage and quota snapshot for a billing period (GET /usage): SMS, email and AI call counts against their plan limits, the 100-receipt-per-month hard stop (used, allowance, hard_stop), the rate-limit window (60 requests per minute), and coordination-cycle spend in micro-USD for build roots created in that period. period defaults to the current UTC month (YYYY-MM). by_key additionally breaks coordination spend down per dispatch-scoped API key, refused (403 owner_required) to anything but an owner admin session -- a tsk_ key never gets it. Read tier.","description_similarity":null,"before_hash":null,"after_hash":"ec84a12c26cd2f165d740f8f1a45a87e"},{"tool":"tascan_request_payment","kind":"changed","observed_at":"2026-09-27T23:33:48.002Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"a497585672f69e039405b63f227e7cf8","after_hash":"7ebf716c8296754a40037b6e5beb7895"},{"tool":"tascan_send_sms","kind":"changed","observed_at":"2026-09-27T23:33:48.002Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"8f0ef778bcb2d303279e11cc83822e2e","after_hash":"5fdd681ebed5d915cfd5bbeffd590b06"},{"tool":"tascan_add_tasks","kind":"changed","observed_at":"2026-09-27T23:33:48.002Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"fd3ee9eb7fa462bd36a09839cb5e5125","after_hash":"cffa4452d4e3653b028783fdeff4784a"},{"tool":"tascan_revoke_device","kind":"added","observed_at":"2026-09-27T17:40:06.592Z","fields":[],"description_before":null,"description_after":"Revoke a device credential immediately — the kill switch for a lost, stolen, or decommissioned device (RFID portal, barcode gun, PLC, camera, robot, tool, sensor). Its next evidence post is refused. Idempotent: revoking an already-revoked device reports already_revoked and mints no second receipt. Requires the device:admin permission (owner-only, needs full, never reachable through OAuth).","description_similarity":null,"before_hash":null,"after_hash":"58cd21cbbedbc5436c354404c09aae4a"},{"tool":"tascan_get_device","kind":"added","observed_at":"2026-09-27T17:40:06.592Z","fields":[],"description_before":null,"description_after":"Get one device by id: kind, name, status, location zone, credential rotation timestamps, revocation reason, and the last 20 evidence_events ids it produced. Never returns a credential hash.","description_similarity":null,"before_hash":null,"after_hash":"13ba16cba1d83dfb69320817ad3b18b7"},{"tool":"tascan_list_devices","kind":"added","observed_at":"2026-09-27T17:40:06.592Z","fields":[],"description_before":null,"description_after":"List registered devices (RFID portals, barcode guns, PLCs, cameras, robots, tools, sensors) in the organization. Filter by status (active/revoked) or kind; paginate with an opaque cursor. Never returns a credential hash.","description_similarity":null,"before_hash":null,"after_hash":"8472e38c093e28be8505a90c8d932f00"},{"tool":"tascan_request_verification","kind":"changed","observed_at":"2026-09-24T06:50:31.041Z","fields":["annotations"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"cf9579e41a4b7dc40eb67c3c2001698e","after_hash":"cee1fa78bb397f5e53777d75c4b14e5a"},{"tool":"tascan_create_cycle","kind":"changed","observed_at":"2026-09-24T06:50:31.041Z","fields":["description","inputSchema"],"description_before":"Start an unattended build-review-decide cycle (protocol v0.2). Queues T1 CODE: (or SHELL:) with your build_brief on the AI Inbox and T2 REVIEW: with your review_brief, born blocked on T1. The local executor builds, stores the exact bytes of artifact_paths as a bundle (build_ref = sha256 over the manifest), the independent reviewer reviews THAT bundle, an approve verdict mints a Decision task for the human authority (one SMS), Approve mints an Integrate task for the deploy id. Revise verdicts spawn revisions (cap max_revisions, default 3); reject, human Reject, scope violations or exhausted revisions PARK the cycle (a Parked task with Resume with notes / Close). REQUIRES agent:dispatch:code. Duplicate protection: the same idempotency_key, or the same briefs + paths, within 24 h returns the existing root instead of queueing again (created=false). Optional `reviews[]` attaches a multi-lens review panel (design item 14a) in place of the single OpenAI review — one review task mints per lens and every blocking lens must approve before the Decision task mints. Track with tascan_get_cycle_report (root_id). Nothing spawns a cycle on its own.","description_after":"Start an unattended build-review-decide cycle (protocol v0.2). Queues T1 CODE: (or SHELL:) with your build_brief on the AI Inbox and T2 REVIEW: with your review_brief, born blocked on T1. T1 (2026-09-24 throughput): kind=review_only mints T1 as CAPTURE: instead — the executor stores the bundle from the repo at HEAD without a model call and the review runs on that; dry_run=true runs the dispatch PREFLIGHT only (nothing queued) and prints every problem at once (codes title_too_long, brief_rule, brief_names_unbundled_path, artifact_over_cap, migration_as_context (tascan repo only), idempotency_replay, kind_invalid — bad kind, bad revisable_by, review_only + task_type SHELL/RESEARCH, review_only + max_questions 0), then what the API could NOT check (unchecked[]: artifact_missing_at_head always — only the executor sees the repo, and a CAPTURE naming a missing path fails with \"[artifact_missing_at_head]\" in its error; artifact_over_cap for any path without a byte count — pass artifact_bytes; idempotency_replay only if its lookup failed) and warnings[] (a build_brief naming a context file outside the bundle); a real create that the API refuses prints the same problems[] list (when the transport hands the tool only the first problem's text, the tool re-runs the preflight and prints the whole list). The local executor builds, stores the exact bytes of artifact_paths as a bundle (build_ref = sha256 over the manifest), the independent reviewer reviews THAT bundle, an approve verdict mints a Decision task for the human authority (one SMS), Approve mints an Integrate task for the deploy id. Revise verdicts spawn revisions (cap max_revisions, default 3); reject, human Reject, scope violations or exhausted revisions PARK the cycle (a Parked task with Resume with notes / Close). REQUIRES agent:dispatch:code. Duplicate protection: the same idempotency_key, or (keyless) the same briefs + paths on a live root, within 24 h is refused by the preflight as idempotency_replay (400, nothing queued, the existing root_id in the problem) and printed as DUPLICATE with that root_id; only a replay the preflight could not see (a race) comes back from the RPC as 200 created=false, printed the same way. Optional `reviews[]` attaches a multi-lens review panel (design item 14a) in place of the single OpenAI review — one review task mints per lens and every blocking lens must approve before the Decision task mints. Track with tascan_get_cycle_report (root_id). Nothing spawns a cycle on its own.","description_similarity":0.557,"before_hash":"357843c29b829252d65ce7d5b4175e55","after_hash":"9754a5f235119d2791ea074d4783d115"}],"next_before":null,"next_actions":[]}