Repository navigation
[obvious-fleet] fix(ios): reviewed substitution table as bundled app data — compiles in macOS CI - #154
Conversation
Adopt PR #114's reviewed substitution table (279 pairs) as bundled app data, mapped to app ingredient IDs without guessing: - scripts/substitutions/convert.py: pairs.json -> app-facing resource. Maps endpoints by exact name, alias, or fdc id only (no fuzzy match); ambiguous evidence fails closed; pairs with unmapped endpoints are dropped and counted in a mapping audit. Role fits carry per-role evidence verdicts (verified/plausible/unknown/unsupported; unknown is never upgraded); supported_also roles never inherit the primary ratio; conditional fails ride separately from functional fails. Recheck payloads carry the substitute's full compound allergen/diet closure and compositionKnown from the canonical facts store. 24 tests. - apps/ios/Resources/Substitutions/substitutions-v1.json: generated resource (35/279 pairs, 40/317 ingredients mapped, 244 dropped fail-closed) from overhaul/substitution-table at 4b58954. - apps/ios/FeatureLogic/Substitution/SubstitutionTable.swift: pure-logic lookup and per-eater composition screen (allowed / ask-user on unknown composition / refused with offending classes). - apps/ios/Platform/Persistence/Services/SubstitutionService.swift: loads the bundled table; hardcoded 24-pair map removed; existing API kept, screenedSubstitutions added for ask-user states. - apps/ios/Tools/substitution-check: portable check compiling the production logic against the generated resource (schema gate, audit counts, determinism, all-pairs x all-restrictions sweep, compound refusals, verdict honesty).
Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The framework target in project.yml is named FLFeatureLogic (product name FLFeatureLogic), so the app-target import must be 'import FLFeatureLogic'. The previous 'import FeatureLogic' does not resolve and failed build-and-test on macOS CI (run 38724597220) at head e6b8ec0. No behaviour change: same table, same screen outcomes. 🤖 Generated with [Obvious](https://obvious.ai) Co-Authored-By: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
|
Independent review (Obvious, Autobuild + Max) Verdict: Transparency note: workspace context says this PR was authored by this workspace's own fleet in an earlier burst. I treated the body as untrusted and re-derived every claim below live at head Findings (ranked by severity)1. Low — 2. Low — 3. Low — Things I checked and am satisfied by (not findings): the untested What I verified (commands and results)
What I couldn't verify
|
fleet-packet: burst6-fridgeluck-fix154-ci
Reviewed substitution table → bundled app data (+ macOS CI fix)
Draft PR #154, base
obv/burst5-fridgeluck-spec-lechef, head452a424onobv/burst5-fridgeluck-lechef-substitutions. Part of the LeChef overhaul burst 5. Adopts PR #114's reviewed substitution table (279 pairs, branchoverhaul/substitution-table) as bundled app data, mapped to app ingredient IDs without inventing identities, and wires the app'sSubstitutionServiceto consume it.1. What changed and why
The CI fix (this packet, commit
452a424):apps/ios/Platform/Persistence/Services/SubstitutionService.swiftline 2 imported a module that does not exist —import FeatureLogic. The framework target inproject.ymlisFLFeatureLogic(framework,PRODUCT_NAME: FLFeatureLogic), so the app-target import must beimport FLFeatureLogic, as every other app/framework-boundary file in the repo already does. The wrong import was the only error in the first CI run (run 38724597220, heade6b8ec0,SubstitutionService.swift:2:8: error: Unable to resolve module dependency: 'FeatureLogic'); CI stops at the first file that fails to compile, so nothing after it had been compiled. One line, no behaviour change, no other files touched.The slice itself (commits
f6cbc5c,e6b8ec0, carried forward unchanged):scripts/substitutions/convert.py+test_convert.py— pairs.json → app-facing resource converter.--strictexits 2 on any unmapped ingredient.verified/plausible/unknown/unsupported; conflict stays plausible-at-best; unknown is never upgraded). A functional fail on the only role drops the pair; on another role it lands inexcludedRoles. Aconditionalfail rides separately inconditionalForwithout degrading the swap's own verdict.supported_alsorole never inherits the primary ratio — a missing ratio row for it staysunknown.compositionKnownfrom the canonical facts store; a nullfacts_keyfails closed to ask-the-user even when the ingredient mapped.differencetext promising "no change" is rejected; every pair must cite a source; output is deterministic (keys sorted, verified by a byte-equality test).apps/ios/Resources/Substitutions/substitutions-v1.json— generated resource: 35/279 pairs shipped, 40/317 referenced ingredients mapped, 244 pairs dropped fail-closed, with the source commit (4b58954onoverhaul/substitution-table) recorded insource. A pinned copy ofpairs.jsonis committed underdata/substitutions/for reproducibility (seescripts/substitutions/README.mdfor the regeneration commands).apps/ios/FeatureLogic/Substitution/SubstitutionTable.swift— pure-logic lookup and per-eater composition screen in theFLFeatureLogicframework:allowed/askUser(unknown composition, only under active restrictions) /refused(offending:)naming the offending classes. Compound closures are included in the screen; unknown restriction IDs (keto,low_carb) screen nothing — the reviewed table defines no forbids for them. Public API only (no GRDB) so the app target consumes it across the module boundary.apps/ios/Platform/Persistence/Services/SubstitutionService.swift— loads the bundled table at init; the hardcoded 24-pair map is removed. Existing API (substitutions(for:dietaryRestrictions:),hasSubstitutions(for:),ingredient(id:)) is kept compatible; a newscreenedSubstitutions(for:dietaryRestrictions:)exposes ask-user states instead of silently dropping swaps. A missing or undecodable resource leaves the service empty (nothing wrong is ever offered), with an assertion failure in debug. The bundle lookup tries the bundle root first, then aSubstitutionssubdirectory, so either XcodeGen resource layout works.apps/ios/Tools/substitution-check/— portable check that compiles the productionSubstitutionTable.swiftagainst the generated resource.2. How I verified it
apps/ios/Tests):e6b8ec0, run 38724597220 —build-and-testfailed withSubstitutionService.swift:2:8: error: Unable to resolve module dependency: 'FeatureLogic'.452a424, run 38767497722 —build-and-testpass (4m45s),dead-code-advisorypass (2m50s). Both conclusions re-verified viagh run view ... --json headSha,conclusion.python3 -m pytest scripts/substitutions/ -q→ 24 passed (schema gate, mapping by name/alias/fdc, ambiguous-fdc fail-closed, no-fuzzy, pair-drop isolation, strict mode, verdict matrix, functional/conditional fails, supported-also ratio isolation, compound closure, diet classes, source/difference guards, determinism, restriction shipping). Run on head452a424even though the fix does not touch the table or converter.SWIFT_BIN=.../swiftc bash apps/ios/Tools/substitution-check/run.sh(Swift 6.1.2, Linux sandbox) → OK — 35 swaps, 40 mapped ingredients, sweep allowed=435 askUser=0 refused=20. The sweep runs every shipped swap × every table restriction and asserts a forbidden class never screens allowed, refusals name exactly the offending classes, unknown-composition swaps ask the user, and the compound cases hold (olive-oil→butter refused for vegans naming dairy; tofu substitutes refused for soy-free but allowed for gluten-free). Behaviour identical to pre-fix evidence — the one-line import fix did not change the slice.swiftc -parseonSubstitutionService.swift→ clean (syntax; type checking happens in macOS CI).SubstitutionServiceor the old hardcoded map (grep overapps/ios/Tests/), so the hardcoded-map removal breaks no encoded expectation; no test was changed.3. What is not verified
FLFeatureLogicframework were compiled only by hosted macOS CI.SubstitutionServicetype-checks only in CI (GRDB + the framework import); locally I could syntax-parse it and compile the pure framework file (SubstitutionTable.swift) viasubstitution-check. The app build, unit tests, and simulator run happened only on CI, and onlybuild-and-testresults are cited.SubstitutionSheet.swiftUI is untouched — it consumes the sameSubstitutionshape; surfacing ask-user rows in the sheet is a follow-up.substitution-check, not by running the app.4. Assumptions
packages/FLSubstitutions) is PR Overhaul: reviewed substitution table (data milestone 1) #114's deliverable, not this slice's; this PR consumes the generated JSON only, so the app does not take a dependency on that package in this PR.keto,low_carb) are treated as screen-nothing: the reviewed table defines no forbids for them, so they neither allow nor refuse a swap here.data/substitutions/pairs.jsonis a pinned snapshot of PR Overhaul: reviewed substitution table (data milestone 1) #114's table at4b58954; regeneration against a newer table requires updating the--source-commitaccordingly.build-and-test(which passed with no further errors) confirm it.Human author: Sam Gu (sgu07966@gmail.com)
🤖 Generated with Obvious
Co-Authored-By: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact