Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use as the final stage of the Butterbase journey when hackathon_mode is true and journey-deploy has passed. Resolves which hackathon to submit to (asking the user when multiple are open), walks every field in the hackathon's returned field_schema with the user one at a time, then calls prep_and_submit_hackathon_entry. Writes the receipt to docs/butterbase/05-submission.md.
.claude/skills/butterbase-ai-journey-submit/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 1035% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 128% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 33% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 134% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 18% | 0% |
Stage 5 (final) of the guided journey. Resolve the active hackathon, confirm fields, submit.
journey when current_stage: submit and hackathon_mode: true./butterbase-skills:submit."submit is disabled outside hackathon mode") if hackathon_mode: false.If docs/butterbase/03-preflight.md is missing, older than 24 hours, or 00-state.md has app_id: null, invoke butterbase-skills:journey-preflight first. Wait for it to return successfully before proceeding.
Additionally: refuse to run unless deploy is ticked in 00-state.md. If it is not, tell the user to run /butterbase-skills:journey-deploy first.
docs/butterbase/01-idea.md — title / tagline candidates.docs/butterbase/02-plan.md — feature list.docs/butterbase/04-build-log.md — what actually shipped.docs/butterbase/00-state.md — app_id, deployed_url.Always start with action: "prep". Do not assume there is exactly one hackathon, and do not invent a field schema from prior context — the platform owns the schema and it varies per hackathon.
jsonc// First, ask the user: "Do you have a submission code from the organizer? (paste it, or 'no')" // If yes, pass it. If no, omit it. { "tool": "prep_and_submit_hackathon_entry", "arguments": { "action": "prep", "submission_code": "<optional, from user>" } }
The response shape is:
jsonc{ "matched": null | { "slug", "name", "submission_deadline", "ends_at", "field_schema": { "fields": [...] } }, "match_reason": null | "submission_code" | "already_bound" | "single_open", "open_hackathons": [{ "slug", "name", "starts_at", "ends_at", "submission_deadline" }, ...], "next_call": { ... } // present only when matched is non-null }
Branch on the result:
| matched | open_hackathons.length | Action | |---|---|---| | non-null | any | Resolved — continue to Step 2 with matched.field_schema. Mention match_reason to the user ("Resolved via your submission code", "You're already a participant in X", "Only one hackathon is open: X"). | | null | 0 | No hackathon is currently open for submissions. Tell the user, stop, and do not tick submit. | | null | 1 | One hackathon is open but the user isn't bound and didn't supply a code. Ask: "The only open hackathon is '<name>' (deadline <submission_deadline>). Submit to this one? If so, paste the submission_code the organizer gave you." Re-run prep with the code. | | null | ≥ 2 | Multiple open hackathons — ask the user which one. Present the list (name, slug, deadline) and ask: "Which hackathon are you submitting to? Paste its submission_code." Re-run prep with the code. Never guess. |
> Anti-pattern: do not re-run prep in a loop hoping it resolves — it won't until the user provides a submission_code. One question, then re-prep.
matched.field_schema.fields is the authoritative list of fields for this hackathon. Walk every field in order. For each:
label (not key) and description.is_url: true or type: "url") for the deployed app → deployed_url from 00-state.md.01-idea.md.01-idea.md + must-haves.required: false.options-typed fields, present the allowed choices verbatim.Use next_call.arguments.data from the prep response as the literal template — it has one key per field with a placeholder string. Replace each placeholder with the confirmed value.
Show the assembled data object back to the user verbatim and ask: "Submit now? (yes/no)". On yes:
jsonc{ "tool": "prep_and_submit_hackathon_entry", "arguments": { "action": "submit", "hackathon_slug": "<matched.slug from prep — REQUIRED when multiple are open>", "app_id": "<app_id from 00-state.md — strongly recommended, unlocks +50 scoring points>", "submission_code": "<same code passed to prep, if any — required on first submission>", "data": { /* user-confirmed values keyed by field.key */ } } }
> Always pass hackathon_slug = matched.slug from prep. Without it, submit re-resolves and may target a different hackathon if more than one is open. > Always pass app_id — scoring awards up to 50 points for Butterbase usage on that specific app.
Capture the response (submission.id, submission.version, submission.updated_at, participant_created) and write docs/butterbase/05-submission.md:
markdown# Submission - submitted_at: <submission.updated_at> - submission_id: <submission.id> - version: <submission.version> - hackathon_slug: <submission.hackathon_slug> - hackathon_name: <matched.name> - app_id: <submission.app_id> - participant_created: <true|false> ## Fields submitted <one bullet per field: label → value>
Tick - [x] submit in 00-state.md, set current_stage: done. Print a one-line success to the user including the hackathon name and submission id.
prep_and_submit_hackathon_entry (action: "prep" then "submit").docs/butterbase/05-submission.md.action: "prep" and calling submit directly with a hardcoded field list.open_hackathons on the prep response.matched.field_schema.fields.hackathon_slug from prep (can re-resolve to the wrong hackathon).app_id when one exists (forfeits up to 50 scoring points).yes from the user on the assembled payload.Other measured skills in the registry, with their headline benchmark lift.