Skip to content

submit four apps: deadsimple, rentahuman, upfile, kinetic - #100

Open
Alexgodoroja wants to merge 4 commits into
mainfrom
apps/deadsimple-rentahuman
Open

submit four apps: deadsimple, rentahuman, upfile, kinetic#100
Alexgodoroja wants to merge 4 commits into
mainfrom
apps/deadsimple-rentahuman

Conversation

@Alexgodoroja

Copy link
Copy Markdown
Collaborator

Two apps from the publish queue, both authored against the live APIs rather than from the submitted listing alone. Kinetic and Upfile follow separately — status at the bottom.

io.pilot.deadsimple — byo + agent signup

An email identity an agent provisions for itself. deadsimple.signup is declared as a create signup step, so the adapter caches the returned key as DEADSIMPLE_API_KEY and every other method authenticates with it. No dashboard, no verification email, no human anywhere in the loop.

Tested live. I provisioned a real account and inbox with no key and no human, got the documented trial tier back (1 inbox, 10 sends/hour, 25/day), then used that address to sign up for a third-party service and complete onboarding — the exact loop the app exists for.

That run corrected my own draft: every response is wrapped under data, and the inbox field is email, not address. The submitted expects were wrong; these match what the API returns. Worth noting because it is the kind of thing a paper review never catches.

io.pilot.rentahuman — managed, Partner API

Rebuilt against the Partner API rather than the marketplace endpoints in the original submission. Five methods instead of fifteen: describe a task in plain language, poll it, answer ops questions, list what is in flight. No account for the end user to create, no escrow for the agent to manage, no dashboard key.

Partner access is enterprise-gated and one key per partner, which is exactly the managed shape — the broker holds the key and meters per caller, and the adapter ships keyless. Endpoints verified live: 401 with a bogus key, and 404 on a path I invented as a control, so the 401s mean the routes are real.

The whole app hinges on one property, so it is stated in the description, the demo, the gotchas and the next-steps graph: RentAHuman never contacts the end customer. Quotes and payment links arrive addressed to the agent, and nothing reaches a customer unless the agent relays it. An integration that wires webhooks straight through to a customer channel would be wrong in a way that is hard to walk back.

Gates

deadsimple rentahuman
verify-submission (4 platforms)
demo-score 100.0 100.0
demo / next-steps / gateway validators
methods 19 5

Ops note before rentahuman goes live

As a managed app it needs a partner key registered with the broker (RENTAHUMAN_MASTER_KEY) before any call will work. Partner access is not self-serve — it comes from RentAHuman by email. Until that is done the app installs and every call 401s at the broker, which is the documented managed go-live step rather than a defect.

Not in this PR

  • Kinetic — approved as managed. I tested the live key and found that /v1/integrations (16 token and grant methods) and /v1/billing (8, including subscription cancel) are unsafe on a shared key: api_token_create would let any user mint a kinetic.full token on the shared account. The submission needs a curated subset plus broker tenancy on studies, which I am authoring next.
  • Upfile — CLI sourced. bun --compile produces binaries that silently fail on upload (Body already used); it is a bun/node-fetch incompatibility, not an Upfile bug, and it reproduces with bun as a plain runtime. Node SEA works — the darwin/arm64 build does a real upload returning a live CDN URL. Remaining work is the other three platforms and the asset upload.

Alex Godoroja and others added 3 commits August 6, 2026 08:49
Two apps from the publish queue, both authored against the live APIs rather than
from the submitted listing alone.

io.pilot.deadsimple (byo + agent signup)

An email identity an agent provisions for itself. deadsimple.signup is a "create"
signup step, so the adapter caches the returned key as DEADSIMPLE_API_KEY and
every other method authenticates with it — no dashboard and no verification email
anywhere in the loop. The method agents will actually reach for is
get_verification_code, which pulls a one-time code or magic link out of the
newest inbound message.

Tested live: provisioned a real account and inbox with no key and no human, got
back the documented trial tier (1 inbox, 10 sends/hour, 25/day), then used that
address to sign up for a third-party service and complete onboarding. That run
corrected the demo — every response is wrapped under "data", and the inbox field
is "email", not "address". The submitted expects were wrong; these match what the
API actually returns.

io.pilot.rentahuman (managed, Partner API)

Rebuilt against the Partner API rather than the marketplace endpoints in the
original submission. Five methods instead of fifteen: describe a task in plain
language, poll it, answer ops questions, list what is in flight. No account for
the end user to create, no escrow for the agent to manage.

Partner access is enterprise-gated and one key per partner, which is exactly the
managed shape: the broker holds the key and meters per caller, and the adapter
ships keyless. Endpoints verified live — 401 with a bogus key, and 404 on a path
invented as a control, so the 401s mean the routes are real.

The whole app hinges on one property, so it is stated in the description, the
demo, the gotchas and the next-steps graph: RentAHuman never contacts the end
customer. Quotes and payment links arrive addressed to the agent, and nothing
reaches a customer unless the agent relays it.

Both carry a product demo scoring 100.0 and a next-steps graph, and both pass
verify-submission across all four platforms.

Ops note for rentahuman: as a managed app it needs a partner key registered with
the broker before go-live (RENTAHUMAN_MASTER_KEY), obtained from RentAHuman by
email — partner access is not self-serve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Upfile publishes to npm and nowhere else — the v0.2.3 GitHub release carries
zero assets, there is no install.sh (checked four URL conventions), the README
says "npm install -g upfilesh", and the only workflow is an npm publish. So the
per-platform binaries are built here rather than downloaded.

Built with Node SEA, not bun. bun --compile produces binaries that pass a smoke
test and then silently fail every upload with "Body already used". That is a
bun/node-fetch incompatibility rather than an Upfile defect: the same code works
under node and fails under bun as a plain runtime too. Shipping those would have
put a broken CLI in the catalogue that looked fine.

All four platforms were run, not just built:
  darwin/arm64   real upload, live CDN URL
  darwin/amd64   runs under Rosetta
  linux/amd64    signup + real upload on Debian 12, file served back
  linux/arm64    runs under aarch64 emulation

Packaged as tar.gz to match the other CLI apps, which also cuts each artifact
from ~110MB to ~34MB (SEA embeds the node runtime). Tarred with xattr -cr,
COPYFILE_DISABLE and --no-mac-metadata, verified free of ._* junk. All four are
live on the artifact registry and were fetched back over their public URLs and
sha-checked.

The method surface is curated rather than the single passthrough in the original
submission: signup, three upload shapes (public, private, expiring), status,
list, remove, version, cli_help, plus run as the escape hatch. upfile.signup is
programmatic — no browser, no dashboard — which is what makes the app reachable
end to end from pilotctl.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pricing research an agent can drive end to end: pick the method that fits the
decision, draft and preview the survey, collect responses from your own
customers, read deterministic results.

27 methods, curated down from the 99 in the original submission. What was left
out matters more than what was kept, because this is a managed app where every
Pilot user acts as one shared account:

  /v1/integrations (16)  api tokens and OAuth grants. api_token_create on a
                         shared key would let any user mint a kinetic.full
                         token usable outside Pilot forever; api_token_rotate
                         would let any user invalidate the master key for
                         everyone. Verified live: the token list returns the
                         master token's prefix and scope.
  /v1/billing/subscription (4)  subscription cancel/resume are account-global.
  /v1/account, /v1/team, /v1/workspace  shared-account administration.

Checkout IS included, deliberately. study_checkout_create returns a Stripe link
and does not complete the purchase, so the $149-$199 study fee is paid by the
human who opens the link rather than drawn from a Pilot budget. Every other
method is free, which is why the worked demo total is $0.00 against the $5
per-user budget.

The demo and the next-steps graph both lead with the two things an agent gets
wrong here: that Van Westendorp and Gabor-Granger answer different questions, so
the wrong choice yields a confident useless number; and that a clean-looking
result from speeders and straight-liners is worthless, so study_quality_get and
study_progress_get come before believing anything.

Ops note: this needs KINETIC_MASTER_KEY registered with the broker, a credit
block seeding each user, AND broker tenancy on /v1/studies. Without tenancy every
user can list and read every other user's studies on the shared account.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Alexgodoroja Alexgodoroja changed the title submit io.pilot.deadsimple v0.1.0 and io.pilot.rentahuman v0.2.0 submit four apps: deadsimple, rentahuman, upfile, kinetic Aug 6, 2026
…tack tests

Both apps front a SHARED partner account — one key for every Pilot user — so the
partner cannot tell tenants apart and the broker is the only isolation boundary.
Without this, any Pilot user could read, edit and launch any other user's pricing
studies, and read another user's RentAHuman request thread including the
requester's phone number.

Registry entries land in deploy/broker-entries/ so ops applies reviewed config
rather than hand-editing JSON on the VM.

Tests are written as attacks, following zz_tenancy_test.go: Mallory tries to
reach Alice's resource and must get 404, paired with an assertion that Alice's
own access still works. Verified they bite — disabling tenancy flips 7 of the 8
to failure, so they are not passing vacuously.

Three things the work surfaced:

- param_types is keyed by param name GLOBALLY, and Kinetic reused {id} for
  studies, teardowns and tasks. Left alone those collapse into one type and a
  task id gets ownership-checked as a study. The submission now names each
  resource distinctly ({study_id}, {teardown_id}, {task_id}).

- The registry validator rejected a `task` type that nothing creates or
  list-claims: "referenced but never created — nobody could ever own it". It was
  right, and it would have 404'd every task read for its legitimate owner. Task
  ids are opaque handles from long-running ops, so they are left unchecked rather
  than unreachable.

- study_id arrives in the BODY on checkout, not the path, so body_refs is what
  stops Mallory paying against Alice's study. A path-only check misses it.

Also corrects the Kinetic submission against the live API, which contradicted
what the listing implied: POST /v1/studies takes name, product_desc, segment_desc,
decision_type and currency — NOT a study_type — and derives the methodology from
decision_type. Every mutating route also requires an Idempotency-Key header. Both
were wrong in the submitted spec and in my first draft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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