Requirements
The app MUST speak the published web API contract and MUST NOT implement a second API client of its own (ADR-0013).
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Api/PinnedClients.phptests/Arch/NothingOpensAConnectionByHandTest.php
- cited by
- lemonfiber-companion@0727a005e7lemonfiber-companion@d63dfcaf83lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@86f1156a67lemonfiber-companion@b128bba134
Every action available from another surface MUST be offered by the app, except where a requirement here states otherwise and why.
- locked by
- 1.0.0 unmarked
- recorded open
- lemonfiber-companion
- cited by
- lemonfiber-companion@168bfe915blemonfiber-companion@0016d82fdalemonfiber-companion@c0edabaaa9lemonfiber-companion@73ccf58534lemonfiber-companion@39dcf21b8elemonfiber-companion@1d05b1fae5lemonfiber-companion@f79b2d58dclemonfiber-companion@85f3ef6539lemonfiber-companion@700a027e16lemonfiber-companion@032c04f9f5lemonfiber-companion@cde0e97086lemonfiber-companion@734b5be4e8lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@2c7d3b4304lemonfiber-companion@9ba89cd858lemonfiber-companion@1c7d31be3flemonfiber-companion@504d688335lemonfiber-companion@56b22208f8lemonfiber-companion@1935b2d4eflemonfiber-companion@a69d367350lemonfiber-companion@aaddc35d64lemonfiber-companion@c32a7fc706lemonfiber-companion@73bbe5aab3lemonfiber-companion@ba58df6e3clemonfiber-companion@e2c8b47b40lemonfiber-companion@e3153a3a7elemonfiber-companion@8c3236d6a3lemonfiber-companion@2d6aad5e3flemonfiber-companion@2e0eea33c3lemonfiber-companion@9bfe3e23dflemonfiber-companion@5a286ac227lemonfiber-companion@ebf258b1cclemonfiber-companion@f4200a19f1lemonfiber-companion@ec90b99812lemonfiber-companion@acac2246bclemonfiber-companion@de4ed2afd7lemonfiber-companion@9f865bf626lemonfiber-companion@70b3f11f25lemonfiber-companion@21308d4695lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@0b95bed87alemonfiber-companion@0857597273lemonfiber-companion@1f6c22909alemonfiber-companion@62a3648e95
The app MUST NOT hide or remove an action because the stack is currently unreachable; it MUST offer the action and report the reachability failure.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Availability.phptests/Templates/AnObstacleNeverTakesTheActionAwayTest.phptests/Feature/EveryScreenIsWalkableWithNoStackRunningTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@504d688335lemonfiber-companion@1935b2d4eflemonfiber-companion@66ed7ac132lemonfiber-companion@c32a7fc706lemonfiber-companion@e3153a3a7elemonfiber-companion@3f1f96026flemonfiber-companion@4bce0fe122lemonfiber-companion@3886666859lemonfiber-companion@d6fa38221alemonfiber-companion@7f19b2821dlemonfiber-companion@0727a005e7lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@ef7d16cc43lemonfiber-companion@40403b8ccflemonfiber-companion@8136512700lemonfiber-companion@de822caa91
The app MUST NOT offer first-run setup, and MUST state that setup is performed at the machine and why, rather than omitting it silently.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/View/Components/FirstRun.phptests/Arch/TheAppOpensOnlyTheseDoorsTest.phptests/Feature/TheFirstRunIsASequenceTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@8c3236d6a3lemonfiber-companion@2e0eea33c3lemonfiber-companion@5a286ac227lemonfiber-companion@0727a005e7lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@ef7d16cc43lemonfiber-companion@8136512700lemonfiber-companion@de822caa91
The app MUST offer reconfiguration in full once connected.
- locked by
- 1.0.0 unmarked
- recorded open
- lemonfiber-companion
- cited by
- lemonfiber-companion@5a286ac227lemonfiber-companion@1f6c22909a
Pairing MUST be possible by scanning a code, and MUST remain possible by typed entry where no camera is available or permission is declined.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/Internal/Screens/PairByScanning.phpapp-modules/operator/src/Internal/Screens/PairByTyping.phptests/Feature/PairingAStackByScanningTest.phptests/Feature/PairingAStackByTypingTest.php
- cited by
- lemonfiber-companion@ba8fa2d030lemonfiber-companion@bcfe1155a7lemonfiber-companion@1dc5379811lemonfiber-companion@86de113f69lemonfiber-companion@1003650c21lemonfiber-companion@9f865bf626lemonfiber-companion@2ee8db01dflemonfiber-companion@bd4b85bca8
The credential MUST be exchanged for a session once, and MUST NOT be retained for re-sending on subsequent requests.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Api/Admissions.phpapp-modules/kernel/tests/Api/CredentialTest.phptests/Contract/AdmittingContractTest.php
- cited by
- sdk-php@bb56a4bf57sdk-php@cba670f918sdk-php@8ea6dbc35flemonfiber-companion@16a75aa071lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@149bd6a9a4lemonfiber-companion@a1c1592309lemonfiber-companion@1c14731f1flemonfiber-companion@6fb444889dlemonfiber-companion@a1d8ff0c63lemonfiber-companion@7812809d5c
The session MUST be carried in the credential header the API defines, and MUST NOT be placed in a URL or a query parameter.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Session.phpapp-modules/sdk/src/Api/PinnedClients.phpapp-modules/kernel/tests/Api/SessionTest.phptests/Arch/NothingOpensAConnectionByHandTest.php
- cited by
- sdk-php@8ea6dbc35flemonfiber-companion@1c14731f1flemonfiber-companion@2e6395f29alemonfiber-companion@6fb444889dlemonfiber-companion@a1d8ff0c63
Any value shown that was not read in the current session MUST be marked with when it was read, and MUST NOT be presented indistinguishably from a live reading.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/HowLongAgo.phptests/Feature/AReadingCarriesItsAgeTest.php
- cited by
- lemonfiber-companion@266bdab236lemonfiber-companion@e1a5b70ea9lemonfiber-companion@78dd109fddlemonfiber-companion@504d688335lemonfiber-companion@a1c1592309lemonfiber-companion@e69ad24656lemonfiber-companion@1c14731f1flemonfiber-companion@2e6395f29alemonfiber-companion@402d7a7bd1lemonfiber-companion@80027dde9flemonfiber-companion@f2b8657c0d
A stack that cannot be reached, one that refuses the credential, and a device with no network MUST be reported as three different things, each with its own remedy.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Obstacle.phpapp-modules/sdk/src/Api/ClientsThatAskTheDevice.phptests/Feature/EveryObstacleSaysSomethingOfItsOwnTest.phpapp-modules/kernel/tests/Api/ObstacleTest.php
- cited by
- sdk-php@8958a36f19sdk-php@8e4301f942lemonfiber-companion@da105d58a3lemonfiber-companion@258f6fd1b9lemonfiber-companion@85f3ef6539lemonfiber-companion@12f59a7910lemonfiber-companion@fe348cf490lemonfiber-companion@032c04f9f5lemonfiber-companion@8bc885d481lemonfiber-companion@cde0e97086lemonfiber-companion@93ebd1b1c3lemonfiber-companion@06d312150blemonfiber-companion@d1cea6df66lemonfiber-companion@8c0e695e15lemonfiber-companion@8492bed446lemonfiber-companion@e81e8ad1b1lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@504d688335lemonfiber-companion@56b22208f8lemonfiber-companion@1935b2d4eflemonfiber-companion@a69d367350lemonfiber-companion@66ed7ac132lemonfiber-companion@fb0ade9ba3lemonfiber-companion@47264d7464lemonfiber-companion@73bbe5aab3lemonfiber-companion@7f19b2821dlemonfiber-companion@b449273016lemonfiber-companion@e917037894lemonfiber-companion@149bd6a9a4lemonfiber-companion@cf2e9f08d4lemonfiber-companion@426580d6b8lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@ef7d16cc43lemonfiber-companion@40403b8ccflemonfiber-companion@8136512700lemonfiber-companion@625ae74917lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@c8e0ccf8calemonfiber-companion@2adfebfc16lemonfiber-companion@ea7fa11002lemonfiber-companion@a1c1592309lemonfiber-companion@08adddaf91
The app MUST support more than one configured stack, MUST keep each one's session separate, and MUST NOT attribute a reading from one stack to another.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/connection/src/Api/Introducing.phpapp-modules/kernel/tests/Api/ConfiguredTest.phptests/Contract/StacksContractTest.php
- cited by
- lemonfiber-companion@426580d6b8lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@2adfebfc16lemonfiber-companion@ea7fa11002lemonfiber-companion@a1c1592309lemonfiber-companion@b91264c6e1lemonfiber-companion@2ee8db01dflemonfiber-companion@2bd8f3077flemonfiber-companion@c76de39b40lemonfiber-companion@d4cf8c7e4clemonfiber-companion@4c8888b498
The app MUST state whether the connection it has is encrypted, and MUST NOT imply protection it does not have.
The app MUST refuse an envelope whose wire version it does not support, naming the version it received and the versions it reads.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/WireVersion.phpapp-modules/kernel/src/Api/EnvelopeIsNotRead.phpapp-modules/kernel/tests/Api/WireVersionTest.phpapp-modules/sdk/tests/Internal/WireTest.php
- cited by
- lemonfiber-companion@d1cea6df66lemonfiber-companion@6e16a8231elemonfiber-companion@6cc7923ebclemonfiber-companion@fb0ade9ba3lemonfiber-companion@c32a7fc706lemonfiber-companion@47264d7464lemonfiber-companion@73bbe5aab3lemonfiber-companion@ba58df6e3clemonfiber-companion@e3153a3a7elemonfiber-companion@4bce0fe122lemonfiber-companion@d6fa38221alemonfiber-companion@5a286ac227lemonfiber-companion@0727a005e7lemonfiber-companion@e9311c476dlemonfiber-companion@8136512700lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@a1c1592309lemonfiber-companion@1afcd2edbflemonfiber-companion@4d31c5e894lemonfiber-companion@b1d7b2353c
A change of transport — LAN today, an overlay under I1 later — MUST NOT require a change to how the app authenticates or to the contract it speaks.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Address.phpapp-modules/sdk/src/Api/PinnedClients.phpapp-modules/kernel/tests/Api/AddressTest.phpapp-modules/sdk/tests/Api/PinnedClientsTest.php
- cited by
- lemonfiber-companion@1c14731f1flemonfiber-companion@2e6395f29alemonfiber-companion@6fb444889dlemonfiber-companion@b1d7b2353c
The app MUST NOT log, transmit or include in a diagnostic report any credential, session token, or stack address.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Address.phpapp-modules/kernel/tests/Api/AddressTest.phptests/Templates/NothingSecretReachesAScreenTest.phptests/Arch/TheTriedAddressIsShownOnlyToTheOperatorTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@fe348cf490lemonfiber-companion@c44c294ab6lemonfiber-companion@8136512700lemonfiber-companion@b91264c6e1lemonfiber-companion@c76de39b40lemonfiber-companion@1c14731f1flemonfiber-companion@a1d8ff0c63lemonfiber-companion@bc0047724alemonfiber-companion@7812809d5clemonfiber-companion@342168cc95
Every call to the API MUST be made through the SDK. The app MUST NOT issue an HTTP request of its own, construct an API URL, or parse an envelope the SDK did not produce.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Api/Admissions.phpapp-modules/sdk/src/Api/Requests.phptests/Arch/NothingOpensAConnectionByHandTest.php
- cited by
- sdk-php@a8a933179dsdk-php@5b92996662sdk-php@2d2f380f25lemonfiber-companion@85f3ef6539lemonfiber-companion@fde303ddf7lemonfiber-companion@8a6bac1655lemonfiber-companion@e9311c476dlemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@8136512700lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@2adfebfc16lemonfiber-companion@ea7fa11002lemonfiber-companion@a1c1592309lemonfiber-companion@442c2354d3lemonfiber-companion@2bd8f3077flemonfiber-companion@c76de39b40lemonfiber-companion@a6d3de4813lemonfiber-companion@204c752f0flemonfiber-companion@3cf1c66a19lemonfiber-companion@290bb4d9c3lemonfiber-companion@756b1c780elemonfiber-companion@23d0ef3d00lemonfiber-companion@49d5922082
Where the SDK does not expose a capability the app requires, the app MUST NOT reach past it, re-implement the call, or approximate the answer from another endpoint. The gap MUST be raised against the SDK and the contract, and the dependent work MUST stop until it is closed.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/WhatTheCoreDecided.phptests/Arch/WhatTheContractDoesNotCarryTest.phptests/Arch/WhatTheContractCarriesThatNothingReadsTest.php
- cited by
- lemonfiber@150bca10c4sdk-php@a8a933179dlemonfiber-companion@da105d58a3lemonfiber-companion@f79b2d58dclemonfiber-companion@032c04f9f5lemonfiber-companion@cde0e97086lemonfiber-companion@8cdbc61f06lemonfiber-companion@734b5be4e8lemonfiber-companion@033f60c7c7lemonfiber-companion@de072c486dlemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@3823e57432lemonfiber-companion@1935b2d4eflemonfiber-companion@a69d367350lemonfiber-companion@c32a7fc706lemonfiber-companion@73bbe5aab3lemonfiber-companion@ba58df6e3clemonfiber-companion@cc08fe7c65lemonfiber-companion@8a6bac1655lemonfiber-companion@e2c8b47b40lemonfiber-companion@e3153a3a7elemonfiber-companion@faa9f4b139lemonfiber-companion@25c043f25blemonfiber-companion@328e73f19clemonfiber-companion@2d6aad5e3flemonfiber-companion@2e0eea33c3lemonfiber-companion@5a286ac227lemonfiber-companion@785de443e3lemonfiber-companion@ebf258b1cclemonfiber-companion@70b83039celemonfiber-companion@9e92ec8d8alemonfiber-companion@1003650c21lemonfiber-companion@87c78a4855lemonfiber-companion@3b394eb57dlemonfiber-companion@691151ca5clemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@c34cac6f42lemonfiber-companion@ef7d16cc43lemonfiber-companion@8136512700lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@c8e0ccf8calemonfiber-companion@2adfebfc16lemonfiber-companion@ea7fa11002lemonfiber-companion@86f1156a67
The pairing material MUST carry the fingerprint of the certificate the stack will present, expressed as SHA-256 over that certificate's DER encoding in lower-case hexadecimal, and the app MUST take it from that material rather than from the network (ADR-0018, ADR-0025). The digest of the certificate's public key MUST NOT be carried in its place: it is the same length and a different value, so nothing but this sentence distinguishes them.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Pairing.phpapp-modules/sdk/src/Api/PinnedClients.phpapp-modules/kernel/tests/Api/PairingTest.phpapp-modules/sdk/tests/Api/PinnedClientsTest.php
- cited by
- lemonfiber@59edb5b826sdk-php@c28b7ea88e
The app MUST pin the paired fingerprint against that stack and MUST validate every subsequent connection against it, whether or not the platform trust store would accept the certificate.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Api/PinnedClients.phpapp-modules/kernel/src/Api/Fingerprint.phpapp-modules/sdk/tests/Api/PinnedClientsTest.phptests/Feature/NothingReachesAStackUnpinnedTest.php
- cited by
- sdk-php@c28b7ea88elemonfiber-companion@825970cdb0lemonfiber-companion@ea7fa11002lemonfiber-companion@442c2354d3lemonfiber-companion@2bd8f3077flemonfiber-companion@96ed5fed9dlemonfiber-companion@13e24625a3lemonfiber-companion@65115ef6eclemonfiber-companion@aa9df9d899
A connection presenting a different certificate MUST be refused rather than warned about, MUST be reported as this machine not being the one the app was introduced to, and MUST offer re-pairing as the remedy.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/connection/src/Api/HowTheSignInWent.phpapp-modules/sdk/src/Api/PinnedDoors.phpapp-modules/kernel/tests/Api/RecognisedTest.phptests/Feature/NothingReachesAStackUnpinnedTest.php
- cited by
- lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@504d688335lemonfiber-companion@56b22208f8lemonfiber-companion@1935b2d4eflemonfiber-companion@6d60babf9dlemonfiber-companion@149bd6a9a4lemonfiber-companion@2bd8f3077flemonfiber-companion@96ed5fed9dlemonfiber-companion@13e24625a3lemonfiber-companion@65115ef6ec
Certificate verification MUST NOT be disabled in any build, under any flag or configuration value.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Api/PinnedClients.phptests/Arch/NothingTurnsVerificationOffTest.phptests/Arch/VerificationCannotBeTurnedOffTest.php
- cited by
- lemonfiber-companion@3375245c8dlemonfiber-companion@adafa039ddlemonfiber-companion@2f58f6bd93lemonfiber-companion@0093bc0196lemonfiber-companion@a6d3de4813lemonfiber-companion@204c752f0f
Pinning MUST be to the stack rather than to an address, so that reaching the same stack by another route does not re-open the question of its identity.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/connection/src/Api/Introducing.phpapp-modules/kernel/src/Api/Configured.phpapp-modules/kernel/tests/Api/ConfiguredTest.phptests/Contract/StacksContractTest.php
- cited by
- lemonfiber-companion@c76de39b40lemonfiber-companion@65115ef6eclemonfiber-companion@4c8888b498
A credential, a session token and pairing material MUST NOT be written to any cache, and MUST NOT survive beyond the storage N4 defines for them.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/APairingCode.phpapp-modules/kernel/src/Api/APairingLine.phpapp-modules/kernel/tests/Api/CredentialTest.phptests/Contract/SecureStorageContractTest.php
- cited by
- lemonfiber-companion@bb168bb7a0lemonfiber-companion@dd8149d498lemonfiber-companion@de822caa91lemonfiber-companion@7812809d5clemonfiber-companion@4c8888b498
A reading the app retained from an earlier session MAY be shown on opening, and MUST carry when it was read as N1-R9 requires; the confirmation of an action just performed MUST NOT be served from a retained value.
A screen that reads from a stack MUST publish its first frame before issuing the read, and that frame MUST be built from what the app already holds (ADR-0019).
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/Internal/HearsHowEachStackIs.phptests/Arch/ScreensDeclarePaintingTest.phptests/Feature/TheListSaysTheOneLineTest.php
- cited by
- lemonfiber-companion@78dd109fddlemonfiber-companion@7f19b2821dlemonfiber-companion@e0ee168570lemonfiber-companion@a6ba3b0c70lemonfiber-companion@c76de39b40
Every call the app makes MUST carry a bounded timeout short enough that a refused reach returns the screen to the operator, and the bound MUST NOT be raised to accommodate a slow stack.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Timeout.phpapp-modules/sdk/src/Internal/HowLongACallWaits.phpapp-modules/kernel/tests/Api/TimeoutTest.phpapp-modules/sdk/tests/Api/PinnedClientsTest.php
- cited by
- sdk-php@a10ac40108sdk-php@4dc1aa0cd1lemonfiber-companion@535103fca1lemonfiber-companion@adf94d9aeb
A screen whose content can change while it is open MUST refresh on a cadence the screen declares, where a test holds it, and MUST NOT rely on the operator leaving and returning to see a change. The cadence MUST NOT be shown to the operator; what shows whether a value is current is the age N1-R9 requires.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/HowOftenAScreenLooks.phptests/Arch/EveryCadenceIsDeclaredTest.phptests/Templates/EveryReadingCanBeAskedAgainTest.php
- cited by
- lemonfiber-companion@2027d8fe04lemonfiber-companion@b8f282551flemonfiber-companion@9356200302lemonfiber-companion@50bc1bf6eelemonfiber-companion@d060986364lemonfiber-companion@266bdab236lemonfiber-companion@e1a5b70ea9lemonfiber-companion@78dd109fddlemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@1c7d31be3flemonfiber-companion@504d688335lemonfiber-companion@56b22208f8lemonfiber-companion@1935b2d4eflemonfiber-companion@73bbe5aab3lemonfiber-companion@3d9cc1130flemonfiber-companion@9f865bf626lemonfiber-companion@40403b8ccflemonfiber-companion@8136512700lemonfiber-companion@de822caa91
An indeterminate progress indicator MUST be shown only where the app holds nothing to show, and MUST NOT replace a retained reading that could be shown with its age.
The app MUST establish, before offering an action, whether the connected stack supports it by reading the capability set the API declares (ARCH-R78), and MUST NOT determine this by attempting the action or by deriving it from a version number.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/KnowingWhatAStackOffers.phpapp-modules/sdk/src/Api/Assessors.phpapp-modules/sdk/tests/Api/AssessorsTest.phptests/Arch/NothingIsOfferedThatTheStackWasNotAskedAboutTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@7c8780775c
An action the connected stack is too old to offer MUST be reported as unavailable on that stack, naming what would provide it, and MUST NOT be hidden (N1-R3) or presented as a failure of the operator's request. A capability that is present but unconfigured, and one the credential may not use, MUST each be reported as themselves rather than as absence (ARCH-R79).
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/WhetherItIsOffered.phpapp-modules/operator/src/Internal/ViewModels/AnOffer.phpapp-modules/kernel/tests/Api/WhetherItIsOfferedTest.phpapp-modules/operator/tests/Internal/ViewModels/AnOfferTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@7c8780775c
Where two configured stacks differ in what they support, the app MUST NOT present the capabilities of one as the capabilities of another.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Capabilities.phpapp-modules/sdk/src/Internal/WhatEachStackOffers.phptests/Contract/KnowingWhatAStackOffersContractTest.phptests/Feature/AskingAStackWhatItOffersTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@7c8780775c
Anything the app retains between launches MUST carry the version of the shape it was written in.
On reading retained state written in an older shape, the app MUST either migrate it or discard it, and MUST NOT interpret it as though it were current.
Discarding retained state MUST NOT discard a pairing or its pinned fingerprint; where those cannot be carried forward, the app MUST say that re-pairing is required and why.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Stacks.phptests/Arch/APairingIsNotDiscardedTest.phptests/Feature/ClearingWhatThePhoneKeepsLeavesPairingsTest.php
- cited by
- lemonfiber-companion@d1e945797flemonfiber-companion@650e7740d5lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@de822caa91
On a launch with no stack configured, the app MUST first ask which of two people is holding it, somebody invited and somebody who runs a lemonfiber server, in words that name no part of the system; the second MUST be told that setup happens at the machine (N1-R4) and offered pairing, the first MUST be given the member's way in (N3-R26), and neither MUST be shown an empty operator surface.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/Internal/ViewModels/WhatTheLaunchWas.phpapp-modules/operator/src/Internal/Screens/YourStacks.phptests/Feature/TheFirstFrameIsOfferedTest.php
- cited by
- lemonfiber-companion@e22d29101blemonfiber-companion@c8e0ccf8calemonfiber-companion@b91264c6e1lemonfiber-companion@c76de39b40lemonfiber-companion@1f6c22909alemonfiber-companion@19566bcc93
On a launch with a stack configured, the app MUST reach a usable frame without waiting for a reading to complete.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/Internal/ViewModels/WhatTheLaunchWas.phptests/Feature/TheFirstFrameIsOfferedTest.php
- cited by
- lemonfiber-companion@f8b56b2cf9lemonfiber-companion@a77118c28flemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@62ed1b033flemonfiber-companion@b91264c6e1lemonfiber-companion@c76de39b40lemonfiber-companion@84354c25dblemonfiber-companion@b66c43e117lemonfiber-companion@a177650707lemonfiber-companion@f0c7a55607
A launch where the device has no network, where the stack cannot be reached, and where the app is locked MUST each be told apart, consistent with N1-R10 and the lock N4 defines.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Opening.phpapp-modules/operator/src/Internal/ViewModels/WhatTheLaunchWas.phptests/Contract/NetworkingContractTest.phptests/Feature/TheFirstFrameIsOfferedTest.php
- cited by
- lemonfiber-companion@40403b8ccflemonfiber-companion@7c8780775c
Returning to a previous screen MUST restore what the operator had done there, and MUST NOT re-read the stack solely to rebuild it.
Which stack a screen is showing MUST be carried explicitly by that screen, and MUST NOT be read from state shared across screens.
An action the app could not deliver MUST be refused rather than retained, and the refusal MUST name the stack and state that nothing was changed (ADR-0020).
The app MUST NOT retain an undelivered action, MUST NOT replay one on reconnecting, and MUST NOT present an action as pending.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Attempted.phpapp-modules/sdk/src/Api/Handles.phpapp-modules/kernel/tests/Api/AttemptedTest.phptests/Arch/AnActionIsNeverHeldTest.php
- cited by
- sdk-php@5b92996662lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@7df1851164lemonfiber-companion@676b808952lemonfiber-companion@c8e0ccf8calemonfiber-companion@2adfebfc16lemonfiber-companion@18535b4235lemonfiber-companion@4262ac1f4b
An idempotency key MUST accompany every action that changes a stack, and serves retry within a single attempt; it MUST NOT be used to replay an action across a reconnection.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/IdempotencyKey.phpapp-modules/kernel/tests/Api/IdempotencyKeyTest.phptests/Arch/EveryActionNamesItsAttemptTest.php
- cited by
- sdk-php@32195b743asdk-php@4dc1aa0cd1sdk-php@a8a933179dlemonfiber-companion@04cf30bca2lemonfiber-companion@7df1851164lemonfiber-companion@274e136438
A refused attempt MUST leave the action offered, consistent with N1-R3; the attempt failed, the capability did not become unavailable.
Where a session is rejected or has ended, the app MUST report it on the screen the operator is on, MUST offer to establish a new session there, and MUST restore that screen once one is established.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Admitting.phpapp-modules/kernel/tests/Api/InterruptedTest.phptests/Feature/SeeingHowCurrentAStackIsTest.php
- cited by
- lemonfiber-companion@93ebd1b1c3lemonfiber-companion@a55f4063a9lemonfiber-companion@73bbe5aab3lemonfiber-companion@e3153a3a7elemonfiber-companion@3f1f96026flemonfiber-companion@4bce0fe122lemonfiber-companion@3886666859lemonfiber-companion@d6fa38221alemonfiber-companion@5a286ac227lemonfiber-companion@cf2e9f08d4lemonfiber-companion@0727a005e7lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@ef7d16cc43lemonfiber-companion@8136512700lemonfiber-companion@625ae74917lemonfiber-companion@de822caa91lemonfiber-companion@4cc7a5304blemonfiber-companion@2adfebfc16lemonfiber-companion@ea7fa11002lemonfiber-companion@d785161885
The end of a session MUST NOT discard the pairing or its pinned fingerprint; a credential expiring is not the machine changing (ADR-0018).
A session that has ended MUST be reported differently from a credential that was refused, consistent with N1-R10.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Interrupted.phpapp-modules/connection/src/Api/HowTheSignInWent.phpapp-modules/kernel/tests/Api/InterruptedTest.phptests/Feature/SeeingHowCurrentAStackIsTest.php
- cited by
- lemonfiber-companion@a55f4063a9lemonfiber-companion@8ec163a4ealemonfiber-companion@80550703adlemonfiber-companion@56b22208f8lemonfiber-companion@1935b2d4eflemonfiber-companion@9678b63bc5lemonfiber-companion@4f42694f94lemonfiber-companion@bb85e6460elemonfiber-companion@8d40d48158lemonfiber-companion@aa5aaa07e4lemonfiber-companion@ef7d16cc43lemonfiber-companion@d785161885
The stack MUST be able to produce pairing material on demand, from a surface the operator has already been admitted to, and MUST NOT require the app to be reachable in order to produce it.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded partial
- lemonfiber-companionapp-modules/sdk/src/Api/Pairers.phpapp-modules/sdk/src/Api/PairingCodes.phptests/Contract/MakingPairingCodesContractTest.phptests/Feature/PairingAPhoneTest.php
- cited by
- lemonfiber@59edb5b826lemonfiber-web@7d72c5398dlemonfiber-web@089b41c204
Pairing material MUST carry the address the app should reach and the fingerprint of the certificate that address will present, and MUST NOT carry a credential.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Pairing.phpapp-modules/kernel/tests/Api/PairingTest.php
- cited by
- lemonfiber@a18e48f417lemonfiber@59edb5b826lemonfiber-web@7d72c5398d
Pairing material MUST expire, and redeeming it MUST NOT be what admits the app; admission remains the exchange of the operator's own credential for a session (N1-R7).
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Pairing.phpapp-modules/connection/src/Api/WhatTheCodeSaysSoFar.phpapp-modules/kernel/tests/Api/PairingTest.phptests/Feature/PairingAStackByScanningTest.php
- cited by
- lemonfiber@59edb5b826
Where pairing is completed by typed entry rather than by scanning (N1-R6), the app MUST present the fingerprint it observed in a form a person can compare against what the stack displays, and MUST NOT proceed on an unconfirmed fingerprint.
The comparable form MUST be short enough to be checked at a glance and MUST be derived from the whole fingerprint, so that two different certificates do not share one.
The application's identity MUST be declared once in the repository, MUST be the same for every build of a given release, and MUST NOT be derived from the environment of whoever built it.
A build whose configured identity differs from the declared one MUST be refused, naming the declared identity and the configured one.
A launch with no stack configured MUST present a sequence that says what the app is, that setup happens at the machine (N1-R4), and then offers pairing — rather than a single screen the operator is left to interpret.
Every step of that sequence MUST say which step it is and how many there are, and MUST be leavable, with leaving landing on pairing rather than on nothing.
The sequence MUST be shown only while the device holds no pairing, MUST NOT be re-enterable once one is held, and MUST NOT be offered as a setting.
It MUST be possible to reach and operate every screen of the app with no stack on the network, by standing in for the stack itself rather than for any part of the app.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/dx/src/Api/AStackThatIsNotThere.phptests/Feature/EveryScreenIsWalkableWithNoStackRunningTest.phptests/Feature/TheSuiteNeverRunsAgainstAStandInTest.php
- cited by
- lemonfiber-companion@d6fa38221alemonfiber-companion@bdd6048413lemonfiber-companion@1003650c21lemonfiber-companion@149bd6a9a4lemonfiber-companion@426580d6b8lemonfiber-companion@0727a005e7
A stand-in MUST sit below the transport the app's client uses, so that the client, the envelope reading and the wire-version check (N1-R13) exercised against it are the ones exercised against a real stack.
What a stand-in answers with MUST be derived from the published contract rather than written by hand, and a divergence between the two MUST fail a gate.
A stand-in MUST hold no credential, session or pairing material that could reach a real stack, and MUST NOT write any to the device's store.
A released build MUST NOT be able to run against a stand-in, and that MUST be structural rather than a setting the app reads.
Pairing material MUST carry an identifier for the stack that is the stack's own and is stable across re-issue of the material, a change of address, and a replacement of the certificate. It MUST NOT be derived from the address, from the fingerprint, or from any credential, and MUST NOT carry anything that identifies the household or an operator.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/Pairing.phpapp-modules/kernel/src/Api/StackId.phpapp-modules/connection/tests/Api/IntroducingTest.phpapp-modules/connection/tests/Api/WhatTheCodeSaysSoFarTest.php
- cited by
- lemonfiber@59edb5b826
The app MUST decide which machine pairing material refers to from that identifier alone, and MUST NOT infer it from the address or the fingerprint. Material carrying an identifier the device already holds MUST replace what is held for that stack — its address, its pinned fingerprint and its name — rather than add a second.
A re-pairing that changes the pinned fingerprint MUST discard the session held for that stack; a re-pairing that does not MUST keep it, consistent with N1-R45. A different certificate is a different key, and a session obtained under the old one is not carried across it.
A screen MUST perform at most one read of a stack per frame it publishes, however many values that frame goes on to read from what came back. A value read more than once MUST be answered from what the screen holds rather than by reaching the stack again.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/operator/src/Internal/ReadsAStackOnceAFrame.phptests/Arch/EveryCadenceIsDeclaredTest.phptests/Feature/SeeingWhichVersionsRunTest.php
- cited by
- lemonfiber-companion@85f3ef6539lemonfiber-companion@38175aaa1blemonfiber-companion@379d9ed055lemonfiber-companion@3d29801355lemonfiber-companion@033f60c7c7lemonfiber-companion@0954261cc2
Beyond that read, a screen MUST reach a stack only on the cadence it declares (N1-R27) or in answer to an act of the operator's. It MUST NOT reach one because a value was read, a key was pressed, or a screen was rebuilt (N1-R38).
A screen MAY hold a subscription to the stack's event stream in place of reading, and opening it MUST count as that screen's one read (N1-R65). Each value the stream delivers MUST be rendered from what the subscription holds, and MUST NOT be a reason to reach the stack again (ADR-0026).
A screen MUST publish its first frame before opening a subscription (N1-R25), and opening it MUST carry the bounded timeout every call carries (N1-R26). Once the subscription is open, that timeout MUST NOT bound how long it is held.
A screen MUST take what a subscription has delivered on a cadence it declares (N1-R27), and taking it MUST NOT wait for a value that has not arrived.
A subscription that has delivered nothing, neither a value nor the heartbeat, for twice the heartbeat interval the contract states (ARCH-R61) MUST be treated as broken. From then on its last value MUST be shown as stale with when it was read (N1-R9), and a summary it carried MUST read unknown rather than healthy.
A subscription that broke or could not be opened MUST be reopened on a cadence the screen declares (N1-R27), and MUST NOT be reopened more often than that. Nothing held from before the break MUST be presented as current until the reopened subscription delivers a value.
A subscription MUST be held only while a screen showing what it carries is in front of the operator. It MUST be closed when that screen is left, and at the screen's first wake after the app leaves the foreground; it MUST NOT be opened or read while the app is in the background.
The comparable form (N1-R50, N1-R51) MUST be derived the same way wherever it is shown: SHA-256 over the fingerprint written as its sixty-four lower-case hexadecimal characters; the first sixteen bytes of that digest, each taken modulo thirty-two as an index into the alphabet 23456789ABCDEFGHJKLMNPQRSTUVWXYZ; written as four groups of four joined by hyphens. The fingerprint of sixty-four 0 characters MUST give 22VK-KPHH-NKH9-TUWA, and that of sixty-four f characters Z9JL-Q3PK-BZ6M-HRQZ.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded done
- lemonfiber-companionapp-modules/kernel/src/Api/APairingCode.phpapp-modules/kernel/src/Api/AtAGlance.phpapp-modules/kernel/tests/Api/AtAGlanceTest.phptests/Feature/PairingAPhoneTest.php
- cited by
- lemonfiber@a18e48f417lemonfiber-web@3c8735af4alemonfiber-web@7d72c5398d
Wherever the stack displays pairing material, it MUST display the comparable form of the fingerprint that material carries (N1-R73), in its human-readable and its machine-readable output alike, so that typed entry has something to be compared against (N1-R50).
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded partial
- lemonfiber-companionapp-modules/operator/src/Internal/Screens/PairingAPhone.phptests/Feature/PairingAPhoneTest.php
- cited by
- lemonfiber@a18e48f417lemonfiber-web@3c8735af4alemonfiber-web@7d72c5398d
The app MUST read a refusal whose code says the request carried nothing the stack admits as a session that has ended (N1-R44, ARCH-R138), and MUST NOT read a refusal with any other code as one.
- locked by
- 0.18.0 met
- recorded done
- lemonfiber-companionapp-modules/sdk/src/Internal/WhatARefusalMeant.phpapp-modules/sdk/tests/Internal/WhatARefusalMeantTest.phptests/Contract/CataloguingContractTest.php
- cited by
- lemonfiber-companion@1dbd1d426dlemonfiber-companion@c8ec5d2465lemonfiber-companion@a55f4063a9
What the stack says beside pairing material MUST be in words every surface can show, and MUST NOT name a command of one surface; how the certificate is replaced (C6-R19) MUST be said by each surface in its own way.
- locked by
- 0.17.0 met
- recorded done
- lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
- recorded partial
- lemonfiber-companionapp-modules/sdk/src/Api/PairingCodes.phptests/Feature/PairingAPhoneTest.php
- cited by
- lemonfiber@75851ae04dlemonfiber@3c0f78582d
An answer the stack gave that this version of the app cannot read MUST be reported as neither a stack that did not answer nor a refused credential (N1-R10): the operator MUST be told the stack answered in a way this app cannot read, with updating the app or the stack as the remedy, and a member MUST be told the house cannot be reached right now.
A join link (D6-R22) MUST NOT be treated as pairing material: it MUST NOT admit an operator session or replace a pin, and the only credential it can lead to is the one member account it names.