| 104 |
Status idea |

There in x minutes. |
N |
1 |
1 |
2026-08-26 21:10:47 |
2026-08-30 09:12:25 |
| 105 |
Freight legs |
Should a service that has no passenger timetable but is all wtt use the wtt stops as legs?
Currently our map uses the stops but not the test in the summary.
 |
N |
1 |
1 |
2026-08-27 06:02:50 |
2026-09-06 09:46:37 |
| 106 |
Persisting changed platforms |
 |
N |
1 |
0 |
2026-08-28 06:10:35 |
2026-08-28 06:10:35 |
| 107 |
Reflecting lateness - check for complete implementation |
Reflecting lateness in all output
Done on the Service Summary popup, the Live Status Trace and the Full Schedule Popup. |
N |
1 |
0 |
2026-08-28 06:11:20 |
2026-08-28 09:10:43 |
| 108 |
Edits to schedule popup |
This to show +- late after station only on current line and change background to light red when >=10 mins late, amber if >=3<10 |
N |
1 |
1 |
2026-08-28 06:14:56 |
2026-08-28 09:09:30 |
| 109 |
Add detail to Service Summary popup |
I’d like to extend the status box to a second line:
When running: add ‘be there in <x> minutes <arr time adjusted for lateness>’
When at platform: ‘deporting at <pass arr + lateness>’
When terminated: ‘arrived at <actual arr time>’
The lack of initial capitalisation is deliberate and I’ll like it to be slightly smaller text. |
N |
1 |
1 |
2026-08-28 06:29:38 |
2026-08-28 09:09:26 |
| 110 |
A map on the Live Service Trace |
Be able to toggle a map on or off.
Left right on desktop, top bottom on mobile with the table scrollable and the map pan/zoomable.
Click a row on the table it gets highlighted on the map, click the map somewhere and the nearest row is shown. |
N |
1 |
0 |
2026-08-28 21:11:19 |
2026-08-28 21:11:19 |
| 111 |
Tablet experience |
Congestion at the top
The click map to expand does not work, why not make the button do it as well |
N |
1 |
1 |
2026-08-29 13:09:29 |
2026-09-06 09:46:07 |
| 112 |
Station summary arr time for term |
The arrival time for a terminated service is the planned time, change to actual
Same here, 2003 is the planned arrival. |
N |
1 |
1 |
2026-08-29 19:27:13 |
2026-09-06 09:46:02 |
| 113 |
Full schedule summary |
Have a tick box to change the full schedule to the summary schedule, stops and starts only, and only and make the last visited station the shaded one. |
N |
1 |
0 |
2026-08-29 19:32:26 |
2026-08-29 19:32:26 |
| 114 |
Formation diagram notes |
 |
N |
1 |
1 |
2026-08-29 20:16:10 |
2026-09-06 09:45:49 |
| 115 |
This is Sunday 8am??? |

 |
N |
1 |
1 |
2026-08-30 07:16:01 |
2026-09-06 09:45:34 |
| 116 |
Table groups |
Can you group tables in mysql |
N |
1 |
0 |
2026-08-30 08:00:23 |
2026-08-30 08:00:23 |
| 117 |
SSH Permissions |
Can I give permissions for:SSH tunnel
MySQL to access
Flask server local and use to test |
N |
1 |
0 |
2026-08-30 08:01:35 |
2026-09-07 07:18:56 |
| 118 |
Codes in formation |

So, Y seems to be bicycles and gw wheelchair, at least on Xcountry. |
N |
1 |
0 |
2026-08-30 09:14:37 |
2026-08-30 09:14:37 |
| 119 |
Mac paste |
git diff -- ios/GRM.xcodeproj/project.pbxproj
git stash push -m "Mac Xcode signing settings" -- ios/GRM.xcodeproj/project.pbxproj
git pull --ff-only origin main
git stash pop |
N |
1 |
1 |
2026-08-30 12:43:02 |
2026-08-30 12:48:11 |
| 120 |
TRTS identified … |
But not a red line 😄 |
N |
1 |
1 |
2026-08-30 13:35:45 |
2026-09-06 09:44:18 |
| 121 |
Nav idea |

I'd like to make a move to this style of navigation, always there, never covered, always on top of a map II think from here in there will always be a map in the background and everything gets overlayed on it, including these 'glass' buttons.
For IOS I'd like to use native controls, for the html only versions (main and demo) I'd like to use html and CSS to get the closest to the ios version as it is the most important of the 3.
I feel that there are going to be 4 buttons:
1) Map. Fixed, always map, takes you right back to the map.
2) Choices. Where there are options to be applied to the in focus view these options should be accessed from this button, so it will vary depending on the in focus view.
3) Settings, various settings like debug in test domain, other uses TBD.
4) Help. Information and help resources.
Please review this as a concept, don't be concerned about how each options fills the screen right now just evaluate the concept. |
N |
1 |
1 |
2026-09-01 07:00:27 |
2026-09-03 09:41:24 |
| 122 |
Traverse speeds |
Investigate timings regarding initial acceleration and deceleration.
Currently the app spends a lot of a leg being ahead, accelerates faster than the real train then stays ahead, then gets behind near the end because our average speed is lees than line speed, then catches up as the train actually decelerates and crawls into the station.
How can we make our traversal more real. Its not the arrival its the getting there :) There must be theories about this. |
N |
1 |
0 |
2026-09-01 09:58:37 |
2026-09-01 10:01:45 |
| 123 |
Geolocated visitor log |
And sortable and searchable viewer
Linked from debug in test domain.
No cost geolocation if possible. |
N |
1 |
1 |
2026-09-01 11:45:29 |
2026-09-06 09:44:06 |
| 124 |
Replayer |
Journey Replayer — feasibility and design
I would like to explore a Journey Replayer for GRM.
The eventual aim is to be able to completely replay the journey of either:
* a currently live service; or
* a service archived in ana2.
For now, do not rush into implementing the complete feature. First investigate the existing GRM code, data model and map architecture, assess the feasibility of the proposal below, identify anything impractical or unnecessarily complicated, and suggest a sensible implementation approach.
The objective of this exercise is both to test feasibility and to finesse the design before committing to it.
Core replay view
I envisage a replay screen containing three main elements:
1. Map
* The main visual element.
* Show the service moving geographically as its journey is replayed.
* The map should use as much of the available screen as possible.
* It must remain fully pan/zoomable during replay.
2. Evidence display
* Along the bottom of the display where practical.
* Approximately three lines high rather than a large scrolling diagnostic window.
* Show the summarised evidence being encountered during replay.
* Initially I am interested in the relevant TD and TRUST evidence and the Resolved lines only.
* The intention is to let someone visually correlate:
what GRM knew → what GRM resolved → where the train is shown.
3. WTT schedule
* Show the service’s working timetable alongside the map.
* Present it as a compact sequence of timing points/times rather than consuming unnecessary screen width.
* Clearly indicate the point in the WTT corresponding to the current replay position.
* Ideally distinguish what has already happened, what is current, and what is still ahead.
Replay controls
Provide controls to:
* step forward through replay events;
* step backwards if the underlying replay model makes this practical;
* play continuously;
* pause;
* increase/decrease replay speed;
* seek through the journey, ideally with a slider or similar timeline control.
The important principle is that replay should be deterministic: selecting the same archived service and replay position should reproduce the same GRM state/evidence rather than re-running interpretation using today’s data or assumptions.
Please investigate whether the existing retained data is sufficient to achieve this.
Entry points
There should eventually be a Journey Replayer menu option.
Its behaviour depends on context.
If a service is already selected
Launch Journey Replayer directly for that service.
For a currently live service, replay from the beginning of the available journey up to the present/current known position.
For an archived service, make its complete retained journey available.
If no service is selected
Launch a service selector first.
The selector should allow the user to enter:
* one station; or
* a pair of stations.
Present matching services with:
* live services first;
* archived services afterwards.
Where many instances of effectively the same service match, initially present a unique/grouped service list rather than immediately displaying every historical instance.
For each grouped result show, where applicable:
* number of live instances in green;
* number of archived instances in red.
Selecting the grouped result should expand it to show the individual services it represents. The user can then select the exact live or archived service to replay.
Please investigate what constitutes the best stable identity/grouping for these services using the existing GRM data rather than inventing a new identity unnecessarily.
Responsive layout
I am particularly concerned about making this useful on mobile screens.
The layout should respond primarily to the geographical orientation of the service on the map, not simply portrait/landscape orientation of the device.
If the service’s geographical extent is predominantly vertical:
* map on the left;
* WTT schedule on the right;
* WTT panel should be hideable/showable so the map can regain the width when required.
If the service’s geographical extent is predominantly horizontal:
* WTT schedule horizontally across the top;
* map underneath it.
The evidence/replay controls should occupy the minimum practical space while remaining readable and touch-friendly.
Do not permanently sacrifice map area merely to preserve a rigid desktop-style layout.
The aim is to make maximum use of available width and height and minimise unnecessary table/panel scrolling.
The map itself should effectively occupy the available full-screen working area around whichever temporary/overlay controls are required.
Please also consider whether automatically changing layout based on route orientation could itself become distracting—for example on curved routes—and suggest a stable rule for determining the layout once a service is loaded.
Mobile simplification
If all three elements — map, WTT and evidence — cannot sensibly coexist on a small mobile screen, do not simply shrink everything until it technically fits.
Instead consider progressive disclosure, overlays, drawers, hide/show controls or other approaches that retain the map as the primary visual object.
I would prefer a clean, useful mobile implementation over attempting to reproduce the desktop arrangement at miniature scale.
Architecture
Please investigate whether replay can reuse the existing GRM:
* service presentation model;
* mapping/path geometry;
* live-service interpretation;
* TD evidence;
* TRUST evidence;
* resolved evidence;
* WTT/schedule data;
* ana2 archive.
I particularly want to avoid building a completely separate interpretation engine merely for replay.
Ideally Journey Replayer should consume the same underlying facts and interpretation logic as the live presentation, with the effective time controlled by the replay position.
However, do not assume this is possible. Determine from the existing implementation whether replaying historical interpretation from retained evidence is actually safe and deterministic.
First task — investigate, don’t build the whole thing
Please inspect the repository and report back with:
1. What parts of this proposal are straightforward with the existing architecture/data.
2. What parts are difficult or currently impossible.
3. Whether ana2 contains sufficient information for a faithful historical replay.
4. Whether live TD/TRUST/Resolved evidence is retained with sufficient timestamps and ordering.
5. How you would define the replay event/timeline model.
6. How much existing live presentation/interpretation code can be reused.
7. How service lookup/grouping should work.
8. A proposed desktop/tablet/mobile layout.
9. Any concerns about performance, particularly when loading a complete archived journey.
10. Any ambiguities or design decisions that should be resolved before implementation.
Then propose a staged implementation plan.
I would expect something roughly along the lines of:
Phase 1: prove that one known archived service can be reconstructed as an ordered replay timeline.
Phase 2: simple replay UI — map + WTT + evidence + step/play controls.
Phase 3: responsive/mobile layout.
Phase 4: service search/grouping and menu entry points.
But please change that sequence if inspection of the existing GRM architecture suggests a better approach.
The first milestone should be a small proof of concept using one real service, not the complete Journey Replayer.
Do not implement the full feature until we have reviewed the feasibility findings and proposed architecture. |
N |
1 |
1 |
2026-09-01 14:05:43 |
2026-09-06 09:44:01 |
| 125 |
Mobile UI issues |
Here
 |
N |
1 |
1 |
2026-09-01 19:21:58 |
2026-09-06 09:43:57 |
| 126 |
Replay a random |

Replay a random 1, 2 or 9 class service here. |
N |
1 |
1 |
2026-09-01 20:24:53 |
2026-09-06 09:43:36 |
| 127 |
Cycle the demo locations |
Every, say, 15 seconds cycle the 3 locations. Stop the cycle when one is picked.
 |
N |
1 |
0 |
2026-09-01 20:26:58 |
2026-09-01 20:26:58 |
| 128 |
Great snips here |

 |
N |
1 |
0 |
2026-09-02 06:55:07 |
2026-09-02 07:03:02 |
| 129 |
Recovery obs |
 |
N |
1 |
1 |
2026-09-02 07:44:02 |
2026-09-03 05:51:30 |
| 130 |
Update status with platform number and date |


And date. |
N |
1 |
0 |
2026-09-02 09:22:06 |
2026-09-06 09:42:41 |
| 131 |
Location focus |
Input a town, a station, a postcode and see the nearby stations and the services that will be passing through there on the map and clickable to provide location focused detail..
This suddenly introduces the issue of scheduled -v- live and I think we would need to include scheduled in this. |
N |
1 |
0 |
2026-09-02 09:46:09 |
2026-09-02 09:46:42 |
| 132 |
Formation research |
Yes. My overall assessment is:
**A LINX consist record is a strong source for identifying the declared vehicles, their order, their grouping into units, and where that formation applies. It is not, by itself, a complete description of what those vehicles look like or necessarily proof of the train’s live physical state.**
That makes it excellent evidence for showing formation changes and reversals. It becomes much less certain when we try to turn its compact codes into passenger facilities, liveries or realistic vehicle shapes.
## What the record represents
A LINX `PassengerTrainConsistMessage` is hierarchical:
1. **Message and service identity**
2. **Allocation intervals** — where and when a formation applies
3. **Resource groups** — units, locomotives or complete sets
4. **Individual vehicles** — ordered within each resource group
GRM correctly treats each message as a complete snapshot for a UID, service date and signalling identity. The allocation intervals are source evidence, not train movements. GRM then derives a consist leg whenever the ordered equipment remains unchanged; unit membership, unit order or `Reversed` changing starts another leg. That design is documented in the [railway model](C:/Users/andy/OneDrive/projects/grm/docs/railway_model.md:52).
Network Rail describes LINX as the integration platform exchanging planning and operational information between traffic-management and other industry systems. It also explicitly says LINX has no material safety use. In other words, this is operationally useful declared information, but it should not be presented as safety-critical proof of what is physically coupled at that instant. [Network Rail’s LINX description](https://www.networkrail.co.uk/wp-content/uploads/2021/04/Catalogue-of-Railway-Code-Systems.pdf)
## Facts: what LINX directly gives us
### Message and train identity
The message supplies:
- A message identifier and message timestamp
- Sender and recipient identifiers
- Message type and version
- Message status
- Responsible railway undertaking
- Operational train number — normally the headcode
- The train’s `Core`, UID, timetable year, variant and start date
- Scheduled handover and transfer times
- Location identifiers using primary and subsidiary codes
- An `AllocationCompany`
These fields provide provenance: we can say which message asserted the formation, for which service and date, and when it was issued.
GRM currently shapes the most useful service identity fields, while some envelope and location metadata remains only in the retained XML.
### Where the formation applies
Each allocation contains:
- Allocation sequence number
- Origin location, time and mileage
- Destination location, time and mileage
- Resource group position
- Diagram date and diagram number
- `Reversed`, explicitly containing `Y` or `N`
This is one of LINX’s most valuable features. It does not merely say “unit 802207 works 5K03”; it can say that a particular ordered formation applies from one operational point to another and that another formation or orientation applies afterwards.
That is enough to show:
- Units joining or leaving the formation
- A change in unit order
- A stated reversal
- A train continuing with the same formation through several source intervals
- Different formations over different parts of the journey
It does **not** tell us that a physical reversal happened at the precise time implied by a TD event. LINX is separate evidence: it says that the resource is reversed for the applicable allocation interval.
### Resource groups
For every resource group LINX supplies:
- Resource group ID, such as `802207`
- Fleet ID, such as `802/2`
- Position within the train
- Number of vehicles
- Type of resource
- Resource group status
- End-of-day mileage
- Planned diagram
- Applicable origin and destination
- Reversal state
The current data contains three `TypeOfResource` values:
- `U` — overwhelmingly the normal unit resource
- `L` — separate traction/locomotive resources
- `S` — complete sets
GRM has encountered multiple `S` complete sets at the same resource position. These are treated as alternative complete allocations, not as several sets simultaneously coupled together. That conservative handling prevents the graphic inventing impossibly long trains.
The precise official expansion of the letters `U`, `L` and `S` still belongs in the LINX code dictionary, but their structural behaviour in the records is well established.
### Individual vehicles
Each vehicle can contain:
- `VehicleId`
- `ResourcePosition`
- `PlannedResourceGroup`
- `TypeOfVehicle`
- `SpecificType`
- Length and its measure
- Weight
- Livery
- Decor
- Special characteristics
- Number of seats
- Vehicle and registration status
- Number of cabs
- Date entered service
- Date registered
- Registered category
- Train brake type
- Maximum speed
- Additional publisher-specific attributes
The vehicle ID and resource position are the most immediately useful fields. They let us draw:
```text
831207 – 832207 – 833207 – 834207 – 835207
```
and, when the applicable orientation changes:
```text
835207 – 834207 – 833207 – 832207 – 831207
```
That is an honest, easily understood demonstration of reversal. It is considerably stronger than showing the unit number twice with an arrow.
`TypeOfVehicle=C` is used for passenger carriages, including powered DMU and EMU vehicles. It therefore does **not** mean “unpowered coach”. `L` is used for separate traction vehicles. The `SpecificType` must not currently be treated as a reliable propulsion or body-style description.
### Extra attributes
LINX vehicles can carry fields outside the presently classified list. The current data includes:
- `CoachLetter`
- `VehicleName`
- `DateRegistrationExpires`
- `ElectricTrainHeating`
- `FuelCapacity`
- `NextAvailableDateTime`
- `ExamPlanningIndicator`
- `Control`
These are real source fields, but provision varies sharply. `CoachLetter`, for example, is useful and passenger-friendly, but appeared on only about 7.8% of today’s vehicle records. It should therefore be supplementary, never required for understanding the graphic.
## How complete is the data?
I measured the shaped live data for 2 September 2026:
- 26,316 service formation snapshots
- 33,716 declared resource groups
- 142,264 effective vehicles
- 7,327 multi-unit snapshots — about 28%
- 3,309 snapshots with an en-route formation change — about 12.6%
There are 143,215 stored vehicle rows. The excess over the effective vehicle count is consistent with LINX supplying alternative complete `S` sets that GRM retains as evidence without pretending they are all part of the train.
For those vehicle rows:
| Field | Populated |
|---|---:|
| Vehicle ID and position | 100% |
| Specific type | 100% |
| Length and measure | 100% |
| Weight | 100% |
| Livery | 100% |
| Decor | 99.8% |
| Planned resource group | 99.1% |
| Number of seats | 99.2% |
| Vehicle status | 95.9% |
| Cab count | 57.5% |
| Special characteristics | 44.1% |
| Other attributes | 12.1% |
The important lesson is that **population does not imply comprehension**. We have almost universal `SpecificType`, livery, weight and speed values, but without their authoritative definitions some remain well-populated opaque codes.
## What the codes appear to offer
### `SpecialCharacteristics`
Examples include:
- `G`
- `W`
- `Y`
- `ID`
- `WID`
- `GQ9`
- `DGKW`
- `DQW9`
These look like concatenations of atomic characteristic codes. The combinations strongly suggest that a vehicle may carry several independently meaningful properties.
What we do not possess is the authoritative mapping. It would be tempting to guess that particular letters mean wheelchair space, first class, catering, toilets or cycle accommodation. That would be unsafe product design: a plausible guess could generate a very convincing but false graphic.
For now, the compact code is a fact; its passenger meaning is unknown.
### `SpecificType`
Examples look structured:
- `DC2100A`
- `DD2210A`
- `DD2300A`
- `EA2680A`
- `ER2220A`
Within a fleet they clearly distinguish vehicle variants. They may encode driving vehicles, intermediate vehicles, equipment or accommodation layouts. But I have not found a public authoritative LINX v095 definition that lets us decode the grammar reliably.
This field could eventually be the key to less generic vehicle shapes, but it is not yet a safe drawing instruction.
### Livery and decor
Examples such as `TP`, `GV`, `GT`, `SN`, `VW` and `ZZ` are consistently supplied. They potentially allow us to show broad livery distinctions.
Unknowns remain:
- Which organisation or scheme each code denotes
- Whether `ZZ` means unknown, plain, default or something else
- The distinction between `Livery` and `Decor`
- Whether the values describe current appearance or a registered/master-data appearance
- Whether colours and logos can safely be inferred from them
Until there is a source-backed dictionary, these should stay technical details rather than drive the train’s colour.
### Status and engineering codes
The records contain values such as:
- Resource/vehicle status: `N`, `X`, `T`, `D`
- Registered status: currently overwhelmingly `C`
- Registered category: `G`, `H`, `J`, `K`, `L`, `S`
- Brake type: principally `A` and `E`
These are probably meaningful to rolling-stock and control systems, but we should not manufacture expansions for them.
## Suggestions: what I think GRM should do
### In the main formation graphic
Use only facts that communicate instantly:
- Vehicle IDs under every vehicle
- Coach letters above vehicles where supplied
- Unit or set bracket and resource-group ID
- Clear ordered grouping for multi-unit trains
- The arrow showing the service’s applicable front
- Reversed vehicle order where LINX says the resource is reversed
- Vehicle lengths drawn approximately in proportion to the supplied length
- Visually distinct locomotives where `TypeOfVehicle=L`
This would let the graphic tell the story without explanatory wording.
### Make it less “toytown”
The supplied data can support a restrained railway-diagram style:
- Use accurate relative vehicle lengths
- Reduce or remove the row of decorative windows
- Show understated gangway/coupling gaps
- Use a modest cab-end taper only at credible driving ends
- Give locomotives a different mass and profile from passenger vehicles
- Keep the basic body neutral until liveries are decoded
- Treat facilities as small, standard symbols only after their codes are proven
One caveat: `Cabs=1` says the vehicle has one cab, but does not tell us which physical end contains it. We can often infer that from the vehicle being at the outer end of a stable unit, but that should remain a presentation inference, not a source fact.
### Add an optional technical view
An expandable details panel could expose the richer information without cluttering the diagram:
- Fleet and resource type
- Reported length, weight, seats and maximum speed
- Diagram number
- Registration and entry-into-service dates
- Raw livery, decor and characteristic codes
- Message timestamp and responsible RU
- A clear “reported by LINX” provenance label
That would be valuable to expert users while keeping the ordinary view comprehensible.
### Establish a proper LINX codebook
The most valuable next research task is obtaining:
1. `LINX XML v095.xsd`
2. The corresponding interface specification
3. Enumerated code lists
4. Business definitions for ordering and `Reversed`
5. Units and definitions for weight, speed and mileage
6. Publisher guidance for optional fields
The public ERA material establishes the wider TAF train-composition model, but LINX’s `PassengerTrainConsistMessage` and compact GB codes appear to be implementation-specific. The public [ERA technical-document collection](https://www.era.europa.eu/era-folder/technical-documents-baseline-222) does not supply the LINX v095 business dictionary.
I would store any mappings as a versioned, provenance-backed codebook. We should not bury guessed meanings in JavaScript or styling rules.
## Genuine unknowns
At present, I would explicitly mark these as unknown:
- The authoritative expansion of `SpecialCharacteristics`
- The grammar and exact meaning of `SpecificType`
- Livery and decor mappings
- Status and registered-category mappings
- The definitions and units of `Weight` and `MaximumSpeed`
- The precise orientation against which `Reversed=Y` is defined
- Which end of a one-cab vehicle contains its cab
- Whether `EndOfDayMiles` is actual, forecast or administrative mileage
- How quickly every operator updates substitutions
- Whether all publishers apply the optional fields consistently
- Whether vehicle details describe that day’s condition or relatively static master data
- Whether a reported formation was physically present, rather than allocated or expected
LINX also does not appear to give us:
- Door and window positions
- Vehicle width and height
- Bogie, pantograph or motor positions
- Coupler and gangway types
- Detailed seating plans
- Passenger loading or occupancy
- Definitive catering/accessibility descriptions without decoding the characteristic codes
- A live physical reversal event
- An explicit formed-from/forms relationship between services
## Bottom line
Vehicle numbers, resource grouping, order, applicability and `Reversed` are the gold in this record. They are strong enough to make the formation graphic genuinely informative and to show a reversal visually.
The characteristic, subtype and livery codes may contain another layer of excellent information, but today they belong in the **promising but unproven** column. I would improve the drawing first using the trustworthy structural facts, then treat decoding LINX v095 as a distinct research project rather than letting attractive guesses leak into the railway model.
This was an assessment only; I made no further code or behaviour changes. |
N |
1 |
0 |
2026-09-02 10:00:03 |
2026-09-02 10:00:03 |
| 133 |
Timing obs |
Train took off too earlyMaybe we should use tp values
Line max speeds
Equipment max speeds |
N |
1 |
0 |
2026-09-02 18:20:43 |
2026-09-02 18:20:43 |
| 134 |
Function |
# Train
### Statuses
### Equipment classes
### Equipment deep dives
### Diagrams
### Electric etc
### Show on maps for above
# Stations nearby
### Services in next while
### live and planned and passing
## Drill downs a gogo |
N |
1 |
0 |
2026-09-03 05:19:09 |
2026-09-03 05:29:50 |
| 136 |
New layout codex |
Please reorganise the initial geoRailMaps UI as a usability experiment.
The guiding principle is that the map should always remain the obvious underlying environment. We are moving away from the idea of an opening splash/popup panel that obscures or replaces the map. Even where overlays are required later, the map should remain visibly present in the background and may be blurred where appropriate rather than hidden.
## Initial state
Remove the current opening splash panel and its Close control.
On initial load, show the normal full-screen map, unblurred, with a centred navigation panel consisting of six large buttons arranged:
- 2 columns
- 3 rows
Do NOT show the existing action pill in this initial state.
The six-button area should occupy approximately:
- 80% of the available viewport width
- 50% of the available viewport height
but should have sensible desktop maximum dimensions of approximately:
- 600px wide
- 400px high
It should remain responsive on smaller/mobile screens.
## Button appearance
The buttons should visually belong to the existing geoRailMaps UI rather than introducing a new design language.
Use the existing Service Summary popup as the styling reference:
- same/similar translucent background colour
- same map/background blur treatment within each button
- same border colour
- same border thickness
- appropriate slight corner rounding
Leave a few pixels of spacing between the six buttons so that the live map is clearly visible through the gaps.
The outer four corner buttons should have appropriate rounded outer corners so the complete six-button arrangement feels like one composed control, while still visibly consisting of six individual buttons.
Do not create a large opaque container behind the buttons. The map should remain visible around and between them.
## Button identities
For implementation/discussion purposes I will refer to buttons using row/column notation:
11 = row 1, column 1
12 = row 1, column 2
21 = row 2, column 1
22 = row 2, column 2
31 = row 3, column 1
32 = row 3, column 2
Configure them as follows:
- Button 11: **Browse Map**
- Button 12: **Trains near me**
- Button 21: **Find a train**
- Button 22: **Train Details**
- Button 31: **Hot Spots**
- Button 32: **Help**
Unless behaviour is explicitly specified below, the buttons are placeholders for now and should not navigate anywhere.
## Browse Map — button 11
Selecting **Browse Map** should dismiss/remove the six-button navigation layer and expose the normal full-screen map experience as it exists today.
At that point:
- trains should be visible/operate normally
- the existing action pill should appear
- the map should otherwise behave as today's normal map
Do not redesign the action pill or normal map behaviour as part of this task. This is only a temporary path into the existing experience while we test the new opening navigation model.
## Help — button 32
Selecting **Help** should invoke exactly the same Help behaviour/content currently invoked from Help in the existing action pill.
Reuse the existing Help implementation rather than duplicating its behaviour.
When Help is dismissed, return to the six-button opening state rather than unnecessarily entering Browse Map mode.
## Other buttons
For now:
- Trains near me
- Find a train
- Train Details
- Hot Spots
should be visible and styled as real controls but do not need destinations or implemented functionality yet.
Avoid inventing temporary pages or behaviour for them.
## Behaviour/design intent
This is deliberately a usability/prototyping change rather than an attempt to resolve every navigation consequence in advance.
There will almost certainly be awkward or undefined transitions as more destinations are added. Do not over-engineer a navigation framework at this stage to anticipate all of them.
Prefer:
1. preserving the map as the persistent underlying environment
2. implementing this initial six-button state cleanly
3. reusing existing components/behaviour where possible
4. keeping the implementation straightforward and reversible
5. allowing us to discover navigation problems through use and address them from an experience point of view afterwards
Before changing code, inspect the existing opening splash, action pill, Service Summary styling and Help implementation so this work reuses the current UI conventions rather than recreating approximate copies.
Keep the change narrowly scoped to this initial navigation reorganisation. |
N |
1 |
1 |
2026-09-03 08:09:13 |
2026-09-06 09:41:57 |
| 137 |
Stock reverses |

This is a reverser, maybe we should say 'Carriages reverse' rather than repeat the consist. |
N |
1 |
1 |
2026-09-04 07:40:13 |
2026-09-07 07:17:08 |
| 138 |
Overloaded browser |

I had the # set to unlimited |
N |
1 |
1 |
2026-09-04 07:48:54 |
2026-09-07 07:17:04 |
| 139 |
Refine the lost service warning |

10:19
Not sure what to think here, turns out the corrour one was either a lazy or overworked signaller and evidence of liveness did not appear for nearly an hour many TPs later.
10:25
Worked for 12s
This is useful evidence that “lost by GRM” must not be presented as “train delayed.”
The train appears to have continued normally—Rannoch 08:45 to Fort William 09:55—but produced no intermediate reports across Corrour, Tulloch, Roy Bridge, Spean Bridge or Fort William Junction. That may reflect sparse/manual reporting rather than anyone doing anything wrong.
I’d now recommend:
- Keep the red uncertainty section and flashing train.
- Replace DELAYED with POSITION UNCONFIRMED.
- Describe emails as a “live tracking gap”, not a delayed or lost train.
- Include the timetable status separately: for example, “Last known on time; no new positional evidence for 23 minutes.”
- Keep the alert switch off by default while we observe how frequently legitimate reporting gaps occur.
- Avoid automatic social-media publication initially; the email should offer a candidate worth reviewing.
We could later derive expected “dark” sections from observed evidence patterns and suppress routine gaps there. I would collect incidents first rather than introduce manual geographical exceptions now. This case suggests the alert is still valuable, but as an alert about GRM’s confidence—not the railway’s performance.
10:25
Yeah, or if we go to social media then heavily quantify the message: Industry data suggests that this service may be delayed, are you on it? If so inform us here ...' And we will develop some guarrailed feedback mechanism valid only for that incident and for a timeperiod TBD.
10:27
Worked for 11s
Agreed—but I would quantify the absence of evidence rather than imply that delay evidence exists.
Suggested social copy:
Live industry data has not confirmed the progress of 1Y11 for more than 10 minutes beyond its expected timing point. The train may be delayed, or this may be a reporting gap. Are you travelling on it? You can tell us here: [incident link]
The feedback mechanism should be incident-scoped and remain separate from authoritative railway evidence:
- Available only through that incident’s unguessable link.
- Closes when the incident recovers or after a configurable period.
- Initially offers guarded responses such as “moving”, “stationary”, “arrived” and “not on this train”.
- No unrestricted text initially.
- Rate-limited and protected against automated submissions.
- Clearly labelled as passenger-supplied and never allowed to move the map train or change operational status automatically.
- Stored with the incident for later evaluation.
The existing 24-hour map-view expiry can remain separate from the shorter feedback window, which we can decide later. I’d also rename the email/page language from “lost service” to “live tracking gap”; that is more accurate for cases like Corrour. |
N |
1 |
1 |
2026-09-04 09:30:26 |
2026-09-06 09:41:43 |
| 140 |
The idea of a 2nd class service |
This is not railway, its 2nd class within the app, do something as long as reponse times are OK.
That is a sound concept, with one important separation: **authoritative operational status remains first-class; enhanced tracking assurance is second-class.**
In practical terms:
- Receiving and shaping railway messages must always win.
- Correct operational states such as `RUNNING`, `AT_PLATFORM` and `TERMINATED` must always win.
- Serving ordinary map and summary requests must remain responsive.
- Detecting unsupported projected positions, drawing the red section, flashing the train and sending alerts may use only spare capacity.
If optional assurance processing falls behind, the application should degrade honestly—not continue presenting an expired projection as though it were reliable. It could retain the last authoritative position and say something neutral such as “Position awaiting confirmation.” The richer red-section calculation and alert could follow when capacity permits.
### How achievable is it?
Quite achievable. I would call it a **moderate extension**, not a major new system, because we already have:
- central service-state interpretation;
- stored expiry times and an indexed way of finding due services;
- bounded priority and sweep processing;
- prepared operational evidence packages;
- selected-service resolution;
- the map’s expired-glide presentation;
- incident and email-alert machinery.
The substantial work is teaching the central interpreter about tracking assurance and making every consumer use that answer consistently.
### How I would protect performance
Within the existing status worker, give work explicit priority:
1. New railway evidence and core state changes.
2. Core clock events such as departures, arrivals and terminal handling.
3. Selected-service requests.
4. Tracking-assurance expiries.
5. Red-section enrichment and notification work.
Assurance processing would have:
- a small fixed batch allowance;
- no fleet-wide evidence rereading;
- no route geometry assembly unless the service is selected;
- back-off when the core backlog or response latency rises;
- a tunable switch allowing it to be suspended;
- measurements for queue age, processing time and database work.
The email is particularly easy to treat as optional: discovering and recording an incident can happen centrally, while email delivery waits or is skipped if the system is under pressure.
Before enabling it fully, I would establish an acceptance rule along these lines:
> Enable second-class assurance processing only when it causes no material deterioration in fleet and selected-service response times and does not increase the core status backlog.
We should set the actual thresholds after profiling. Given that the fleet response is already around 1.2–1.3 seconds, I would first improve or at least understand that path. Then deploy assurance behind a switch, observe it without customer presentation, and enable the visual behaviour only after confirming the cost.
So yes: **good concept, very achievable, and capable of being genuinely subordinate to the primary service—but degradation must remain honest rather than silently showing a known-expired position.** |
N |
1 |
1 |
2026-09-04 10:02:29 |
2026-09-07 07:16:58 |
| 141 |
Carriage drawngs |
 |
N |
1 |
1 |
2026-09-05 20:14:02 |
2026-09-06 09:41:33 |
| 142 |
Ui only update |
I would like to tackle some UI only issues.
Screenshot 1 is what I'll now refer to as the home screen.
Home Screen defined:

the Live Service Trace and the Live Status Trace and the the Full Schedule I'm going to refer to as the detail popups. I'm calling them popups because I'd like them to be made to be the front screen and all others to be in the background un-live and the forefront popup to be fully refreshed and live. When a popup is selected from the new menu described before it should come to the forefront or be launched and made live if not already there.
I'd like to make the current 4 button action pill 3 buttons, the options for button 2 when they are appropriate shown be thinner sub-buttons above the action pill, lets say a less tall sub action pill with the buttons light grey with black uppercase text and a very thin black border, and the screen content to accommodate the now 2 rows of buttons..
Screenshot 2 shows an example full screen display and I would like the Service Summary popup, the detail popups except the Full Schedule to use this full screen approach and use the same look and feel. No change to the look and feel of the Full Schedule. The X should change to a grey 'Back' button having the effect of closing that popup and returning to where it was when the popup was launched. The Journey Replayer should have an equivalent 'Close' button.
Replayer layout for reference to full screen layout and style:

I think that's it, I'd appreciate a sanity check then if OK going to code with and push and commit to main. |
N |
1 |
1 |
2026-09-06 08:48:15 |
2026-09-07 07:16:53 |
| 143 |
Q: what does this mean ffs 😂 |
Click a line for a decode
 |
N |
1 |
0 |
2026-09-06 12:37:41 |
2026-09-06 12:44:43 |
| 144 |
Build a 5s autosave |
Into ideas |
N |
1 |
0 |
2026-09-06 12:45:18 |
2026-09-06 12:45:18 |
| 145 |
Find a service |
I'd like to use button 22 for 'Find a live train service'.
Idea is the usual 2 step process of selection:
1) Select a station
a typeable dropdown list
the station needs to be a station for which live services have it as a remaining stopping point (so not timing points, just leg starts and ends and of course destinations). If that is too heavy select from a list of stations.
2) select a service, dropdown list sorted by time (at this station) and showing time and destination.
And be taken to the Service summary popup for that service as a result. |
N |
1 |
1 |
2026-09-06 18:14:29 |
2026-09-07 07:16:21 |
| 146 |
Arr dep out of order |
 |
N |
1 |
1 |
2026-09-06 20:58:45 |
2026-09-07 07:16:13 |
| 147 |
Menus rework |
I'd like to revisit the use of 'Action Pills', I prefer the layout of the top one to the bottom one in the screenshot.

So where I'd like to go is for a maximum of 3 rows stacked vertically and centrally, the bottom one being marginally taller and wider with slightly larger text than the 2 potentially stacked above it.
The bottom one is the currently set of 3 we have today, the next up (sub action pill) is the 3 choice options we get today when a Service Summary popup or its popups are in view, no change to the functionality of the buttons so far, just look.
the next one up (sub sub action pill) will, currently be toggles, so for the Live Service Status 3 4 toggles that currently sit in the settings menu should be moved to buttons in that row. If that makes the text difficult to accommodate then we can use symbols (maybe symbols in mobile, symbols and text in desktop), unfortunately I cant think of what symbols to use so any help would be appreciated. This may be used in other views too, I'm trying to get a standard for navigation for us to work with that is usable.
All ui components above the 1, 2 or 3 action pill rows should be perfectly sized to accommodate the whole thing.
if I've not been clear let me know, other wise lets move to a committed and pushed implementation. |
U |
1 |
0 |
2026-09-06 21:02:12 |
2026-09-07 09:15:59 |
| 148 |
Services per toc |
Show on map
A full gb map, a toc list with status below it, click the toc and show their live services on a map and focus in. Each service will link to the service summary popup.
Toc coverage map. |
N |
1 |
0 |
2026-09-07 06:45:17 |
2026-09-07 07:06:35 |
| 149 |
Services per station |
Full gb map
A full gb map, a station list below it, click the station and show live services that will use that station on a map and focus in.
Show each service a different strong colour.
Live departure board per station.
Station facilities.
Incidents affecting station services
So a map showing the services, the polylines clickable, where the polyline represents multiple services have a small, clickable numbered circle that brings a clickable table of services. |
N |
1 |
0 |
2026-09-07 06:52:45 |
2026-09-07 07:05:56 |
| 150 |
Mapped journey planner |
Take the nre real time journey planner and map its result showing journeys, changes and times etc. |
N |
1 |
0 |
2026-09-07 07:01:02 |
2026-09-07 07:01:02 |
| 151 |
NRE disruptions |
Show on map? |
N |
1 |
0 |
2026-09-07 07:02:11 |
2026-09-07 07:02:11 |
| 152 |
Table sprawl |
Review |
N |
1 |
0 |
2026-09-07 07:27:33 |
2026-09-07 07:27:33 |
| 153 |
Current info for dep estimates |
The current evidence falls into three groups: calculated departure clocks, direct evidence that departure happened, and contextual observations that might prove useful later.
| Fact or input | Origin | Intermediate leg boundary | Current role |
|---|---|---|---|
| Scheduled departure — WTT, with passenger time fallback | Baseline for Darwin; not sufficient alone to depart an origin | Baseline for the calculated departure clock | Used |
| Darwin `wet`, otherwise `et` | Produces a revisable departure clock | Latest estimate is now retained for the current/next stop | Origin used; intermediate observation-only |
| Direct TD/SMART departure | Confirms departure | Confirms departure | Used |
| Direct TRUST departure | Confirms departure | Confirms departure | Used |
| Direct TD/SMART arrival | Establishes arrival and calculates lateness | Establishes the train at the station | Used at intermediate stops |
| Direct TRUST arrival | Same | Same | Used at intermediate stops |
| SMART-derived TRTS | Indicates “Ready to Start” | Indicates “Ready to Start” | Context only; cannot depart |
| Platform allocation or berth occupation | Helps establish where the train is | Helps establish platform occupation | Context/platform authority, not departure timing |
| TRUST activation | Establishes that the service exists | Normally irrelevant after departure | Context only |
| Unresolved TD `CA` | Not accepted as departure | Not accepted as departure | Excluded |
| Darwin platform | Visible in Darwin trace evidence if unsuppressed | Same | Observation-only; not platform authority |
| TD platform movement / “Move forward” trace messages | May indicate preparation or repositioning | Same | Observation-only |
### Origin departure
The current operational candidate is:
```text
max(scheduled origin departure, Darwin wet/et)
+ configured departure offset
```
The offset currently defaults to 30 seconds.
Important details:
- There is deliberately no timetable-only origin departure. Without a usable Darwin estimate or direct departure evidence, GRM does not start the service merely because the booked time has passed.
- A newer Darwin estimate can move the clock later or replace it.
- `etUnknown`, `delayed`, or a Darwin actual departure `at` clears the operational Darwin forecast.
- Darwin’s `at` is visible in the newly retained trace evidence, but is not currently accepted as operational proof of departure. GRM still waits for direct TD/SMART or TRUST movement evidence.
- Direct TD/SMART or TRUST departure takes precedence as evidence that the train really moved.
- TRTS and origin berth occupation can establish `At Platform` or `Ready to Start`, but cannot open the first leg.
- An unresolved `CA` cannot start the service. It only qualifies if SMART resolves it to a direct `DEP` event at the origin schedule stage.
### Intermediate departure
Once direct TD/SMART or TRUST evidence establishes arrival, GRM can calculate:
```text
scheduled departure
+ 30-second departure offset
+ max(0, actual arrival − scheduled arrival)
```
This calculated departure is only allowed when arrival lateness is strictly less than the configured threshold, currently 120 seconds. Therefore:
- early arrival contributes no negative delay;
- arrival 90 seconds late moves the departure candidate 90 seconds later;
- arrival exactly 120 seconds late disables the calculated clock;
- the departure candidate can never precede the actual arrival;
- direct TD/SMART or TRUST departure still confirms movement immediately when effective.
The latest Darwin departure update is now available for comparison at an intermediate stop:
- while running, the relevant Darwin fact is for the next stop;
- while at a platform, it is for the current stop;
- `wet` is preferred to `et`;
- `at`, `etUnknown`, `delayed`, estimate-clearing attributes and unsuppressed platform evidence are retained;
- revisions replace the previous value for that Darwin service/location;
- it is shown as a blue line in the TRUST/Darwin departure column at its received time.
It does not yet influence the intermediate departure clock or open the next leg.
### Other potentially useful evidence
TRTS, platform occupation/allocation, activation, TD platform movement and “Move forward” messages could eventually help qualify confidence—for example, distinguishing “forecast departure” from “apparently ready to depart.” At present they intentionally do not supply a departure time.
The selected-service summary also shows a passenger-facing “departing at” estimate based on scheduled passenger departure plus the latest non-negative TRUST timing variation. That is a presentation estimate, not the operational rule which changes the service from `AT_PLATFORM` to `RUNNING`.
Finally, a terminating destination has no departure to infer. An intermediate station is both the end of the incoming leg and the beginning of the outgoing leg, so its arrival facts and departure estimates meet at the same schedule stage. |
N |
1 |
0 |
2026-09-07 08:29:33 |
2026-09-07 08:29:33 |
| 154 |
GLIDE |
Depart->Glide->Arrive, every train journey is made of 1 or more of these patterns, or legs. Each leg has >=2 timing points.
We have arrive as good as it needs to be, depart and glide are what needs attention.
Depart was the subject of an earlier conversation regarding involving Darwin estimates with a touch of our pessimism was probably the way to go and we’ll do another analysis of that later in the day.
For glide I see the following:
Acceleration, after departing leg start, reach max speed, at some point implement a decreasing speed to arrive at leg end at the hard target of potentially varying arrive time.
For this phase we will set a fixed acceleration and a fixed max speed as tunable parameters with a medium term view to establishing equipment max speeds, that is rolling stock and line maximums.
We should now start to regard a journey as having >=0 intermediate timing points (to), this means that a leg can have >=1 tp->tp segments, and I see the intermediate tp as soft targets. What I mean by that is that they are not stops, instead they are target times that should be aimed for by adapting speed but softly transitioning into the next segment. Any variation in speed across the tp should be subject to acceleration/deceleration at the tunable parameter rate.
The deceleration phase is again difficult to think about, my gut is that if max speed is achieved then it should start when deceleration at the tunable acceleration parameter gives an on time arrival, and if arrival time changes during this then so be it, the train must arrive on time without teleporting.
In a situation where early arrival is inevitable then the mapped train should sit at the station while the service status is still ‘Running’.
In the situation where late arrival is inevitable then so be it for this phase, it’s the smooth glide that is important for this phase. We will create a tunable parameter to identify the minimum dwelling, even 10s, that the service will sit ‘At Platform’ before commencing the next leg, even if the established departure time has passed.
What I’d like to do is: preserve the current arrival calculation; revisit the departure timing with regard to Darwin as described; evaluate the theory for leg glide that I’ve proposed. |
N |
1 |
0 |
2026-09-07 18:03:12 |
2026-09-08 07:30:11 |
| 155 |
Trawling for GLIDE parameters |
The more I think about this I'm realising that we need t become more clever now, rather than test out using tunable parameters that work for one service but not for the other 99.99% is going to be more confusing than helpful. So, I think we need to start getting more serious, there is a bullet here that needs to be bitten.

The first screenshot is from RTT, they don't show this form for every service, but I'd be interested to find where they get this level of detail.

This screenshot is from open railway map (ORM) and clearly shows line speeds, and as we have already established ORM is an interpretation of OSM so the data is in our OSM trove. I think the most challenging aspect of this is that the speed topology may not match with our triplet or tp topologies, my thought is that when we build and update our route cache, we refer to line speeds and use them to arrive at an average maximum speed per triplet.
As far as the max speeds of the rolling stock I'm sure that this is in the LINX data, so can be established per class that we could tabulate. We must also bear in mind that when services run in multi (multiple sets to one train) each of the sets may have different maximums, class 170/4=100mph, 158/7=95mph for example, often used by Scotrail, so the train max would be 95.
I think I'd like to forget whare we are on the glide today and reinvent it, and start to plan for this more serious approach to service mapping. |
N |
1 |
0 |
2026-09-08 08:03:46 |
2026-09-08 08:18:29 |
| 156 |
Apple Developer Guide |
# iOS Delivery Guide
## Purpose
This is the beginner-oriented delivery guide for geoRailMaps. It assumes that
development builds have so far been installed by connecting one iPhone to a
Mac with USB and pressing Run in Xcode.
Apple uses several related systems:
- **Xcode** builds, signs, installs, tests, archives and uploads the app.
- The **Apple Developer website** manages membership, the development team,
app identifiers, signing assets and registered devices.
- **App Store Connect** manages the app record, uploaded builds, TestFlight,
screenshots, privacy answers, review and release.
- **TestFlight** is the iPhone application through which invited people install
beta builds uploaded to App Store Connect.
They use the same Apple Account, but they are not one application.
## What the current USB workflow probably is
Xcode calls a free account a **Personal Team**. It supports personal on-device
testing, but its App IDs, registered test devices and provisioning profiles
expire after seven days. The free account is limited to ten simultaneous App
IDs and three devices per platform. Consequently, a USB-installed development
app may periodically need to be rebuilt and installed again.
That is suitable for learning and immediate device checks. It cannot publish
geoRailMaps through TestFlight or the App Store.
Apple documents the current comparison in
[Choosing a Membership](https://developer.apple.com/support/compare-memberships/).
## What paid membership changes
The Apple Developer Program costs USD 99 per membership year, or the local
price Apple offers. It adds distribution signing, App Store Connect,
TestFlight, App Store distribution, advanced app capabilities and registered-
device distribution. It does not change the geoRailMaps source code, GRM
server or MapLibre architecture.
A paid team may register up to 100 iPhones per membership year. Xcode can
register an attached phone automatically when automatic signing is enabled.
Disabling a device during the membership year does not return its slot.
[Apple's device overview](https://developer.apple.com/help/account/devices/devices-overview)
has the current limits.
Paid membership does **not** automatically publish the app. It gives the
account access to the delivery machinery; the developer still chooses a stable
app identity, uploads an archive, supplies the required information and sends
the app for review.
## Decide the enrolment identity first
This decision affects the seller name customers see:
- An **individual or sole proprietor** enrolment lists applications under the
developer's personal legal name.
- An **organisation** enrolment lists them under the organisation's legal
entity name and normally requires a D-U-N-S Number.
If the desired public seller is **Geographic Railway Mapping**, establish
whether it is an eligible legal entity before enrolling as an organisation.
Do not choose an organisation merely because its trading name looks better;
Apple verifies the entity. Conversely, do not casually create the production
app under an individual identity if a company seller is important.
## Recommended beginner progression
### 1. Keep using USB while the native presentation develops
There is no need to make TestFlight the inner development loop. Continue to:
1. connect and unlock the iPhone;
2. open `ios/GRM.xcodeproj`;
3. choose `GRM-Test` and the named phone;
4. select the correct Team under **Signing & Capabilities**;
5. leave **Automatically manage signing** enabled;
6. press Command-R.
Automatic signing should remain the default. Certificates and provisioning
profiles are real, but a novice does not need to create them manually for this
project unless Xcode reports a specific problem that automatic signing cannot
resolve.
### 2. After membership is active, make one deliberate identity decision
Replace the provisional `net.avarcher.grm` bundle identifier with the final
reverse-domain identifier before creating the production App Store record. A
plausible example is `com.geographicrailwaymapping.georailmaps`, but the final
choice depends on the enrolled legal identity and must be agreed rather than
copied blindly.
The bundle identifier is the app's durable technical identity. Changing it
later normally creates a different app rather than an update to the installed
one.
### 3. Prove paid development signing over USB
Before attempting distribution, run `GRM-Test` on the existing phone using the
paid team. This separates ordinary code/signing problems from App Store
Connect problems. Xcode normally registers the attached device and updates the
development provisioning profile automatically.
### 4. Create the App Store Connect record
In App Store Connect create one iOS app using:
- the final name;
- the final bundle identifier;
- a unique SKU used only for your own records;
- the correct primary language.
Creating the record does not release anything publicly.
### 5. Upload the first TestFlight build
In Xcode:
1. select the `GRM-Production` scheme;
2. choose **Any iOS Device (arm64)** rather than the attached phone;
3. choose **Product → Archive**;
4. let the Organizer finish validating the archive;
5. choose **Distribute App → App Store Connect → Upload**;
6. leave automatic signing selected unless Xcode gives a concrete reason not
to do so.
After Apple processes the upload, select it under the TestFlight tab in App
Store Connect and complete any requested export-compliance and beta-test
information.
An internal tester must be an App Store Connect user with an eligible role.
External testers can be invited by email or public link, but the first external
build needs TestFlight beta review. Builds remain testable for up to 90 days.
Apple currently permits up to 100 internal and 10,000 external testers; see
[TestFlight](https://developer.apple.com/testflight/).
For one developer testing on one personal phone, internal TestFlight is not
necessarily easier than USB. Its value begins when the app should install
without Xcode, survive away from the Mac, or reach another tester.
### 6. Prepare App Store submission separately
App Store submission additionally needs at least:
- final icon and iPhone screenshots;
- description, subtitle, keywords and category;
- support and privacy-policy URLs;
- accurate App Privacy answers;
- age rating and export-compliance answers;
- review notes explaining that the live map is informational, how to select a
train, and how a reviewer can see useful behaviour;
- a working production service throughout review.
The native-first presentation materially helps with Apple's requirement that
an application offer more than a repackaged website, but approval is never
automatic. The current requirement is in
[App Review Guideline 4.2](https://developer.apple.com/app-store/review/guidelines/).
## The safest next actions
Tomorrow's account work need not include an App Store submission. The useful
checkpoint is:
1. decide individual versus organisation enrolment;
2. confirm the paid membership is active;
3. add that Apple Account to Xcode;
4. select the paid Team and automatic signing;
5. run the Test scheme over USB;
6. stop before choosing the final bundle identifier if the public seller name
remains unresolved.
That establishes the environment without making an irreversible public-release
decision. |
N |
1 |
0 |
2026-09-09 10:48:59 |
2026-09-09 10:49:18 |
| 157 |
IOS led dev |
Yes—an iPhone-led UI is a sensible direction for this app, provided we treat it as the reference experience rather than trying to share SwiftUI code with the web version.
The model I’d recommend is:
```text
Shared GRM backend and railway model
│
Shared API/behaviour contract
┌─────┴─────┐
│ │
SwiftUI iPhone HTML version
reference UI equivalent UI
│ │
└── hosted MapLibre/OSM map ──┘
```
SwiftUI would determine the journeys, terminology, screen states and interactions. We would then reproduce their meaning in HTML, adapting the layout for browsers instead of attempting a pixel-for-pixel copy.
That gives you the best chance of producing something that genuinely feels like an iPhone application: native navigation, sheets, lists, typography, accessibility, gestures, loading states and system integration. The OpenStreetMap/MapLibre map can remain the existing web implementation, hosted inside the native application with a deliberately small Swift-to-JavaScript bridge.
The cost is that there will be two UI implementations. They can drift unless we deliberately share:
- API response formats and behavioural rules
- wording and status meanings
- colours and other design tokens where practical
- test scenarios covering loading, success, empty and error states
I would therefore describe the strategy as “design once, implement twice”, with iPhone as the primary design and acceptance platform.
On the Mac question: **you need a Mac capable of running a supported version of macOS and Xcode, but Apple Silicon is not formally required for ordinary iPhone development.** Apple’s requirements specify supported macOS versions; the explicit Apple-Silicon-only restriction is currently for visionOS development. [Apple’s current Xcode requirements](https://developer.apple.com/xcode/system-requirements/)
Nevertheless, if you are acquiring a Mac for this project, I strongly recommend Apple Silicon. An older Intel Mac might technically work with a particular Xcode release but has a much shorter useful life, poorer simulator performance and a greater risk of being unable to run a future macOS/Xcode combination. A current or recent Apple Silicon Mac mini would be a perfectly credible development machine; you do not need a MacBook or a high-end model merely to build this app.
The paid Apple Developer subscription changes distribution more than development:
- Without it, your current USB workflow still works, but Personal Team signing expires after seven days and can require rebuilding and reinstalling.
- With the paid programme, you gain TestFlight, App Store distribution, App Store Connect and less restrictive signing. Membership is currently USD 99 per year or the local equivalent. [Apple’s membership comparison](https://developer.apple.com/support/compare-memberships/)
- It does **not** eliminate the need for Xcode and a Mac. Something must still compile and sign the Swift application.
- Xcode Cloud can eventually build and upload remotely, but initial setup still uses Xcode, and you still want a Mac for device debugging. It should be treated as later automation, not as a replacement for learning the basic Xcode workflow. [Xcode Cloud setup](https://developer.apple.com/xcode-cloud/get-started/)
- Builds can be uploaded using Xcode or Xcode Cloud and then distributed through TestFlight or submitted to the App Store. [Apple’s build-upload guidance](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds/)
For you as a novice, I’d use this progression:
1. Continue daily development over USB from Xcode—the fastest feedback loop.
2. Join the paid programme when you want installations that do not expire every seven days.
3. Introduce internal TestFlight builds at useful checkpoints.
4. Add Xcode Cloud only once the manual build and signing process makes sense.
5. Approach public App Store submission after the native application is stable.
You can continue developing the backend and much of the source on Windows, but the final native build, simulator work, signing and proper iPhone debugging need Xcode on a Mac. I would also clone the Git repository separately onto the Mac rather than trying to share one live Xcode working directory through OneDrive.
The important distinction is: the subscription makes **delivery** markedly easier; SwiftUI makes **iPhone UI changes** cleaner and more native; the Mac and Xcode remain the workshop where those native changes are built and tested. |
N |
1 |
0 |
2026-09-09 10:50:14 |
2026-09-09 10:50:14 |
| 158 |
Macbook suggestions |
Yes. For your particular GRM work, the cheapest new MacBook that can genuinely run Xcode is now the **MacBook Neo at £599**.
### Current UK options
| Option | Indicative price | Will it run Xcode/iOS 18? | My view |
|---|---:|---|---|
| Refurbished 2020 M1 MacBook Air, 8GB/256GB | About **£389** | Yes | Absolute cheapest workable option |
| New MacBook Neo, 8GB/256GB | **£599** | Yes | Cheapest new option; workable but constrained |
| Refurbished M3 MacBook Air, 16GB/256GB | About **£700** | Yes, comfortably | Best-value target |
| New current MacBook Air | From **£1,099** | Yes, comfortably | Safest but unnecessary for this experiment |
The £599 MacBook Neo runs full macOS Tahoe, which supports current Xcode. Apple lists it with an A18 Pro processor, 8GB unified memory and 256GB storage. It is £499 if you legitimately qualify for Apple’s education pricing. [Apple’s MacBook Neo announcement and pricing](https://www.apple.com/uk/newsroom/2026/03/say-hello-to-macbook-neo/)
Current Xcode versions can deploy to iOS 18, and App Store Connect presently requires iOS applications to be built with Xcode 16 or later. [Xcode compatibility table](https://developer.apple.com/xcode/system-requirements/) [App Store build requirements](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds/)
### Would the £599 MacBook Neo be enough for GRM?
Yes—with qualifications.
Your intended workload is unusually favourable to it:
- The backend remains elsewhere.
- MapLibre and OpenStreetMap remain inside the web map.
- You will test primarily on your real iPhone over USB.
- The native project is a relatively compact SwiftUI application.
- You are not proposing video production, 3D development or a large local database.
The constraint is its non-upgradeable 8GB memory. Xcode itself will run, but Xcode plus its SwiftUI preview canvas, an iPhone Simulator, a browser and other development tools can push it into slower disk-backed memory. Independent testing found that the Neo could compile a large Xcode benchmark, but took 6 minutes 47 seconds—substantially longer than more expensive Macs. [Tom’s Hardware Xcode test](https://www.tomshardware.com/laptops/macbooks/apple-macbook-neo-a18-pro-review)
Using your physical iPhone instead of leaving the Simulator open will help considerably. However, SwiftUI previews are particularly useful for a novice learning and adjusting screens, so the limited memory could make the development experience more frustrating even though it remains technically possible.
### The absolute lowest-cost route
A refurbished **M1 MacBook Air with 8GB/256GB** is currently appearing from approximately **£389** with a 12-month seller warranty. The 2020 M1 Air is still officially supported by macOS Tahoe, so it can run a current compatible Xcode release and build for an iOS 18 phone. [Current refurbished price example](https://www.backmarket.co.uk/en-gb/p/macbook-air-m1-series) [Apple’s Tahoe compatibility list](https://support.apple.com/en-gb/122867)
I would accept one as an inexpensive experiment, but not regard it as a long-term development purchase because:
- it is already a six-year-old model;
- most inexpensive examples have only 8GB memory;
- battery condition varies;
- its remaining macOS/Xcode support life is less certain.
Avoid Intel MacBooks, regardless of how inexpensive they look.
### What I would buy
My preferred value point would be a **refurbished M2, M3 or M4 MacBook Air with 16GB memory**, ideally with at least 256GB storage. I found a current M3 16GB/256GB refurbished example at about **£700**, although that is a market listing rather than an Apple-certified recommendation. [Current M3 price example](https://www.calatech.co.uk/products/apple-macbook-air-m3)
That extra approximately £100 over the new Neo buys the important improvement: **16GB memory**. For Xcode, simulators and SwiftUI previews, that matters more than moving between nearby M-series processor generations.
My conclusion:
- **Cheapest possible:** refurbished M1 Air 8GB/256GB, around £389.
- **Cheapest new:** MacBook Neo 8GB/256GB, £599.
- **What I recommend:** refurbished M-series MacBook Air with 16GB, around £700–£850.
- **Maximum sensible specification for GRM:** 16GB memory and 512GB storage if the price difference is modest; you do not need a MacBook Pro.
The Neo would do the job, especially with your USB testing approach. But if iPhone-led development becomes the main GRM UI workflow, I think paying roughly £100–£250 more for a 16GB Air would be money well spent. |
N |
1 |
0 |
2026-09-09 12:04:13 |
2026-09-09 12:04:13 |
| 159 |
4 speeds |

1 line
2 train
3 calculated
4 gps |
N |
1 |
0 |
2026-09-09 13:55:53 |
2026-09-09 13:56:38 |
| 160 |
9/9 obs |
Accel too slow
some line speeds suspect slow
Late off station
Add follow train and show stats tick boxes
Make stats a fixed box as it’s only the one service
In find station services full schedule blow up show dep with green line around for clarity
Add a speed change indicator at changes, show each on either start of the change offset slightly into their track part. |
N |
1 |
1 |
2026-09-09 13:59:43 |
2026-09-11 15:59:53 |
| 161 |
Vtsp data |
Why are so few usable
 |
N |
1 |
1 |
2026-09-09 16:23:03 |
2026-09-11 15:59:46 |
| 162 |
Reorient the map |
Either prevent map rotation or provide a reorientation method |
N |
1 |
0 |
2026-09-10 06:19:04 |
2026-09-10 06:19:43 |
| 163 |
Train in field 😄 |


 |
N |
1 |
1 |
2026-09-11 06:26:11 |
2026-09-11 15:59:35 |
| 164 |
Mac info |

 |
N |
1 |
1 |
2026-09-11 09:04:36 |
2026-09-11 15:59:37 |
| 165 |
Td interprets out of order |

 |
N |
1 |
0 |
2026-09-11 15:56:28 |
2026-09-11 15:58:21 |
| 166 |
Zig zag |
 |
N |
1 |
0 |
2026-09-11 15:59:23 |
2026-09-11 15:59:23 |
| 167 |
Glide and route observations 11+12/9/26 |
Some early observations, browser based not on train, and certainly not extensive:

So the line speed is 100, equipment 100, hopelessly late (snapshot was about 17:14:30) yet it persists at about 60mph, then at Haymarket it teleports. However, this is not the case for all services, some behave perfectly.
----------

It’s not following the route?
---------
Despite the map showing arrival at a station, the status seems to wait until a TD/TRUST catch up?
---------
If, for example TD changes the arrival; time, it often takes ages for the speed calculation to adapt.
----------

Massive turnback at Clapham (North Yorkshire) back to Settle Junction and with speed constraints the service never catches up from that point forward. Surely catching these should be quite easy?
----------
For no obvious reason the train often slows up approaching soft timing points, even if there is actual evidence regarding timing shows as having passed already and causes it often to hit the timing point late then speeds up on passing it.
I only want understanding, and not deep technical explanations, and any solution must not add too much complication to a process that is already showing signs of being over complex. |
N |
1 |
0 |
2026-09-11 16:14:28 |
2026-09-12 09:00:05 |
| 168 |
Gating review |
Assuming non-gated to be the default, what is currently gated to:
Demo
Test
Subscription |
N |
1 |
0 |
2026-09-12 09:43:24 |
2026-09-12 09:44:23 |