Done means
A new dev account can log in, and on first login already has:
- access to venue
mobile-kit by default
- an experience called My First Experience, already created
- that experience has its own public git repo on our own git, seeded as a clone of the Hydra Unreal Template
- they can clone that repo on their machine and start developing
Delivery target for the first increment is flat, on chunky-turnip-23 (Windows, Sunshine). WiVRn and the Linux lane come later.
What already exists (verified 2026-10-02)
- Login is built. hydramancer has the whole iamnim flow:
/experience/login -> iamnim with redirect_uri, /experience/authed stores an HttpOnly iamnim_session cookie, and the server calls Me(session) and Memberships(session). It is invisible only because the entire signed-in block in experience.html is wrapped in {{if .CanProvision}} and provisioning is unconfigured in the live deployment.
- Venue authorization has a definition and the data. hydravenues stores
organization_id per venue (6 of 9 set; mobile-kit = visit-flanders), and read is unauthenticated. So "venues I can deploy to" = venues whose organization_id is one of my iamnim memberships. No new concept needed.
- The library models publishers.
Developer is first class with list/create endpoints, and every experience carries owner and developer. PUT /api/v1/experiences/{name} can set districts scoping.
- hydragitprovision exists (private repo, SINGLE commit, scaffold only, 2026-08-16). It turns a verified iamnim org membership into git repo access next to a self-hosted Gitea: ensures org + creator account, creates the repo, adds the creator as WRITE collaborator, optionally registers the hydragitwatcher webhook. iamnim authenticates, it provisions.
- hydragitwatcher is LIVE (gitwatcher.experiencenet.com, health ok) and is the push-to-deploy engine for scales under #492.
What is missing
- There is no forge. No Gitea or Forgejo anywhere in the fleet (checked every hydraskin node: pi-node-001, pi-node-003, pi-node-004, hydraskin-arm-1), and no DNS for any git host. This is the foundation; nothing in item 3 of Done can proceed without it. Needs: image, scale on a hydraskin node, persistent disk, DNS, HTTPS at the edge, admin token.
- hydragitprovision has never been released or deployed. One scaffold commit. Needs CI/release, a scale deploy and config holding the Gitea admin token.
- It creates PRIVATE repos; the spec says public. And it creates an EMPTY repo, so template seeding has to be added (Gitea supports template repos and generate-from-template).
- Default org membership. Venue access derives from iamnim org membership, and today an empty membership list renders "ask your admin to add you in iamnim". A new dev account needs to land in an org automatically, and that org must own
mobile-kit. OWNER DECISION: either create a dedicated org (e.g. hydramancers) and move mobile-kit's organization_id to it, or keep mobile-kit on visit-flanders and introduce a shared/default-venue concept. Putting dev accounts into the real visit-flanders org is wrong.
- Onboarding hook. On first login: ensure developer record, create My First Experience as draft owned by their org and scoped to bxl1-test-2 / mobile-kit, provision its repo, seed it from the template.
- The creator view in hydramancer: un-gate the signed-in block from CanProvision, list my experiences, list my deployable venues, show the clone URL.
Two findings that constrain the design
Push-to-build does not transfer from scales to experiences. hydragitwatcher builds a repo's Dockerfile into an OCI image. An Unreal experience cannot be built that way: packaging needs UE 5.7.3/5.7.4 and C++ build tools on a Windows workstation via HydraUnrealEngine. So for an experience repo the git repo carries SOURCE only, the creator builds locally, and the artifact still arrives through the existing upload path. The repo-provisioning half of #492 transfers; the build half does not. Do not build toward push-to-deploy for experiences.
One experience record carries one exe_path, so it cannot serve both platforms. hydraunrealtemplate's exe_path is the Linux launcher /opt/hydra/experiences/hydraunrealtemplate/run.sh. On chunky (Windows) that path never stats, so hydrabody falls through to download and then cannot find the exe. Since delivery is chunky, each student experience needs a WINDOWS exe_path (C:\experiences\<slug>\<Name>.exe) and a Windows package. A Linux lane later needs its own library entry.
Already done under this work
- #721 fixed, released as hydraexperiencelibrary v0.10.13 and deployed to pi-node-004. Experiences with an exe_path now serve a build_url again, verified live on 4 titles, so bodies can auto-install.
- The five kit nodes are bound to district bxl1-test-2 / venue mobile-kit (#761).
hydraunrealtemplate and hellohydra-xr are now scoped to bxl1-test-2 / mobile-kit and both return a populated build_url for that pair.
- The template repo history was rewritten to a single clean commit with the internal deployment log and agent notes removed (#762); it is still private pending the owner's publication decision.
Delivered and live
All of it verified in production, not assumed.
hydramancersorgmobile-kitPOST /api/me/joinon aself_join_orgsallow-list, plus organization names on membershipsssl:perforce.hydramancers.experiencenet.com:1668, depot//hydramancers/mainseeded with 23 template filesRegistering now joins the org, creates a library developer record and creates a first experience scoped to bxl1-test-2 / mobile-kit, idempotently. Requesting source access gives a login, a one-time password, and a personal stream branched from the template.
Defects found and fixed along the way
Several of these would each have broken the flow on first real use:
UserFromEmailkeeps only the local part, so ada@example.com and ada@other.org both becameada; since an existing login counts as already provisioned, the second person would have been handed the first one's account, files and stream with no password of their own. Isolated orgs now derive the login from the whole address.ParentViewon a stream spec, andpopulate -Srefuses an empty target while the explicit form needs its flags BEFORE the paths. Both only surfaced by smoke-testing against the real server.fleet.manage_ufwdefaults to false, soensure-serverreported success while leaving the port closed and handing out an unreachable P4PORT.Still open on this ticket