Team session: PTWeb and PTAgenda
Summit priority (freeze 16:00 UTC): head d310767 is in split/rc 75203d5 (conductor's full run). Done: App Review fixes, NowModel (with NOW-M-1/2), PICK, My program (PROG-1), -PTSeedPicks, AgendaClock, agenda opens on today. Not yet seen compiled: everything after run 364 was cancelled or superseded; rc is the first run to cover it.
Branch: split/team (merged origin/dev b845004, phase 1 + vault) · Updated: 8 Nov, 12:25 UTC
Account B notes (8 Nov, about 01:50 UTC)
- Merged origin/dev (docs only). Run 293 on 6cccf88 stays queued: six runs are ahead of it, and a push now would send it to the back, so I made no Swift change yet.
- Read by eye, no compiler: PTWeb (all of Bridge/, WebPage, BridgeServices, public inits, PTCore symbols it uses) and the PTAgenda seams, ReminderPlan, AgendaBridgeServices, ReaderStore head. All types are public or private as needed; PTCore has every symbol used (Lisbon, HTTPLog, KindBadge, Palette). Nothing to fix before the first compile.
- One behaviour bug to fix with the
AppLinks.schemechange:ReminderDelegate(ReminderScheduler.swift) only acceptspromptugallinks, so a Team (ptteam) reminder tap is dropped. It will checkAppLinks.scheme. AppLinksis not on dev yet (platform ce3602e, run 292 queued).
- 02:20 UTC: Run 293 failed (cancelled by the conductor after the Debug build, iPhone and iPad tests, PTWeb and PTAsk failed). The log has one real error, twice:
BridgeScripts.swiftusedScheduleDocument.storageKeyand.changeEvent, and PTWeb cannot see PTAgenda. PTWeb now owns both strings (BridgeScripts.scheduleKey,scheduleChangeEvent) andScheduleDocumentreads them. PTAsk failed through PTWeb, so the same fix should clear it.ReminderDelegatenow acceptspromptugalandptteamlinks. Pushed as 115ba30; run 296 (app=all) queued. PTAgenda itself has not compiled yet.
- 03:20 UTC: 17a160c merged to dev as 7863ae2. Follow-up on top of dev eb99508:
ReminderPlan,ReminderItemandReminderSchedulertake their scheme fromAppLinks.scheme(read when scheduling, so launch order does not matter),ReminderDelegateaccepts only the app's own scheme, andTeamFeatures.urlSchemeis gone.AppReviewTests: StoreKit product load bounded to 15 s, then the known issue is recorded. Not yet compiled.
- 04:15 UTC: Run 313 (macos-26, app=all) on 3899bb1 green, all 15 jobs. READY sent to the conductor.
- 07:15 UTC, phase 4 review: Read platform's plan against my folders and sent platform and the conductor the findings: module rename breaks 10
@testable import PrompTugalfiles; InfoPlistTests expects the old BGTask ids; NowNext is not in PTAgenda yet, so the Team project must keep the Shared group andNowNextPublisher(or I delete the publisher calls); design'sAppShell.swift:97must compare withAppLinks.scheme. My own fixes are on split/team (dcca18e, not CI-tested):ReadingCreditViewlink fromAppLinks.open, StoreKit file found in either layout, reminder tests pass their scheme. Waiting for platform's move to review it.
- 07:25 UTC, NowNext moved (conductor ruling):
Shared/NowNext.swiftis nowPackages/PTAgenda/Sources/PTAgenda/NowNext.swift(publicNowNextSnapshot,SharedContainer,LisbonClock),App/NowNextPublisher.swiftisPackages/PTAgenda/Sources/PTAgenda/NowNextPublisher.swift(public, no team dependency), andNowNextTests.swiftis inPackages/PTAgenda/Tests/PTAgendaTests/.SharedContainer.appGroupis now a settable static (defaultgroup.news.promptugal.reader; an app with its own group sets it at launch). The widget and intents sources (PrompTugalWidgets/,PrompTugalIntents/) now needimport PTAgenda, and their targets must link PTAgenda: platform and apps. Not CI-tested.
- 11:00 UTC, round 2 (contracts §8): native Team screens. All in
Apps/Team/Sources/Team/, read throughTeamStorefrom the team site's public data, kept on the device, web page one tap away. TeamStandupAgenda.swift(parsers),StandupsView.swift(StandupsView,StandupDetailView, items): list with open counts, agenda by kind, "only items for me", briefings.MyCommandCentreView.swift(MyCommandCentreView,CentreIssuesView): decisions, issues with filters, workstreams, agents, activity, messages, sessions.TeamPage.swift,TeamPageView.swift: any twin page as native blocks (reports, board health, pulse summary);ReportsView,WakesView,PulseView.TeamStore:standupSummaries,agendas,pages,refreshAgenda(slot:),refreshPage(_:), validated paths, offline cache. Tests:Apps/Team/Tests/TeamNativeTests.swift.- Not registered: design owns
Shell/Destinations.swift. Entries to add once green:team.commandcentre→MyCommandCentreView()(kind native),team.standups→StandupsView(),agents.reports→ReportsView(),agents.wakes→WakesView(),briefings.pulse→PulseView(),briefings.board→TeamPageView(path: "board-health", title: "Board health"). - PTNowNext (conductor request):
Packages/PTNowNext(no dependencies) holdsNowNextSnapshot,SharedContainer,LisbonClock; PTAgenda depends on it and re-exports it;NowNextPublisherstays in PTAgenda. Inapps.jsonand the workspace. Exception to the project-ownership rule, approved by the conductor: I added a reference-onlyXCLocalSwiftPackageReferencefor../../Packages/PTNowNexttoApps/Team/Team.xcodeproj(platform told).PrompTugal.xcodeprojis apps': its reference and the widgets and intents product links come with their merge.
- 11:30 UTC, summit app (summit-app-store brief): conductor paused Team-native; my job is PTAgenda for participants.
NowBoard(Packages/PTAgenda/Sources/PTAgenda/Schedule/NowBoard.swift):NowBoard.snapshot(agenda:picks:now:)gives venue now/next, my now/next (a day ahead), clashes among my picks (DayPlanner.clashes(in:), extracted from the planner), per-stage now/next, and the summit phase (noAgenda,before,live,between,ended). My program is built from the picks' own event copies, so it shows even before the agenda loads.ReaderStore.nowBoard(at:)feeds it from the screen's one-minute timeline.- Offline agenda:
AgendaHub.seedAgenda(the app sets it from the core pack at launch) is read when nothing is cached;ReaderStore.agendaSource(none,seed,cache,network) andagendaUpdatedsay where the agenda came from, for "synced 3 min ago". - Reminders already work for picks with no team (
ReminderScheduler(team: nil, identity: nil)); clashes already feed the planner. Tests:NowBoardTests,NowNextSnapshotTests(PTNowNext). - Waiting for: ux's spec with screen ids. Needs from apps: PrompTugal.xcodeproj reference for PTNowNext and the widgets/intents links; from collab: set
AgendaHub.seedAgendafrom the core pack.
- 12:25 UTC, summit app (PTAgenda, all on split/team, uncompiled until rc reports):
NowModel(Schedule/NowModel.swift, pure): phase, For you (with clash flag), On now, Up next, Tomorrow, countdown, first items. NOW-M-1: first items are the firstregistrationand the firstsummititem (Opening Night); NOW-M-2: registration never takes an On now, Up next or Tomorrow slot.ReaderStore.nowModel(at:)feeds it.- PICK:
PickRules,PickFeedback(toast, clash toast with View),PickStarButton(event:),.pickToasts(),NowNextRepublisher(schedule:). App wiring (design):.pickToasts()at the root, oneScheduleStoreper app,PickStarButtonon every session row. - My program (PROG-1):
ProgramModel(clash groups, free gaps of 30 min or more, day counts,defaultDay) andMyProgramView(chooseTalks:open:); needsScheduleStore,ReminderSchedulerand an optionalPickFeedbackin the environment. Route idteam.scheduleis kept. AgendaView(openSession:): the app's native session detail (deck's PTExplore detail, per the conductor). The agenda opens on today (Lisbon) during the summit.PickSeed/ScheduleStore.seedPicks(arguments:): DEBUG-only-PTSeedPicks, slugs or full ids.AgendaClock.override(set from-PTNowin DEBUG): the one clock of the agenda screens.- App Review: PTAgenda text has no Web Summit trademark;
WebsiteSources.resourceselectsWebsitesPublic.json(the public app sets it and removes the old shortcut asset). - Waiting for: i18n's merge, then I switch my new strings to
String(localized:bundle:.module); design's registration of the screens; rc results.
Handoff
Handed off at 01:35 UTC, 8 Nov, to the session on account B.
- Head:
6cccf88onsplit/team(phase 3 moves for PTWeb and PTAgenda, on top of origin/dev 94b63c7). - Last CI run: ios.yml run 293 (
workflow_dispatch, app=all) on 6cccf88. It was still queued when I stopped. Result not seen. Read it first:actions_listfor ios.yml, branch split/team. - Done:
- PTWeb:
Bridge/,WebPage,WebsiteView,WebsiteShortcuts,Websites.json(package resource,Bundle.module). Seams:WebBridgeHub(bridge,offlineReader,noteCurrentPage) andBridgeServices,BridgeMeterSourceinBridge/BridgeServices.swift. - PTAgenda:
Schedule/(notScheduleIntents.swift),Notifications/,AgendaView,ReaderStore(inNews/). Seams inAgendaSources.swift:AgendaTeamSource,AgendaIdentitySource,VaultPicksAccess,AgendaHub,TeamStandup.AgendaBridgeServicesis the adapter for the bridge. - Team app glue:
Team/TeamAgendaConformances.swift(conformances andVaultSessionPicks),Team/TeamFeatures.swift(registerHubs()). - Tests moved: ScheduleTests and ReaderStoreTests to PTAgenda; WebsitesJSONTests and the bridge-gate / checkout tests (new
BridgeGateTests.swift) to PTWeb. - Both
Package.swiftfiles useswiftLanguageModes: [.v5], matching the app (SWIFT_VERSION 5.0). PTWeb hasresources: [.process("Resources")]. - Half-done / unknown:
- Nothing has been compiled. Expect errors: I added
publicwith a script (publicize.py, not in the repo) and generated public inits for structs without one. Likely misses: a missing public init, an@escaping, a private type in a public signature, an unimported symbol, a package test target that does not compile. - Check also that the Xcode project still builds: the app target uses synchronized folders, so moved files drop out by themselves, but
Websites.jsonandShared/are worth a look. - Exact next steps: 1. Read run 293 (
get_job_logswithfailed_only). Fix, push, dispatch ios.yml again (app=all; pushes to split/** do not trigger it). 2. Switch the reminder URL scheme toAppLinks.schemeonce PTCore has it on dev (platform, commit ce3602e on split/platform): merge origin/dev, then inPackages/PTAgenda/Sources/PTAgenda/Notifications/ReminderPlan.swiftreplace the default"promptugal"(ReminderItem.scheme,ReminderPlan.items(scheme:)) and inReminderScheduler.init(urlScheme:)useAppLinks.scheme. ThenTeamFeatures.urlSchemecan go. 3. When green, run one full run (quick=false), then send_message "@parent" with branch, commit and run number: READY. 4.Shared/NowNext.swiftstays until the widget target links PTAgenda (phase 4, platform).ScheduleIntents.swiftstays inPrompTugal/Schedule/until phase 4 (goes to the PrompTugal app). - Open questions:
- Is
swiftLanguageModes: [.v5]right for all packages? The other packages on dev do not set it. WebBridgeHub.noteCurrentPageis wired toCollabHooks.noteCurrentPageinTeamFeatures.registerHubs(). The public app needs its own wiring for Ask's "current page".- The conductor asked for PTWeb alone first, so design's PTNews could merge it. It is in the same commit as PTAgenda. If PTAgenda keeps failing, split PTWeb out by reverting PTAgenda files in a separate branch.
State
- Done: read both briefs, mapped every type in the moving folders.
- In progress: this plan.
- Next: wait for "PTCore is on dev", then merge
origin/devand move. - Blocked: nothing yet. Three questions below.
- Last CI run: none (no code changed).
What moves
| Package | Files | Lines |
|---|---|---|
| PTWeb | Bridge/ (CheckoutPolicy, AppBridge, BridgeScripts, SiteDataStores, BridgeLog, BridgeLogView), Shell/WebPage.swift, App/Web/ (WebsiteView, WebsiteShortcuts), App/Resources/Websites.json | 736 + 244 + 440 |
| PTAgenda | Schedule/ (14 files), Notifications/ (3 files), Shared/NowNext.swift | 1783 + 348 + about 80 |
NowNextPublisher.swift stays in App/ (platform). PrompTugalWidgets/NowNextWidget.swift also uses NowNext.swift, so the widget target must link PTAgenda (platform, phase 4).
Edges that point up or sideways, and how each is broken
PTWeb (may use only PTCore)
| Where | Uses | Fix |
|---|---|---|
WebPage, WebsiteView | TeamFeatures.shared.bridge (configure, attach, handlesNavigation, pageDidFinish) | AppBridge moves into PTWeb. Add WebBridgeHub in PTWeb: @MainActor public static var bridge: AppBridge?. The app sets it once at launch. The views call WebBridgeHub.bridge?.... No schedule or meter type is needed there. |
AppBridge | ScheduleStore (document, merge, markSynced, .scheduleDidChange) | New public protocol BridgeScheduleSource in PTWeb. It works on JSON ([String: Any] / Data), so ScheduleDocument stays in PTAgenda. PTAgenda gets a small adapter that wraps ScheduleStore. See question 1. |
AppBridge | MeterStore (update, snapshot, .meterHasPendingCredit) | New public protocol BridgeMeterSource (update(from:), balanceText, pending-credit notification name). MeterStore stays in the Team app and conforms. |
AppBridge | TeamIdentityStore (current, verified, .teamIdentityDidChange) | New public protocol BridgeIdentitySource (id, name, verified). Team app conforms. |
AppBridge | ReminderScheduler (currentAuthorization, reschedule) | New public protocol BridgeRemindersSource. PTAgenda's ReminderScheduler conforms (the app or PTAgenda adds the conformance). |
AppBridge | ReadingCredit.isAvailable (Store/, stays in the Team app) | A Bool / closure offersAppTopUp in the init. The Team app passes ReadingCredit.isAvailable, the PrompTugal app passes false. |
WebPage | HTTPClient.redact | PTCore (platform, phase 2). Just import PTCore. |
BridgeLog*, Lisbon | PTCore | import PTCore. |
These sources can be one protocol (BridgeServices) if you prefer. I will use one protocol with five groups, so AppBridge.init takes one services: argument instead of five.
PTAgenda (may use PTCore and PTWeb)
| Where | Uses | Fix |
|---|---|---|
Event (in App/Content.swift) | used by ScheduleStore, DayPlanner, ScheduleIntents, NowNext. Needs FeedClient.site and Lisbon. | Must be in PTCore, or PTAgenda cannot compile. See question 2. |
ReminderScheduler, ReminderSettingsView, PlannerStore, MyDayView, NextHoursCard, PlannerView | TeamStore (standups, upcomingStandups, me, centres, refresh, refreshCentre) and TeamIdentityStore (current) | Team stays in the Team app. In PTAgenda: public protocol AgendaTeamSource (standups, upcomingStandups(after:), refresh(person:)) and public protocol AgendaIdentitySource (current person id). Move the value type TeamStandup (about 30 lines, only Foundation and Lisbon) into PTAgenda. Its url uses TeamEndpoints.base, so that URL is passed in or computed by the Team app. The planner's team-coordination part (centres, TeamPerson.order, CommandCentre) is reached through one closure coordination and one closure loadTeam on PlannerStore. Views read the sources from the environment as before. @Environment(TeamStore.self) becomes an environment key for the protocol. |
ScheduleVaultLink, ScheduleVaultSync | VaultSession.shared (reader, canPush, readText, loadPicks, savePicks). PTAgenda does not depend on PTVaultUI. | public protocol VaultPicksAccess in PTAgenda (hasVault, canSave, loadPicks, savePicks, an observation hook). The app implements it over VaultSession.shared. ScheduleVaultLink takes it in init. It also takes a BridgeLog, which is in PTWeb, so that is fine. |
ScheduleIntents | TeamFeatures.shared.planner / .schedule | AgendaHub in PTAgenda: @MainActor public static var planner / schedule, set by the app. See question 3 about App Intents in a package. |
MyDayView | AppBridge (bridge in the environment) | Fine. PTAgenda depends on PTWeb. |
Notifications/ReminderPlan and the promptugal://open/team.schedule link | route string only | No type. Stays as a string. |
Stays in the Team app (team owns)
TeamFeatures stays in Team/. It builds the stores, sets WebBridgeHub.bridge and AgendaHub, and conforms the stores to the new protocols. Today it also creates ScheduleStore, PlannerStore, ReminderScheduler, AppBridge: those become public with public inits.
Resources
Websites.jsonmoves toPackages/PTWeb/Sources/PTWeb/Resources/Websites.json, declared inPackage.swiftwithresources: [.process("Resources")].WebsiteShortcutschangesBundle.maintoBundle.module.- The injected JS is inline Swift strings in
BridgeScripts.swift(no.jsfiles). Nothing to bundle. WebsitesJSONTestsreadsBundle.main. It moves toPackages/PTWeb/Testsand usesBundle.modulethrough@testable import PTWeb.- Platform: remove
Websites.jsonfrom the app's Resources build phase when its folder moves (phase 4, or when PTWeb lands).
Tests
| Test file | Where |
|---|---|
ScheduleTests, NowNextTests | Packages/PTAgenda/Tests (to confirm they use no TeamFeatures / app host) |
WebsitesJSONTests | Packages/PTWeb/Tests |
AppReviewTests (CheckoutPolicy parts) | split: CheckoutPolicy cases to PTWeb, the rest stays |
TeamFeaturesTests | stays in the Team app (it builds TeamFeatures) |
Conductor's answers (8 Nov, 00:48 Lisbon)
- JSON-level bridge.
ScheduleDocument,ScheduleMerge,ScheduleIDstay in PTAgenda. - Platform moves
EventandFeedClient.siteinto PTCore in phase 2. ScheduleIntentsstays in the app target; in phase 4 it goes to the PrompTugal app. The Team app gets no intents tonight.- The public app gets a no-team
AgendaTeamSourcethat returns nothing.
News/AgendaView.swift(204 lines) moves into PTAgenda. It readsScheduleStorefrom the environment and uses.webTwinandFeedClient(PTCore / PTWeb). Design reviews it.App/ReaderStore.swift(168 lines) moves into PTAgenda. ItsTeamFeatures.shared.scheduleandTeamFeatures.shared.agendaDidLoadbecome an injected schedule and anonAgendaLoadedclosure. PTAgenda must not import PTNews; each app addsextension ReaderStore: NewsSource {}.- Reminder links take their URL scheme from the app (
ptteam://for Team,promptugal://for the public app).ReminderPlangets aschemeparameter instead of the hard-codedpromptugal://(line 28).
Waiting for phase 2 (PTCore on dev).
Questions for the conductor (answered above)
- Schedule types across PTWeb and PTAgenda. The bridge reads and merges
ScheduleDocument. I plan a JSON-level protocol so PTWeb does not know the type. The cheaper alternative is to putScheduleDocument,ScheduleMergeandScheduleID(pure Foundation value types) in PTCore. Which do you want? Default: JSON-level protocol, no PTCore change. EventandFeedClient.siteare inApp/Content.swift. PTNews, PTAgenda and PTAsk all needEvent. Is platform moving theEventstruct (andFeedClient.site) to PTCore in phase 2? If not, I need it there.- App Intents in a package.
ScheduleIntents.swift(SessionEntity, SessionQuery, intents) is an App Intents type. Intents in a Swift package need anAppIntentsPackageconformance and the app target to include it. Safer: keepScheduleIntents.swiftin the app target and move only the stores. I propose it goes toApps/PrompTugalandApps/Team(shared source, or platform decides). OK?
Also: Store/ and Team/ stay as they are, but Team/ must not be moved by anyone until TeamFeatures is updated by me in the same phase. I will edit Team/TeamFeatures.swift, Team/TeamStore.swift conformances and Store/ only for public/conformance lines.
Needs from others
- design or platform:
Shell/AppShell.swift:97accepts onlyurl.scheme == "promptugal". When the Team app switches toptteam(phase 4) it must compare withAppLinks.scheme, or reminder taps and deep links stop opening.
- platform:
Event,FeedClient.site,Lisbon,HTTPClientpublic in PTCore (question 2). PTWeb and PTAgendaPackage.swiftwithresources:for PTWeb. - design: review
WebPage.swiftandWebsiteView.swiftafter the move (onlypublic,import, andWebBridgeHubchanges).