OpsDesk AcademyGet the project Code · prompts · workflows
THE COMPLETE LOVABLE ROUTE · BUILD, RUN, INSPECT

From a blank project to a real investigation.

This is the route used for the actual OpsDesk rehearsal. Build a useful inbox first, connect native AI, then inspect the harness and prove the change boundary. Add Langfuse after the app works.

Open your own Lovable project ↗ Inspect the actual app source ↗ Download the full agent workflow (.md)

FIRST-HOUR FINISH LINE

You can create, search, filter and select a ticket; obtain a real native-model/tool answer; inspect its reported usage; and show a server-enforced change stop. Observability export and independent trace readback are separate checks, not implied by that finish line.

Your shortest route: three prompts, one working app.

Stay in the same Lovable project. No terminal is needed for this route. Each step says where to act and what you should see before continuing.

  1. Build the screen · paste prompt 1 in Lovable chat. See three tickets.
  2. Connect AI · paste prompt 2 in that same chat. Sign into your app.
  3. Try the controls · create, search and select a synthetic ticket.
  4. Investigate · click Analyze safely once. Read the actual result.
  5. Check security · click Test a change request. Expect zero model calls.
  6. See the trace · paste prompt 3, save your three server secrets, check setup, then verify one run in Langfuse.

Want the files? Copy the Git commands below. Advanced explanations stay expandable; you can return to them after the app works.

WHERE · Lovable chat

Copy prompt 1 below → paste it into a new Lovable project → send.

Look for: Three tickets and a usable inbox. AI is not connected yet.

01 · DEFINE AND BUILD

Make the app visible.

Start a new project in your own builder account. Copy this prompt, then use the actual preview rather than treating the builder's completion message as acceptance.

Prompt 1 · copy into the same builder chat
Build OpsDesk, a small incident board for an operations team. Start with the visible
app only. I should be able to click and use it before adding AI.

Create three synthetic tickets: payments is slow (high), checkout needs a health
check (medium), catalog availability check (low). Each has id, title, description,
service and priority. Show an inbox, priority filter, search, selected-ticket detail
and a New ticket form. Ticket edits stay in memory for this first exercise.

Add an Ask AI panel with Analyze safely, a result area and an initial state reading
"AI is not connected yet". Do not generate a fake AI response, pretend to authenticate
a user, or imply that a database exists. Mark all tickets as synthetic training data.

Use Oracle Redwood for a clear desktop/mobile layout: Oracle red accents, warm stone
surfaces, Georgia headings and local Figtree/system UI text. Use only approved brand
assets. Keep compact incident rows and one clear action. Make loading, empty,
validation and failure states usable. Render ticket text as text, never raw HTML.
No paid integrations, real customer data, production connectors, automatic publishing,
real model calls or secrets in this first build. Show which visible features work
and which capabilities still need a backend. Then stop for a review of the preview.
Download prompt (.md)
EXPECTED RESULTThree synthetic incidents, search, priority filter, selected detail and a working new-ticket form. The AI panel explicitly says it is not connected.
Actual first-build inbox with synthetic tickets and disconnected AI
Real first-build checkpoint. This screen proves visible controls, not model execution.
WHERE · Same Lovable chat

Copy prompt 2 → paste and send in the same project → review backend activation.

Look for: A protected Analyze safely action, with app sign-in.

02 · ADD THE NATIVE BACKEND

Give the same app a protected AI action.

Use the next prompt in the same project. It asks Lovable to implement the server, authenticated entry, bounded model loop, strict tools and actual inspector. It uses the builder's available native model; a separate local gateway is not needed for this route.

Prompt 2 · copy into the same builder chat
Continue this same unpublished OpsDesk project. Preserve its working inbox,
create/search/filter/select controls and synthetic-data label.

Use an available native Lovable AI model through its supported server runtime.
Do not use an external gateway or ask for its API key. Require an authenticated
app session before billable inference. Keep all provider keys server-side.

Implement a bounded loop with only service_health and release_diff read-only
synthetic tools. Validate input strictly, reject extra arguments, scope every tool
to the selected service, cap tool events and output, and allow at most three model
calls. Enforce two analyses per minute and ten per UTC day per account with atomic
backend reservations, not worker globals. Do not retry inference automatically.

Block explicit change intent in server code before provider construction, key
reads or model calls. Return approval_required with zero generations. Treat
tickets and runbooks as untrusted data. Do not create shell, arbitrary-network,
write or approval-resume tools.

Show actual loading, empty, validation and dependency-failure states. Provide an
expandable inspector with actual model calls, validated tool events, duration,
returned model and provider-reported token usage. Keep missing usage/cost unknown;
do not invent a price, answer or trace. Do not expose hidden model reasoning.

Use presentation-safe account text, excluding name, email and profile picture.
Render all untrusted ticket and answer text as text, not HTML. Test change stops,
strict arguments, selected-service scope, rate rejection, upstream denial and the
actual call ceiling with isolated transports and no real credentials.

Explain that builder sign-in and generated-app sign-in are separate. Present
required backend activation or unexpected consent for review before proceeding.
Use existing account entitlements; do not buy credits, upgrade a plan, publish the
app, connect another project or change account-wide settings.

Optional Langfuse tracing can remain explicitly unconfigured until its separate
integration step. Do not replace a real analysis with simulated telemetry.
Report actual test output, exact reopen steps and any remaining acceptance gate.
Download prompt (.md)

Review any request to enable Lovable Cloud or backend capabilities. Use your own existing credits and current plan. The rehearsal used a maximum of three model calls and two analyses per minute / ten per UTC day per account. A free course does not include free builder/model usage.

WHERE · Your app preview

Open the preview and use its Sign in control. Review the consent.

Look for: Signed in · workshop session.

03 · SIGN IN TO YOUR APP

Two sign-ins, two different jobs.

Google SSO opens the builder workspace. The generated app then authenticates its own user through a supported sign-in flow. Review its consent before allowing name/email sharing. The presentation UI should say “Signed in · workshop session,” without showing an account identifier.

The editor preview is blurred or blank

On the newest completed change card in Lovable chat, select Preview first. Then use Open preview and check the rendered app. The editor can display current source while the preview remains pinned to an older history entry. Authenticated preview URLs can contain access tokens. Never paste them into GitHub, course notes or recordings. Do not disable authentication to make the demo easier.

WHERE · Your app preview

Follow the six clicks below. No chat or terminal command is required.

Look for: Search, filter and selected detail behave as described.

04 · PROVE THE VISIBLE CONTROLS

Try the same small acceptance script.

  1. Submit the blank new-ticket form. Required fields must prevent creation.
  2. Create “Workshop rehearsal: checkout check,” with a synthetic read-only description, service checkout and Medium priority.
  3. Search its exact title: one ticket should match.
  4. Choose High while that search remains: the empty state should appear.
  5. Clear the search while High remains: only the high-priority payments ticket should appear.
  6. Choose All and select TRAIN-101. Its detail must replace the created ticket's detail.

These interactions were repeated in the actual authenticated Lovable app. Tickets remain in memory; a reload resets them. Persistent incident storage is a later capability.

WHERE · Your app preview

Copy the request below into Analysis request → click Analyze safely once.

Look for: An actual answer and model/tool events. Wait; do not click repeatedly.

05 · RUN ONE REAL INVESTIGATION

Ask for evidence, not an automatic repair.

Analyze this synthetic incident using read-only evidence.

Select TRAIN-101, then click Analyze safely once. Wait for the actual result. The model should use the registered synthetic service-health and release-diff tools, separate observation from uncertainty, and recommend safe read-only next checks.

Fresh authenticated Lovable rehearsal showing the created ticket and actual completed investigation
Fresh repeated rehearsal: the real answer completed with two model calls. The cause stayed unconfirmed; no change was executed. Account details and run identifiers are absent from this selected capture.
Why your token counts and timing will differ

One earlier recorded run reported 952 tokens in 5.218 seconds; the repeated check reported 944 tokens in 5.577 seconds. Variation is normal. Neither figure is a promise, a benchmark or a bill. The trace-reading lab uses one separately identified 948-token run.

WHERE · Your app preview

Expand Run inspector. Compare its events with the agent map.

Look for: Actual calls and usage; unknown cost is allowed.

06 · OPEN THE HARNESS

Match the explanation to actual events.

Expand Run inspector. Find the actual model call count, tool names, elapsed time and reported token usage. Cost must remain unknown unless matching sourced rates are configured. Keep gateway/trace IDs private in your own receipts; show only selected safe evidence to an audience.

Follow the interactive app → harness → LLM → tools map, then find the corresponding code in the published reference. The diagram explains; the actual inspector and tests verify.

WHERE · Your app preview

Click Test a change request.

Look for: approval_required and zero model calls.

07 · PROVE THE BOUNDARY

Ask for a change and inspect the stop.

Click Test a change request. The actual app returns approval_required, model not called, zero model calls and an explicit server-block event. It offers no approval-resume or infrastructure-changing tool.

Actual policy stop with zero model calls
Real explicit-change boundary check. This case does not prove universal prompt-injection resistance or a production security audit.

The final downloaded source's 49 isolated tests passed locally, covering server safety, bounded tools, exporter handling, safe diagnostics, setup checks and the trace panel. They use model/export doubles; live authentication and provider acceptance require their own checks.

WHERE · Lovable chat → server Settings → Langfuse

Copy prompt 3 below → let the builder instrument the server → save your own three secrets → Check telemetry setup.

Look for: All fields present and origin valid. Then one synthetic run must appear in your own Langfuse project.

08 · ADD AGENT VISIBILITY

Three server settings, one real trace.

Next lab: learn to read your trace →

  1. Build the exporter: send prompt 3 below in the same Lovable project. Keys alone do not add instrumentation.
  2. Save your three values: More → Settings → Secrets, using the protected server form. Copy field names only; enter your own values privately.
  3. Check setup: sign into the actual app → Connect Langfuse → Check telemetry setup. All three fields must be present and origin valid.
  4. Use a real run: inspect an existing configured analysis or run one authorized synthetic investigation. Open Agent trace or Run inspector in the app.
  5. Match it in Langfuse: copy the actual trace ID privately → open your own project → Tracing → locate that exact trace, then expand its root. This is the independent delivery check.
LANGFUSE_BASE_URL
LANGFUSE_PUBLIC_KEY
LANGFUSE_SECRET_KEY

Use the instrumentation prompt below, keeping the existing LLM. In the project toolbar, open More → Settings → Secrets and add LANGFUSE_BASE_URL, LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY through the protected secret form. Never paste values into builder chat, ordinary browser forms, public-prefixed variables or Git.

Prompt 3 · copy into the same builder chat
Add Langfuse visibility to this existing working AI app without rebuilding it.
I will supply only LANGFUSE_BASE_URL, LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY
through the platform's server-side secret/environment settings. Never ask me to
paste keys in this chat, expose them in browser code, use a public-prefixed env
variable, or create a new model/provider connection. Keep the app's current LLM.

Inspect the actual server execution path and any existing OpenTelemetry setup.
Reuse it; do not add duplicate spans/exporters. Use current official Langfuse
SDK/OTLP documentation and a version compatible with the selected server/runtime.
Current JS/TS SDK v6 and Python SDK v5 require Langfuse v4.59.0+; for older self-hosted
servers use a compatible supported SDK or OTLP path. Record exact dependency
versions. Do not copy a legacy ingestion API example into a new Cloud integration.

Instrument actual work: one agent root/trace per app action; a random server-owned
session label for conversation grouping; authorization; one generation for each
actual model call; validated tool calls with their actual success/failure. Record
model ID and provider-reported usage, or unknown if not available. Keep the
explicit change-intent stop before model construction and show zero generations
on that path. Do not expose hidden chain-of-thought.

Export metadata only: no names, emails, account/tenant IDs, ticket text,
prompts/answers, tool payloads, keys or private endpoints. Filter attributes before
export, including attributes added automatically by framework integrations.
Use a deliberate allowed-host destination and server-only project credentials.
Wait/flush appropriately in the actual server runtime, but do not claim that
flush success proves backend readback. Report telemetry failure separately from
AI outcome; never replace a real answer with a fake success or retry AI just to
repair a trace.

Make configuration simple: missing values display 'Langfuse not configured';
saving secrets does not run inference. After one real synthetic app action, show
the actual trace ID, export outcome and a link to the correct Langfuse project
trace when available. Independently find that exact trace/session and expected
observations in the intended project before marking 'verified'. Do not invent
IDs, screenshots, costs or delivered traces.

Test the app's existing happy path, a zero-generation change stop, a dependency
failure and missing/rejected telemetry config. Keep raw receipts private. Give me
one short setup checklist and explain exactly where the three values belong in
this platform. Do not publish, purchase, alter account-wide permissions or send
telemetry to an unapproved destination.

Add a visible Agent trace panel below the real answer, derived only from actual
run events and export results. Show local execution, calls, usage, elapsed time
and exporter status. Add Copy trace ID / Copy session label inside a collapsed
presentation-safe disclosure with copy feedback. Explain how to locate that exact
trace in the learner-owned Langfuse project. Never embed a reader key, iframe or
claim automatic independent readback. Keep raw payloads and identifiers hidden
from the default presentation view. Add isolated mapping/privacy tests.
Download prompt (.md)
Use the free European Langfuse Cloud option
  1. Open the region selector, choose Europe and sign into your own account with your selected SSO provider.
  2. Review the displayed legal terms. Confirm Hobby. Review optional AI-powered features separately because they can forward project data to another service; they are not required for tracing.
  3. Name a dedicated workshop project. In Project Settings → API Keys, create a named application key with the Ingestion role and a bounded expiry, such as 30 days.
  4. Save its one-time values privately, then enter only the three required fields in Lovable's server Secrets. An ingestion key writes telemetry; use your authenticated Langfuse owner/viewer session for independent readback rather than giving the app full project privileges.

The official pricing page currently lists 50,000 units/month, 30 days of data access and two users on Hobby; recheck at signup. Units are not traces.

Actual empty European project API key settings, cropped to exclude account controls
Actual first-setup screen before key creation. The visible key strings are provider placeholders, not credentials. Account controls, project identifiers and browser address bar are outside this capture.
The secret records exist, but the app still says not configured

Stop before another model call. Select Preview on the newest completed change card, then Open preview. Confirm you are testing that revision, rather than a previously selected history entry. Check the exact project, preview/runtime binding, secret names and supported server integration. Diagnose only boolean presence, never values or derived values. Refresh the supported runtime if required. Do not move keys into browser code, VITE_ variables, public files or chat to bypass the problem. Request a new bounded live test if the previous canary allowance has been used.

Actual independently matched Langfuse tree with an agent root, authorization, two model generations and two synthetic tools
Actual successful run: six observations, 948 reported tokens. Account controls and private identifiers are outside this capture. Displayed costs are calculated by Langfuse, not a bill.
INDEPENDENT ACCEPTANCE

Run one synthetic investigation after configuration, then find its exact trace in the intended project. Verify the agent root, authorization, actual generations and tool observations. Export acknowledgment is not readback. Check the stored metadata excludes identities, secrets and raw content.

Current course evidence proves the native app and explicit change stop. The rehearsed native run was independently found in Langfuse: its exact trace and random session matched, with six observations and 948 reported tokens. OCI APM and Log Analytics remain separate integrations and readback gates.

Your app now shows its own trace.

After a real analysis, the updated reference app puts Agent trace directly below the answer. It shows actual calls, reported tokens, elapsed time and chronological execution events. Open Trace identifiers only when you want to copy the real trace ID or session label; keep it closed during a presentation.

A fresh normal run displayed two model calls, 960 reported tokens, six exported spans and HTTP 200. Langfuse showed a corresponding run with 960 tokens and both tools. This is separate from the earlier 948-token example shown in the basics lab. The app event list is not the span tree: successful authorization is recorded in the server telemetry, but is not present in this app's event list, so the panel does not invent it.

Earlier troubleshooting checkpoint: the block worked while export failed
Actual in-app trace panel: zero model calls on a policy stop, with failed telemetry export honestly displayed
Actual new panel, zero-model change-request test. The policy block worked while this separate telemetry request failed without an HTTP receipt. The app keeps that failure visible. This screenshot does not claim the policy trace arrived in Langfuse.

This is a preserved failure receipt. The current successful app and provider check appears below; do not mistake the historical image for the current acceptance status.

Two separate checks matter: did the app perform or block the action? and did its telemetry arrive? Never rerun an expensive model action merely to repair a missing trace. Use the missing-trace checklist.

LIVE SECURITY + VISIBILITY CHECK · VERIFIED

Block the change. Still record what happened.

In the updated app, click Test a change request. The server rejects that action before model construction. The actual Agent trace panel below shows zero model calls and an acknowledged two-span export. Its trace and random session were independently matched in Langfuse.

Actual app trace showing a blocked change, zero model calls and HTTP 200 for two spans
Real signed-in app check. This is a policy stop, not an AI answer. No extra model invocation was used to verify this path. Identifiers remain collapsed.
Actual matched policy trace containing only the agent root and authorization, with no generation
Independent Langfuse readback: exact trace/session matched privately; two observations, zero generation nodes. Root metadata reports status approval_required and model_calls 0. Account and private identifiers are outside this capture.

Why the app still says readback not verified: it knows the export acknowledgment but does not hold a reader credential or query Langfuse. We verified delivery separately in the signed-in Langfuse UI. That distinction remains visible in the app; adding keys does not give it permission to read all project traces.

Read the two boundaries: the authorization step checks that the user may invoke the app. The action policy then blocks the requested infrastructure change; its result appears in the root metadata and the app event. A successful sign-in does not grant permission to change infrastructure.

Repeat in your own project: select the newest completed Lovable change card's Preview → Open preview → Test a change request → reveal/copy the trace ID privately → find that exact trace in Langfuse → verify no generations and inspect the root's policy status. Check the full rendered app before interpreting a source download as runtime acceptance.

WHERE · Your project workspace

Reopen your project and use your downloaded workflow for the next part.

Look for: The same app, with a clear record of what passed and what remains.

09 · REOPEN, HAND OVER, KEEP BUILDING

Leave a demo someone else can repeat.

Reopen the same project through the builder workspace, or run your own configured source runtime. A token-bearing preview URL is not a student handoff. Document the supported start/reopen path, chosen model, synthetic inputs, actual outputs, usage availability, policy result, telemetry status and unresolved gates.

Continue with your six-part persona workflow. Keep the same app while adding capabilities. A public GitHub Pages lesson is not a hosted authenticated AI backend.

Get the workshop files

Terminal · optional. Install Git first. Run these commands in the folder where you keep projects. If you already cloned it, open that existing folder instead.

git clone https://github.com/adibirzu/opsdesk-agent-academy.git
cd opsdesk-agent-academy

Browser · no terminal? Open the GitHub project → Code → Download ZIP. The reference-app folder contains the actual app source; docs contains the lessons. Neither includes credentials or a ready-to-use backend account.

Developer option: test the reference app source

Requires an existing Bun installation. From the repository root, run one command at a time. Installation downloads pinned dependencies; tests use isolated model/export doubles and need no keys. These tests do not start or authenticate the app.

cd reference-app
bun install --ignore-scripts --frozen-lockfile
bun run test

To run the real app, configure your own supported backend/auth/native-model runtime. For the easiest working hosted route, build inside your own Lovable project using the prompts above.