Commit Graph
93 Commits
Author SHA1 Message Date
q792602257 1107ace89c Default-enable AI Planner in Host Agent; propose cloud-planner-proxy
Tests / Test passed: 626
- Host Agent now defaults AI_PLANNER_ENABLED=true (opt-out via env),
  scoped to apps/device-host-agent/host_agent/execution.py only; the
  shared runtime.planner_config default (disabled) is unchanged.
- Add openspec proposal for cloud-planner-proxy: centralize LLM
  provider config/credentials on the Cloud Control Plane and let the
  Host Agent proxy AI Planner decisions through it instead of holding
  provider API keys locally. Proposal only, no implementation yet.
2026-07-13 20:50:35 +08:00
q792602257 78ce788e2f chore(openspec): archive android-driver
Tests / Test passed: 624
Archives the completed android-driver change (16/16 tasks). Promotes
the driver_type="uiautomator2" scenario into the canonical
driver-registry spec and moves the change artifacts to
openspec/changes/archive/2026-07-13-android-driver/.
2026-07-13 20:39:27 +08:00
q792602257 938d97a2ad docs(openspec): complete android-driver command sanity check
Completes task 1.1: verified mobile: clickGesture, mobile: dragGesture,
mobile: pressKey (keycode=3 / KEYCODE_HOME), and the appium:systemPort
capability against the official appium-uiautomator2-driver README and
android-mobile-gestures.md (master, 2026-07), plus the installed
appium-python-client 5.3.1. All four match driver/android_driver.py.

16/16 tasks complete; openspec validate --strict passes.
2026-07-13 20:24:49 +08:00
q792602257 c162c2501b feat(cloud): remove static credentials and add host console
Tests / Test No test results found
2026-07-13 19:45:53 +08:00
q792602257 efeb3eb926 Implement edge-host-self-enrollment
Tests / Test passed: 581
Host Agent:
- One-time local operator account bootstrap (PBKDF2-HMAC-SHA256, atomic
  0600-permission write) gating the daemon's first unattended start via a
  new `setup` CLI subcommand.
- Default control-plane URL now https://amcp.home.jerryyan.top (env var
  override unchanged).
- Enrollment no longer requires a pre-issued token; falls back to
  zero-token self-service enrollment when none is configured.

Cloud control plane:
- CLOUD_SELF_SERVICE_ENROLLMENT_ENABLED (default false) opt-in flag.
- SelfServiceEnrollmentAuthProvider + ChainedEnrollmentAuthProvider:
  configured tokens still take priority; self-service only applies when
  no token matches, preserving edge-host-enrollment's token-bound path.
- Fixed a latent bug in sql_repository.py::enroll_host: the token-conflict
  lookup used `== enrollment_token_digest`, which SQLAlchemy compiles to
  `IS NULL` when the value is None, so every self-service enrollment after
  the first would have falsely collided with an existing NULL-digest host.
  Skipped that lookup entirely when the digest is None.

Docs/deploy: .env.example, compose.yaml, compose.deploy.yaml,
CLOUD_DEPLOYMENT.md, MACOS_IPHONE_SETUP.md updated for the new flag,
URL default, and required `device-host-agent setup` step.

Verification: 494 non-integration tests pass; openspec validate --strict
passes. PostgreSQL-backed contract tests and full manual end-to-end
verification were not run (no Postgres/Docker or reachable cloud-api in
this environment); noted as unchecked in tasks.md 7.2/7.4.
2026-07-13 18:30:49 +08:00
q792602257 a2802c6320 chore(openspec): add edge host self-enrollment proposal
Tests / Test passed: 558
2026-07-13 17:55:40 +08:00
q792602257 c72c31de04 docs(cloud-console): document user authentication 2026-07-13 17:55:21 +08:00
q792602257andClaude Opus 4.6 50f0b8ade9 feat(driver): add Android UiAutomator2 driver
Tests / Test No test results found
Register `SUPPORTED_DRIVER_TYPES["uiautomator2"]` backed by the new
`AndroidDriver`, mirroring `WDADriver` method-for-method. tap/swipe/home use
the confirmed UiAutomator2 mobile commands (`clickGesture`, `dragGesture`,
`pressKey`); swipe converts `duration_ms` to a drag speed with a zero-distance
guard. Adds 34 mocked unit tests, an env-var-gated integration test, and
corrects the outdated "Android not registered" note in the iPhone setup doc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 14:47:01 +08:00
q792602257andClaude Opus 4.6 2169bb03d9 feat(cloud-console): task listing, attempt history, CORS, and console SPA
Implements the cloud-console OpenSpec change: adds GET /v1/tasks (filterable,
bounded pagination, tasks:read) and GET /v1/tasks/{id}/attempts (404 on unknown
task) to the platform SDK, with matching CloudClient methods and a closed-by-
default CLOUD_CONSOLE_CORS_ORIGINS allow-list wired through CloudControlConfig.
Ships an independent Vue 3 + Vite SPA at cloud-console/ that authenticates with
an operator-supplied bearer token held in sessionStorage, renders tasks with
attempt history, device pool, host registry, and the plugin registry with a
registration form.

Backend test suite: 438 passed (-m "not integration"); cloud-console typecheck
and production build both succeed. PostgreSQL-backed repository tests and
manual end-to-end verification remain pending external infrastructure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-13 14:00:23 +08:00
q792602257 62923b9285 docs(openspec): confirm android-driver UiAutomator2 commands via research
Resolve the previously-open design questions in the android-driver
change by researching the appium-uiautomator2-driver docs and Appium 3
release notes:

- tap -> mobile: clickGesture
- swipe -> mobile: dragGesture (duration_ms converted to speed px/s)
- home -> mobile: pressKey (KEYCODE_HOME)
- port isolation -> appium:systemPort capability
- Appium 3 breaking changes confirmed to not affect this design

Updates design.md (Decisions/Risks/Open Questions/Migration Plan) and
tasks.md (section 1 and tasks 2.1/2.4/4.1) accordingly.
2026-07-13 13:56:04 +08:00
q792602257 e61dcca801 feat(cloud): add edge host enrollment 2026-07-13 13:54:16 +08:00
q792602257 cd56facbbf chore(openspec): add android-driver proposal 2026-07-13 12:48:09 +08:00
q792602257 960361493c chore(openspec): add cloud-console proposal 2026-07-13 11:49:34 +08:00
q792602257 e9006c3a29 chore(openspec): archive cloud control plane integration 2026-07-13 09:00:53 +08:00
q792602257 70d15f8f0b docs(openspec): sync cloud control plane specs 2026-07-13 08:58:04 +08:00
q792602257 ea9b15fce7 docs(project): record cloud control plane maturity 2026-07-13 08:25:43 +08:00
q792602257 7b717a05a9 test(openspec): map cloud integration scenarios 2026-07-13 08:21:44 +08:00
q792602257 ffc3df6c5b test(runtime): verify local interfaces 2026-07-13 08:11:18 +08:00
q792602257 e162ec5041 test(cloud): verify public execution outcomes 2026-07-13 08:10:11 +08:00
q792602257 22d37ca95b chore(cloud): verify integration change 2026-07-13 08:06:15 +08:00
q792602257 3c5f5509c2 docs(cloud): state deployment limitations 2026-07-13 07:59:56 +08:00
q792602257 e28705b0f2 docs(cloud): add deployment runbook 2026-07-13 07:58:24 +08:00
q792602257 dbd70732e1 build(deploy): add cloud stack containers 2026-07-12 22:58:17 +08:00
q792602257 1f95d23beb feat(cloud-sdk): authenticate client requests 2026-07-12 22:53:34 +08:00
q792602257 16bcbf5a27 feat(cloud-sdk): expose distributed task status 2026-07-12 19:57:03 +08:00
q792602257 77fadbd9e6 test(host-agent): cover distributed recovery flows 2026-07-12 19:54:30 +08:00
q792602257 b1303569e3 feat(host-agent): shut down gracefully 2026-07-12 19:47:50 +08:00
q792602257 91f08509a7 feat(host-agent): report assignment outcomes 2026-07-12 19:09:07 +08:00
q792602257 ec1e8c20d8 feat(host-agent): renew active assignment leases 2026-07-12 19:06:22 +08:00
q792602257 6dc2803ccc feat(host-agent): execute cloud assignments 2026-07-12 18:52:32 +08:00
q792602257 ab538513b0 feat(host-agent): compose execution factories 2026-07-12 18:50:21 +08:00
q792602257 6e59f2f3ca feat(host-agent): synchronize device snapshots 2026-07-12 18:48:17 +08:00
q792602257 f6bc8f6b98 feat(host-agent): add control plane client 2026-07-12 18:44:18 +08:00
q792602257 1e10d5aa95 test(cloud-api): verify restart recovery 2026-07-12 18:40:29 +08:00
q792602257 8131c0124b feat(cloud-api): add correlated lifecycle logging 2026-07-12 18:37:51 +08:00
q792602257 a5de7399f8 feat(cloud-api): expose health readiness 2026-07-12 18:33:45 +08:00
q792602257 b8d02abf87 fix(cloud-api): retry lifecycle iterations 2026-07-12 18:31:19 +08:00
q792602257 937a4646e1 feat(cloud-api): run lifecycle workers 2026-07-12 18:26:41 +08:00
q792602257 bd261e4992 feat(cloud-api): compose control plane services 2026-07-12 18:21:57 +08:00
q792602257 09cfe54dd9 test(host-protocol): verify internal API isolation 2026-07-12 18:17:39 +08:00
q792602257 a24efc1043 feat(host-protocol): renew and complete leases 2026-07-12 18:15:04 +08:00
q792602257 c7f8d0c128 feat(host-protocol): long poll assignments 2026-07-12 18:12:33 +08:00
q792602257 efb754fbe7 feat(host-protocol): accept heartbeat snapshots 2026-07-12 18:10:42 +08:00
q792602257 b4cbd83dcd feat(host-protocol): define internal API models 2026-07-12 18:07:42 +08:00
q792602257 a05465458c test(cloud-auth): cover authorization failures 2026-07-12 18:05:30 +08:00
q792602257 7d22b5234d feat(cloud-auth): require production credentials 2026-07-12 18:02:49 +08:00
q792602257 82b66f74a2 feat(cloud-auth): bind host principals 2026-07-12 17:58:20 +08:00
q792602257 71f0a892e3 feat(cloud-auth): enforce public scopes 2026-07-12 17:56:14 +08:00
q792602257 b916b394c7 feat(cloud-auth): verify scoped bearer tokens 2026-07-12 17:45:31 +08:00
q792602257 4cb116f527 test(cloud-scheduler): prove assignment concurrency 2026-07-12 17:42:20 +08:00