Maschinell geprüftes Scope-Budget für KI-Demos am Wochenende
Wochenend-KI-Projekte scheitern meist daran, dass der Plan schneller wächst als die verfügbare Zeit. Eine prüfbare Datei mit eng begrenztem Scope soll dafür sorgen, dass die Demo tatsächlich fertig wird.

The demo ships or it does not. What decides which is a file, not an intention.
Weekend AI side projects usually fail at the same place: the plan grows faster than the clock. A single-path demo needs a much smaller surface than most people budget for, and that surface has to be enforced by something other than willpower at 11 p.m. on Sunday.
The pattern below uses three artifacts: a golden-path smoke test, a scope budget that a script is allowed to veto, and a cut table that decides in advance what gets deleted rather than deferred. The running example is a small "summarize one file into a changelog stub" service with exactly one model call in the path.
MonkeyCode's free model access and free server option are relevant here for one narrow reason: they remove two classic weekend sinks, key provisioning and deploy plumbing. The pattern itself is independent of any provider. Disclosure: This article was prepared as part of MonkeyCode's product outreach.
Write the demo as one shell command that either exits 0 or exits non-zero. If the golden path cannot be expressed as a command, the scope is not yet small enough to start.
#!/usr/bin/env bash # smoke.sh - the golden path end to end, no mocks, no manual steps set -euo pipefail BASE_URL = " ${ BASE_URL:- http://localhost:8080 } " FIXTURE = " ${ FIXTURE:- fixtures /tiny_repo.txt } " OUT = " $( mktemp ) " # 1. the service is up and self-reports curl -fsS --max-time 5 " $BASE_URL /health" | grep -q '"status":"ok"' # 2. one real request against a frozen fixture curl -fsS --max-time 45 -X POST " $BASE_URL /summarize" \ -H 'content-type: text/plain' \ --data-binary "@ $FIXTURE " \ -o " $OUT " # 3. the response is markdown with a heading, not an error page grep -q '^## ' " $OUT " || { echo "FAIL: no markdown heading"; exit 1; } grep -qi 'summary' " $OUT " || { echo "FAIL: no summary section"; exit 1; } echo "GOLDEN PATH OK ( $( wc -c < " $OUT " ) bytes)" Enter fullscreen mode Exit fullscreen mode The important property is that step 2 crosses a real network boundary. A smoke test that stubs the model call proves nothing about the demo, because the model call is the part most likely to break during a live walkthrough.
Scope creep is easier to catch as a validation error than as a feeling. Put the whole weekend in weekend.yml, then let a small checker refuse plans that cannot fit.
# weekend.yml - the plan the checker is allowed to veto budget_hours: 12 golden_path: name: " summarize one file into a changelog stub" must_pass_by: " sunday 20:00" items: - id: read-fixture hours: 1 tier: must - id: model-call hours: 2 tier: must - id: render-markdown hours: 2 tier: must - id: deploy-hosted hours: 1 tier: must - id: auth hours: 4 tier: later tripwire: " only if the demo needs more than one user" - id: history-db hours: 6 tier: later tripwire: " only if a reviewer asks for past runs" - id: settings-ui hours: 5 tier: later tripwire: " only if a config value must be edited by a non-developer" Enter fullscreen mode Exit fullscreen mode #!/usr/bin/env python3 """ scope-check.py - reject the plan before the weekend rejects it. """ import sys import yaml # pip install pyyaml MAX_MUST_ITEMS = 4 MAX_MUST_HOURS_PER_ITEM = 3 def load ( path ): with open ( path, encoding = " utf-8 " ) as fh: return yaml. safe_load ( fh ) def check ( plan ): problems = [] budget = plan [ " budget_hours " ] musts = [ i for i in plan [ " items " ] if i [ " tier " ] == " must " ] must_hours = sum ( i [ " hours " ] for i in musts ) if must_hours > budget: problems. append ( f " must items need { must_hours } h, budget is { budget } h " ) if len ( musts ) > MAX_MUST_ITEMS: problems. append ( f " { len ( musts ) } must items; the ceiling is { MAX_MUST_ITEMS } " ) for item in musts: if item [ " hours " ] > MAX_MUST_HOURS_PER_ITEM: problems. append ( f " must item ' { item [ ' id ' ] } ' is { item [ ' hours ' ] } h; split or demote it " ) for item in plan [ " items " ]: if item [ " tier " ]!= " must " and not item. get ( " tripwire " ): problems. append ( f " deferred item ' { item [ ' id ' ] } ' has no tripwire " ) return problems def main (): path = sys. argv [ 1 ] if len ( sys. argv ) > 1 else " weekend.yml " problems = check ( load ( path )) if problems: print ( " SCOPE CHECK FAILED " ) for problem in problems: print ( f " - { problem } " ) return 1 print ( " SCOPE CHECK PASSED " ) return 0 if __name__ == " __main__ ": raise SystemExit ( main ()) Enter fullscreen mode Exit fullscreen mode Example transcript for the plan above:
$ python3 scope-check.py weekend.yml SCOPE CHECK PASSED $ python3 scope-check.py weekend.yml # after adding a 4h 'oauth' must-item SCOPE CHECK FAILED - must items need 13h, budget is 12h - must item 'oauth' is 4h; split or demote it Enter fullscreen mode Exit fullscreen mode The tripwire requirement matters more than the hour math. A deferred item with a written tripwire has a condition for returning; a deferred item without one is just a wish that will resurface mid-demo.
Each additional service in the golden path multiplies the number of things that can be down at demo time. In this build, the path has exactly two: the app host and the model endpoint.
The request shape below is a sketch, not a verified contract. Endpoint paths and model identifiers change between releases, so read the project's current documentation instead of copying a blog snippet, including this one.
# shape sketch: confirm base URL and model id against current docs export MC_BASE = " ${ MC_BASE:?set from docs } " export MC_MODEL = " ${ MC_MODEL:?set from docs } " curl -fsS --max-time 45 " $MC_BASE /chat/completions" \ -H "authorization: bearer $MC_TOKEN " \ -H 'content-type: application/json' \ -d " $( jq -n --arg m " $MC_MODEL " --rawfile f fixtures/tiny_repo.txt \ '{model:$m,messages:[{role:"user",content:("Summarize as markdown:\n" + $f)}]}' ) " Enter fullscreen mode Exit fullscreen mode Two properties are worth copying regardless of provider. First, the model identifier lives in an environment variable, so switching providers is a config change rather than a code change. Second, every model call has a wall-clock timeout shorter than the smoke test's patience, so a hung request fails loudly instead of stalling a walkthrough.
Gate the whole thing behind one command and run it before every rehearsal:
check: python3 scope-check.py weekend.yml./smoke.sh Enter fullscreen mode Exit fullscreen mode The cut table Decisions get easier when the response to a scope item is chosen by rule instead of by mood.
Recent community discussion has been heavy on AI fatigue, and this cut list is the practical response to it. A smaller AI surface is easier to defend to a reader, a reviewer, or a future maintainer.
A weekend side project succeeds when the golden path runs, the plan is small enough to enforce, and the skipped list is written down. The checker and the smoke test take under an hour to write and they pay for themselves the first time a demo survives a rehearsal it should have failed.
If the free model access or the free server option is what decides whether the weekend happens at all, read the project's current terms first, then start from the smoke test rather than from the feature list. The repository is open source, so the fastest way to verify any capability claim is the source itself.