Skip to content

merge(dev→main): mobile mode-selector always shown at boot - #5

Merged
Rwanbt merged 1 commit into
mainfrom
dev
Jul 7, 2026
Merged

Rwanbt merged 1 commit into
mainfrom
dev

Conversation

@Rwanbt

@Rwanbt Rwanbt commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • The mobile app's onMount auto-connect (added in 8e92945) unconditionally called handleLocalConnect() on every cold start, skipping the Local/Remote mode-selector screen entirely unless a hidden dev-only localStorage flag was set.
  • A previously-configured remote (TLS) server was therefore never offered again after any launch — setDefaultServer() persisted it correctly, but getDefaultServer() was never read at boot.
  • Removed the auto-skip block. ExtractionProgress already runs its own checkRuntime()/installExtendedEnv() when the user picks Local from the selector, so this is a pure removal with no loss of behavior for fresh installs.

Verification

  • bun run typecheck — 15/15 packages pass.
  • Built + signed + installed the APK on a real device (Xiaomi 14 Ultra); confirmed via screenshot that the mode selector ("Local Mode" / "Remote Server") renders on cold start.
  • CI on dev (commit f0b3eb7): typecheck, test, generate, nix-eval, deploy, CodeQL, Build Android APK all green.

Test plan

  • typecheck
  • CI green on dev
  • Manual device verification (screenshot)

The onMount auto-connect added in 8e92945 unconditionally called
handleLocalConnect() on every cold start unless a hidden dev-only
localStorage flag was set, skipping ModeSelector entirely. This meant
a previously-configured remote (TLS) server was never offered again
after any local-mode launch, even though setDefaultServer() persisted
it correctly — getDefaultServer() is never read at boot.

The block was also redundant: ExtractionProgress already runs its own
checkRuntime()/installExtendedEnv() when the user picks Local from the
selector, so removing the auto-skip restores the full manual flow with
no loss of behavior for fresh installs.
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Hey! Your PR title merge(dev→main): mobile mode-selector always shown at boot doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@Rwanbt
Rwanbt merged commit ec74245 into main Jul 7, 2026
32 of 34 checks passed
Rwanbt pushed a commit that referenced this pull request Sep 4, 2026
… error classification + generic evidencePath validation

This commit closes the P0 integrity gaps from the latest
mandate. Source-only; the next commit re-runs the
qualification and publishes the matching evidence.

P0 #1 — durable AttemptId allocator (mandate §3-§7)
  - The DBOS binary now persists a per-(runId, liId)
    sequence in the `attempt_sequence` table that lives
    in the DBOS SQLite system database.
  - The new POST /attempts/next endpoint atomically
    reads+increments the sequence via a SQLite UPSERT
    transaction and returns the canonical external
    AttemptId `att:<runId>:<liId>:<seq>`.
  - The harness adapter calls this endpoint to obtain a
    durable AttemptId for every driveAttempt invocation.
  - Two consecutive calls return two DISTINCT AttemptIds
    with monotonic sequences; a process restart resumes
    from the durable state (no in-process counter, no
    reuse); concurrent calls are serialized by SQLite.
  - The OLD `att-${Date.now()}-${randomUUID}` adapter-
    side generation is removed.

P0 #2 — single RunId generation authority (mandate §8-§9, §63)
  - The Go HTTP handler is the SINGLE authority for
    WorkflowRunId. StartRunWorkflow is now fail-closed
    if it receives an empty in.RunID.
  - The defensive `if out.RunID != runID { out.RunID = runID }`
    overwrite is REMOVED. A mismatch is now a 500
    RUN_IDENTITY_MISMATCH failure (mandate §9 forbids
    hiding identity inconsistency behind a fallback).
  - The harness adapter now mints a UUID-style `run-<UUID>`
    runId and passes it to the binary.

P0 #4 — generic evidencePath validation (mandate §16-§18)
  - The publication writer no longer relativizes only
    paths ending in `/result.json`. It now handles any
    filename (`error.txt`, `trace.json`,
    `provider-journal.json`, etc.) and rejects:
      * absolute Windows paths (C:\... D:\...)
      * absolute POSIX paths (/tmp/...)
      * file:// protocol prefixes
      * path-escape attempts (../, ..\)
  - The publication FAILS LOUDLY on any of these. No
    more "best-effort path conversion" warnings.

P0 #5 — typed qualification error classification (mandate §19-§20)
  - New `errors.ts` defines:
      QualificationNotImplemented    → NOT_IMPLEMENTED
      QualificationBlocked           → BLOCKED
      QualificationMethodologyInvalid→ NOT_VALID
      QualificationCorrectableFailure→ FAIL_CORRECTABLE
      QualificationArchitecturalFailure→ FAIL_ARCHITECTURAL
      QualificationHarnessError      → HARNESS_ERROR (new)
  - The runner catches every unclassified exception and
    maps it to QualificationHarnessError (NOT_VALID),
    not to a blanket FAIL_CORRECTABLE.
  - The DBOS real adapter's "not yet implemented" methods
    now throw QualificationNotImplemented so DBOS FC-14
    etc. surface as NOT_IMPLEMENTED in the canonical M0
    result (no more hidden FAIL_CORRECTABLE).
  - New QualificationStatus member: "HARNESS_ERROR".

New tests (mandate §3-§7, §8-§9)
  - test/dbos-attempt-allocator.test.ts (3 tests):
      * monotonic sequences for the same (runId, liId)
      * sequence survives a process restart (no reuse)
      * per-(runId, liId) sequences are independent
  - test/runid-invariant.test.ts (1 test):
      * the returned RunId is the canonical UUID-style
        `run-<UUID>`, NEVER the OLD `run-<liId>` pattern
      * the same RunId is recoverable after a fresh
        process restart with the same durable store
Rwanbt added a commit that referenced this pull request Oct 5, 2026
…297)

The 223 open alerts all carry the same most_recent_instance commit,
207ff45, which is origin/main and an ancestor of dev. The two analyses
since then, both on dev, completed with an empty error and 22 results each.
Of the 46 alerts carrying a security severity, 30 point at a path dev no
longer has; the remaining 16 can still describe dev, and 8 of those were
still true of the code at 26ba494.

github/index.ts took a URL out of a model-produced prompt and attached the
Action's GitHub token to the request, then wrote that URL to the log
unflattened (#14 critical, #23). attachmentUrl() now asserts the parsed
origin is https://github.com and the path is a user attachment before any
header exists; a URL that fails is dropped, never fetched. logSafe()
collapses control characters and bounds the line. The test asserts that
new URL() resolves ".." before the pathname is read, which is why
/user-attachments/../../settings/tokens is refused.

Three console scripts escaped only the quote in the env value they hand to
sst secret load (#2, #3, #4). The value is JSON read back from
sst secret list, so it holds escaped-quote pairs: escaping the quote alone
turned that into a double backslash followed by a quote, which closes the
value early, and a trailing backslash escaped the line's own closing quote.
quoteEnvValue() escapes the backslash first. Verified the test earns its
place: with the old escaping restored it is 0 pass / 3 fail.

checkMacosApp interpolated an IPC-supplied appName into a macOS .app path,
so a parent segment or a second separator could aim the existsSync probe
anywhere (#5). isBundleName() rejects anything that is not one plain
segment.

bundle-mobile.mjs joined its bun build arguments into a string and gave it
to execSync, i.e. a shell, with outdir coming from the command line (#8,
#35). execFileSync takes a list and spawns no shell.

formatDateForTable ended in .replace(",", ","), replacing a comma with
itself; removed, since Intl already emits the separator the locale wants
(#21).

Each fix has a regression test. No alert is dismissed and no query is
weakened.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant