Skip to content

Feat/27 deploy flow UI - #109

Closed
Pericena wants to merge 7 commits into
mainfrom
feat/27-deploy-flow-ui
Closed

Pericena wants to merge 7 commits into
mainfrom
feat/27-deploy-flow-ui

Conversation

@Pericena

@Pericena Pericena commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Closes #27 (UI scope). Also covers part of #37 (Studio form validation) and a mobile-first UX pass, as discussed. Testnet end to end is blocked by #18 and #25 (see below).

Summary

1. Agent deploy flow (#27)

  • Reusable DeployFlow for one AgentDraft, embeddable by the Agent Studio (feat: Agent Studio UI (builder, playground, deploy) #37) with no dependency on its form.
  • Steps: preparing → waiting for signature → registering on-chain → activating → live (DeployStepper).
  • Signing only through WalletPort. It refuses to sign a transaction prepared for a different account.
  • Success: agent id, tx hash with a stellar.expert testnet link, copy buttons, and "Open agent" to /agent/:id.
  • Errors with recovery and no reload: signature rejected, transaction failed (re-prepares), backend error, plus wallet unavailable, wrong network, account changed, connection lost/timeout and invalid response.
  • DeployFlowController holds the logic: it never runs twice, resumes from the failed step and verifies every backend answer. DeployGateway is the port for the feat: register agent flow (wallet and on-chain identity) #18 endpoint; FakeDeployGateway stands in until it exists.

2. Mobile-first UX

  • Bottom navigation on phones (Marketplace, Studio, Activity, Profile) with an unread badge.
  • Compact phone type scale (14 px body, 18–28 px titles), 44 px buttons and denser inputs. Tap targets stay 48 px.
  • Marketplace: search with a clear button, sort sheet, sideways skill chips, a "Top rated" carousel, compact cards, skeletons and an empty state.
  • Activity feed and a wallet-first Profile (no passwords). Both are in memory until server endpoints exist.

3. Studio publishing rules (part of #37)

  • ADR-0004 manifest rules: name 3–48 chars, description 10–280, prompt 20–8,000, 1–5 skills, price > 0.
  • Inline errors, character counters, a "Ready to publish" checklist and agent policies that must be accepted before deploying.

4. Ratings and hire flow (on top of #92)

Acceptance criteria (#27)

  • Each error state reproduced and recovered without reload (one test per error)
  • Embeddable, no dependency on the Studio form
  • Widget tests for every progress and error state with MockWallet and a fake client
  • flutter analyze: 0 issues · flutter test: 141/141
  • Testnet end to end + GIF + tx hash: blocked. There is no register/deploy endpoint yet (feat: register agent flow (wallet and on-chain identity) #18) and no real wallet adapter yet (feat: wallet connection in Flutter app #25). Wiring it means adding one DeployGateway implementation over the generated Serverpod client; no UI change is needed.

How to verify

cd puls3_flutter
flutter analyze && flutter test --concurrency=1

Then open the app through Serverpod at http://localhost:8082/app. Serverpod caches the app for 24 h, so hard-reload with Ctrl+Shift+R after a new build. Deploy an agent, then deploy again and reject the signature.

Notes for reviewers

Pericena and others added 7 commits October 5, 2026 23:47
…27)

Reusable DeployFlow for one AgentDraft, embeddable by the Agent Studio
(#37) without depending on its form:

- DeployFlowController drives preparing -> waiting for signature ->
  registering on-chain -> activating -> live. It never runs twice at
  once, keeps finished steps so a retry resumes where it stopped, and
  verifies every backend answer (64-hex tx hash, agent id, G... wallet).
- The wallet signs through WalletPort only; it refuses to sign a
  transaction prepared for another account.
- Errors, each with a recovery action and no reload: signature
  rejected, transaction failed (re-prepares), backend error, plus
  wallet unavailable, wrong network, account changed, connection lost
  or timeout, and invalid response. Details are shown only on request.
- Presentational widgets: DeployStepper, phase card, error panel,
  success (agent id, tx hash with a testnet explorer link, copy, open
  agent) and skeletons until values arrive.
- DeployGateway is the port for the #18 register/deploy endpoint;
  FakeDeployGateway stands in until it exists.
- The top bar wallet chip shrinks instead of overflowing while the
  deploy connects the wallet on phones.

Tests: every progress and error state with MockWallet and a scripted
fake client, recovery for each error, a single run on double retry,
and no overflow from 320 px to desktop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Make the app feel like a native app on phones without changing desktop:

- Below 640 px: a bottom navigation bar (Marketplace, Studio, Activity,
  Profile) with an unread badge; the top bar keeps logo and wallet.
- Compact phone type scale (14 px body, 18-28 px titles), 44 px buttons
  and denser inputs; tap targets stay 48 px.
- Marketplace: search with clear button, sort sheet (recommended, top
  rated, price), sideways skill chips, a "Top rated" carousel, compact
  agent cards, skeletons while loading and a "No agents found" state.
- Activity: notifications with unread dots, mark all read, tap to open;
  a deploy that goes live adds one.
- Profile (wallet-first, no passwords): connect, create a profile
  (name, handle, bio) with validation, my agents, settings, disconnect.
- Studio: Create / My agents tabs and a sticky Deploy button on phones.
- Agent detail: sticky price and Hire bar on phones.

Profile and notifications are in memory until server endpoints exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Enforce the manifest rules from the agent-definition spike (ADR-0004)
before a deploy can start:

- AgentDraftRules: name 3-48 chars, description 10-280, system prompt
  20-8,000, 1-5 skills, price above 0. One human message per field.
- The form shows errors under each field after the first deploy
  attempt, character counters, and stops at five skills.
- "Ready to publish" checklist with progress, plus "I agree to the
  puls3 agent policies" and a sheet with the six policies (lawful and
  safe, no impersonation, honest listing, never ask for secrets, builder
  owns the output, testnet demo).
- Deploy with missing requirements does not open the deploy flow; it
  says how many requirements are left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hire flow:
- Review shows price, platform fee (0%), network fee and total, and
  explains the escrow (held, delivered, approve to pay or reject for a
  full refund). Without a wallet it asks to connect first.
- Every wallet failure has a message and a retry, and says no funds
  moved: rejected, not enough funds, wrong network, wallet unavailable.
- Confirmation shows the amount held in escrow, a copyable transaction,
  a testnet explorer link and what happens next; it also adds an
  Activity notification. The sheet cannot be closed while signing.

Ratings (ADR-0005: only paying clients rate):
- Agent detail shows the average, a 5-to-1 distribution and reviews
  with a verified-hire badge.
- After a paid hire the client can rate once: 1-5 stars required,
  optional comment up to 280 characters.

Reviews are in memory, seeded for the demo agents, until the server
and the Reputation Registry (#14) replace them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in merge

#92 builds AppScope directly; #27 made deployGateway required.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings the stacked work into the deploy flow branch:
- Mobile-first app shell: bottom navigation, compact type, 44 px
  buttons and denser inputs, marketplace search/sort/carousel, Activity
  and wallet-first Profile.
- Studio publishing requirements and policies (ADR-0004 manifest rules).
- Agent ratings and reviews on the agent detail page.

Conflicts with #92 (hire flow, already in main) resolved in favour of
#92's escrow summary and demo-signing honesty. On top of it: wallet
failures in plain language ("No funds moved"), a scrollable safe-area
sheet on phones, and no overflow in its title rows and address badge.
Rating stays locked after a demo signature, since #92 creates no hire.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying puls3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: a0c37cf
Status: ✅  Deploy successful!
Preview URL: https://2efb1c77.puls3-4lw.pages.dev
Branch Preview URL: https://feat-27-deploy-flow-ui.puls3-4lw.pages.dev

View logs

@Pericena Pericena self-assigned this Oct 7, 2026

@TOMOKI977 TOMOKI977 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, it's a lot of careful work. The deploy controller is genuinely solid: it resumes from the failed step, keeps the prepared and signed transaction across a lost response (so a retry doesn't register the agent twice), and never runs twice. The error-state tests and the UX pass show real attention to detail.

I need to request changes, mostly so the app never claims something that didn't happen (the same rule we applied to #92):

Blocking

  1. A production build shows a fake deploy as real. main.dart passes MockWallet() and no gateway, so app.dart falls back to FakeDeployGateway with no flag. The success screen says "Your agent is now live on Stellar" (deploy_copy.dart:86), the notification says the same (deploy_sheet.dart:45), and the stellar.expert link opens a fabricated hash. Please either gate the fake gateway behind an explicit demo flag, or label the result clearly as a demo (no "live on Stellar", no explorer link for a fake hash), like #92's "Demo signature only".

  2. Closes #27 would close the issue with the testnet end-to-end criterion unmet. Our template asks for Refs #27 in that case, listing what's missing (you already explain it well in the body).

  3. WalletPort.signTransaction still says "Signs and submits [unsignedXdr]. Returns the transaction hash." (wallet_port.dart:18), and MockWallet returns a hash that the controller passes to submitRegistration as the signed transaction. With the relay (api.md, Decision A) the wallet only signs and returns the signed XDR, and the server submits. The PR notes say this, but the code doesn't yet. A real adapter written to the current doc would submit on its own and bypass the relay. Since #25 is also yours, aligning the port now saves a rework.

  4. Invented reputation is shown as real.

    • Seeded reviews default to verifiedHire: true, so made-up reviews carry the "Verified hire" badge (review_store.dart:12,129-153).
    • The Activity seed shows "Payment received" and "New 5-star rating" (notification_center.dart:87-111).
    • A newly deployed agent gets rating: 5.0 with zero reviews (deploy_sheet.dart:55, studio_screen.dart:196).

    Only the footer says "Demo build". Please mark seeded items as demo, drop the "Verified hire" badge from seeds, and start new agents at 0.0 (RatingBadge already hides 0).

  5. Size. 58 files and ~5,200 lines across four concerns is too much to review safely, so I'd rather not grant size:exception. Suggested split, in merge order:

    • A. Theme and shell: puls3_theme.dart, breakpoint constants, content_width, primary_button, screen_header, skeleton_box, app_shell.
    • B. Deploy flow (#27): lib/src/deploy/*, ui/organisms/deploy/*, copyable_value_row, progress_step_row, deploy_sheet, the deploy_progress_view/success_panel cleanup, and their tests.
    • C. Studio publishing rules (#37): agent_draft, publish_checklist, agent_form, studio_screen, and their tests.
    • D. Mobile screens: market, activity, profile, notification center.
    • E. Ratings and reviews, last, once markHired is wired to a real hire.

For when the relay (#18, #96) is wired, not blocking now

  • retry() only re-prepares after transactionFailed or accountChanged. The relay returns PreparationExpired and superseded preparations (api.md:103,117), which today fall into backendError and would retry the same expired XDR forever.
  • DeployGateway doesn't match the documented deploy flow yet: there's no second signature for set_agent_wallet, no draftId on prepare, and no polling of the deploy session (api.md:149-172). So "no UI change needed" won't fully hold.
  • connect() and signTransaction() have no timeout, and while busy the sheet can't be closed, so a wallet popup that never answers leaves the user stuck. There's also no cancellation if the flow is disposed mid-run.

Smaller things

  • Validation counts UTF-16 code units (String.length), and the tests skip the exact boundaries (3/48, 10/280, 20/8000, 1 and 5 skills). A prompt over 8,000 shows "Write at least 20 characters", and systemPrompt is sent untrimmed.
  • The checklist labels and profile messages repeat the limits as literals next to AgentDraftRules, so they will drift.
  • Breakpoints (600/640/900/960) are repeated as raw numbers, and compactLayoutMaxWidth exists but isn't used everywhere.
  • markHired is never called from lib/, so rating is unreachable in the app. SuccessPanel and AppScope.ids are now unused. The explorer URL is built inline instead of using stellarExpertTxUrl.
  • Raw e.toString() is shown in the hire sheet error.
  • PR hygiene: a conventional title such as feat(flutter): deploy flow UI with stepper and error recovery, labels (area: frontend, type: feat), and request reviewers.

Happy to pair on the split or the WalletPort change if useful.

@Pericena

Pericena commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. I split the work as you suggested and applied the blocking fixes:

Blocking

  1. Fake deploy shown as real: fixed in Feat/27 deploy flow #112. A demo banner shows during the flow; the result reads "Demo deploy only" with no "live on Stellar", no explorer link, no agent page and no made-up hash. Demo agents are not listed.
  2. Closes #27: Feat/27 deploy flow #112 uses Refs #27 and lists what's missing (feat: register agent flow (wallet and on-chain identity) #18, feat(server): escrow relay prepare and submit endpoints for hires #96).
  3. WalletPort: fixed in Feat/27 deploy flow #112. signTransaction signs and returns the signed XDR; the server submits. MockWallet returns a marked signed placeholder instead of a hash.
  4. Invented reputation: new agents start at 0.0 in Feat/27 deploy flow #112. Seeded notifications and reviews (marked as demo, no "Verified hire") are handled in D and E.
  5. Size: split into feat(flutter): mobile-first theme and app shell #111 and Feat/27 deploy flow #112. C (Studio publishing rules, feat: Agent Studio UI (builder, playground, deploy) #37), D (mobile screens) and E (ratings, last, once markHired is wired to a real hire) follow as separate PRs.

Relay notes, also handled in #112: re-prepare on PreparationExpired, a timeout for a wallet that never answers (the sheet can be closed while the wallet prompt is open), and cancellation if the flow is closed mid-run. Full DeployGateway alignment (set_agent_wallet, draftId, session polling) goes with #18/#96.

Smaller things: stellarExpertTxUrl, and SuccessPanel/AppScope.ids removed, in #112. Validation (character counting, exact-boundary tests, shared limits, trimmed prompt) goes in C. The hire sheet's raw e.toString() goes in D.

Closing this PR in favour of #111 and #112. Thanks for the offer to pair. I'll ping you on the C split if needed.

TOMOKI977 added a commit that referenced this pull request Oct 7, 2026
Part A of the #109 split (theme and shell). No screen content changes.

- Puls3Breakpoints: one set of named layout breakpoints instead of raw
  600/640/700/900/960/1000 numbers across screens and widgets, plus
  isCompactLayout().
- Phone type scale below 640 px (14 px body, 18-28 px titles), set by
  the app root; desktop keeps the brand sizes.
- Compact visual density and denser inputs on phones; PrimaryButton is
  44 px tall there (52 on desktop) inside a 48 px tap target.
- Bottom navigation bar on phones (Studio, Marketplace); the top bar
  keeps the logo and a wallet chip that shrinks instead of overflowing.
- ScreenHeader and SkeletonBox building blocks for the following parts.

Tests: bottom bar on phones only, compact type and button size, and no
overflow on every screen at 320, 360, 390 and 414 px.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Julio Cesar Severiche Orellana <39506930+TOMOKI977@users.noreply.github.com>
@TOMOKI977

Copy link
Copy Markdown
Contributor

@Pericena this one is superseded by the split (#111 merged, #112 and #113 open). Could you close it so the review queue stays clear? Thanks!

@Pericena

Pericena commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Closed in favor of #111 (merged), #112 and #113. Thanks!

@Pericena Pericena closed this Oct 8, 2026
Pericena added a commit that referenced this pull request Oct 8, 2026
Part B of the #109 split. Refs #27: the testnet end-to-end criterion
waits for the deploy endpoint (#18) and the relay (#96).

- DeployFlow + DeployFlowController: preparing -> waiting for signature
  -> registering on-chain -> activating -> live. Never runs twice,
  resumes from the failed step, keeps the prepared and signed
  transaction across a lost response, verifies every backend answer,
  and stops if the flow is closed mid-run.
- Presentational widgets: DeployStepper, phase card, error panel and
  success, with skeletons until values arrive.
- Errors with a recovery action and no reload: signature rejected,
  transaction failed, backend error, plus wallet unavailable, wrong
  network, account changed, connection lost/timeout, invalid response,
  expired preparation (prepares again) and a wallet that never answers
  (times out; the sheet can be closed while the wallet prompt is open).

Review fixes:
- The demo gateway is labelled: a banner says nothing is registered on
  Stellar, and the result reads "Demo deploy only" with no explorer
  link, no agent page and no made-up hash. Demo agents are not listed.
- WalletPort.signTransaction only signs and returns the signed XDR; the
  server submits (API contract #77, Decision A). MockWallet returns a
  marked signed placeholder instead of a hash.
- Real agents start at a 0.0 rating; explorer links use
  stellarExpertTxUrl; the unused SuccessPanel, DeployProgressView and
  AppScope.ids are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TOMOKI977 pushed a commit that referenced this pull request Oct 8, 2026
Refs #27. Part B of the #109 split; supersedes #109. Demo gateway until the deploy endpoint (#18) and the relay (#96) are live.
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.

feat: agent deploy flow UI (progress, result, errors)

2 participants