Repository navigation
Conversation
- Closed verb grammar (plan §7): strict parser, first non-empty line only, one action per turn, hints checked against the current observation - Observation model: node filter with z-order and dedupe (C4), coverage detector (C1), session-stable hint table with quarantine (C3), screen fingerprint, paging at 60 with more - Formatter renders the <<OBS ... OBS>> block; labels are one bounded, escaped token so screen text can never open or close the block Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
- policy/policy.yaml: verb tiers as ordered data rules (plan §4), app allowlist, sensitive controls in EN and ES, settings packages - policy/cases.yaml: shared conformance cases; every rule has one - PolicyEnforcer: pure rule walk plus the gate (grant / card / refuse) - Ports the phone implements: Observer, Planner, Executor, ApprovalSurface, KillSwitch, SqlExecutor, SecretStore Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
- Accessibility service: tree walker with stable identities, observer, executor (accessibility actions first, gestures second, plan §7) - Approval surface: overlay highlight and card plus notification with Approve and Deny; timeout is deny (plan §4) - Kill switch: Quick Settings tile and Stop action on the task notification - Notification listener with inline reply; assistant role services; Keystore-wrapped secret store; SQLite executor; foreground task service; settings activity with the policy self-check - Type-checked against the API 36 framework jar (tools/androidcheck); assembleDebug still needs the SDK Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
…eck and kill switch
…t the root CI's core job sets ANDROID_HOME="" to force the SDK-less path, which the settings script converted to a File. The app job failed because org.jetbrains.kotlin.android was requested with a version while the Kotlin Gradle Plugin was already on the root classpath from kotlin.jvm. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
Hostile screen text, prose and JSON replies, multi-line replies, invented hints, non-allowlisted apps, app drift, keyguard, and a missing task grant: in every case nothing executes beyond the grammar and the policy gate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
The Kotlin Android plugin and the Android Gradle Plugin must load in one classloader; with KGP at the root and AGP only in :app the app build failed with NoClassDefFoundError com/android/build/gradle/BaseExtension. AGP is added to the root buildscript classpath only when settings found an SDK, so the SDK-less core build stays free of it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
…rovals and append-only triggers; AuditStore with redaction and desktop-shaped exports
…r client) and steering (rules boundary, instruction stack)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
- CloudPlanner: one brain-tier chat call per step, metered; spend cap turns into an ask line so the turn ends cleanly - AuditListener: every step, approval and model call is an INSERT through the redactor; unparsed replies are recorded too - Planners: picks cloud-key, home or device from the active preset and says plainly what is missing (key, slug, unbuilt device mode) - Graph: config presets, Endpoints allowlist, audit store with migrations, seeded agent-unwritable rules dir with RulesBoundary, per-device id Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
okhttp-android 5.5.0 requires compileSdk 37, beyond AGP 8.13's maximum of 36, and drags in AndroidX. The plain JVM artifact runs fine on Android and keeps the dependency surface to what core actually uses. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
…, sequence tracker, OkHttp client)
The net module's source scan (the no-telemetry promise) caught the wire client holding its own OkHttpClient factory. It now asks Endpoints for the WebSocket client, so the host is checked against config before any connection exists. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
- Endpoints never follows redirects, refuses cleartext outside loopback and the tailnet, pins MagicDNS names to tailnet addresses, and judges every network hop; hosts are recorded once per call - MagicDNS names classify as tailnet; tailnet tiers send no key unless bound; credential routing mirrors tstd (an OpenRouter key only ever goes to OpenRouter); a key over plain http to a third party fails validation - Fingerprints fold actionable labels and toggle state so a recycled row cannot be tapped after its contents changed - notif list becomes a NOTIF data block for the model; notification verbs are judged by the posting app (allowlist and intent lock apply) - recursive_triggers on, so INSERT OR REPLACE cannot rewrite audit rows - ClientMessage.toString never shows the hello token - Conformance drives the enforcer's own fact derivation; the outbound scan covers app sources too Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
- TreeObserver builds observe() and fingerprint() from one filtered screen (no overlay windows), so an approved action no longer fails the stale check because our own card was on screen; FLAG_SECURE is not inferred - NodeExecutor re-checks the target's label before acting, refuses text into non-editable nodes, marks the paste clip sensitive and clears it, and drags as one continued stroke instead of a second pointer at (0,0) - TreeWalker derives a label for clickable containers whose words live in a child, so a Delete row is a sensitive control - Cancellation is rethrown in the task service and the planner; the service only stops itself for its own start; ask lines are quoted safely - Keystore: an unreadable secret is forgotten, not a crash; key() synchronized - Rules boundary root is the files dir; audit detail is bounded; the notification listener reports posters; goal apps never widen to the whole allowlist; the direct-to-box planner is named home-direct - Settings: the person's config.yaml overrides the shipped presets; a Home box section (MagicDNS URL, model, optional key), a one-call brain test, and a way back to the shipped presets Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The first build of TST Assist per
docs/tst-assist-android.md(v2.0 plan, paste ends at §9.4 S1). A pure-JVM Kotlin core, built and tested, plus the Android side written against framework APIs. CI runs the JVM suite and a realassembleDebug; both are green.In this PR
core/ (JVM, 254 tests,
./gradlew :core:test)more. Labels render as one bounded escaped token so screen text can never open or close the<<OBSblock.policy/policy.yamlas ordered data rules;policy/cases.yamlconformance suite (every rule has a case); Kotlin enforcer with the silent / once / every / refused gate; sensitive controls in EN and ES.logging.py(same five patterns, structure scrub, idempotent).config.yamlshape (desktop presets copied, plusdeviceandhome), and the cost meter with tstd's cache-honesty rule (absent cache figure is not zero).ws.pyandtailscale_bind.py(loopback always, one Tailscale extra, never unspecified), token and hello handshake,Endpointsas the single place a connection is made (hosts not named in config are refused), OpenAI-compatible provider client, and a source scan that fails if anything else opens a connection.ASSISTANT.md,CHARTER.md,profiles/,policy.yaml, escapes and symlinks), instruction stack with token estimate, defaultASSISTANT.md.approval.ts, sequence tracking, checked against TST Desk's ownprotocol-fixtures.json.app/ (Android, framework APIs only,
assembleDebuggreen in CI, not yet run on a phone)docs/: the plan as supplied, a decision log (TM-001 to TM-009), README.
Still landing on this branch
docs/reality-check.md: the plan's claims checked line by line against TST Desk's code, plus the counterpoints that survived an adversarial review. The review is running.Not done
🤖 Generated with Claude Code
https://claude.ai/code/session_01Vyo2hxtfWppNVyy99Q8GmZ