@mhome/app-facade-protocol 1.114.1 → 1.116.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,7 +13,9 @@ A call may carry optional `source: {kind, page?, cardId?}` beside `control` and
13
13
  `input`. Kinds are `ui`, `agent` (built-in Agent), `messaging`, `cli`, `skill`, `mcp`.
14
14
  Source hints never select authorization or actor. Trusted Agent/MCP ingress overrides
15
15
  hints; a canonical Messaging Agent surface keeps `messaging`, including through
16
- Cloud-to-Hub forwarding. CLI defaults to `cli`; external Skills explicitly pass
16
+ Cloud-to-Hub forwarding. Direct Messaging Dialog replies use the verified external sender
17
+ and a Messaging-only forwarding binding; they create no Agent run and can only invoke
18
+ `/app/dialog/reply` in direct mode. CLI defaults to `cli`; external Skills explicitly pass
17
19
  `meow --source skill`. UI sets `ui`. `appClientId` comes only from the verified
18
20
  Client identity, not connection routing IDs or an input hint.
19
21
 
@@ -35,11 +37,22 @@ not a claim that all its physical effects completed. Failures keep intent and er
35
37
  code, never raw exception messages, internal details, complete request/response or
36
38
  source scripts. Runtime completion/Twin observations belong to their own sources.
37
39
 
40
+ Facades may contribute frozen business facts through an execution-scoped hook. The
41
+ hook runs in the background writer and cannot replace canonical event/status/error
42
+ fields. Automation save and Overview save contribute the resolved YAML document
43
+ already obtained by the business flow. Their projection keeps name, description,
44
+ root `$` parameter values and input-variable references; task/action bodies, compiler
45
+ models, attached scripts and diagnostics are excluded. Hook failure leaves the
46
+ business response unchanged.
47
+
38
48
  Space mode determines the single storage owner: Local -> Hub SQLite, Cloud ->
39
49
  Lion's configured cloud store. Routing/forwarding creates no second record.
40
50
  The existing Space cleanup removes this partition. Hub queued deliveries retain
41
51
  the existing runtime fence so revoked/replaced generations cannot recreate records
42
- after cleanup; Cloud writes use the existing Space admission guard.
52
+ after cleanup. Cloud writers register with Space admission before reading the
53
+ authoritative Space identity; only ACTIVE Cloud Spaces accept queued records.
54
+ Terminal deletion marks the identity first, drains admitted work, then deletes the
55
+ partition, so other instances and delayed queue entries cannot recreate it.
43
56
  The physical row has `pk`, `sk`, `schemaVersion=1`, `payloadYaml` only:
44
57
 
45
58
  - `pk = tenant|space`.
@@ -47,6 +60,10 @@ The physical row has `pk`, `sk`, `schemaVersion=1`, `payloadYaml` only:
47
60
  - Fixed string order supports `[start,end)` queries in one partition. Pagination
48
61
  uses the last returned SK exclusively. No secondary index is required.
49
62
  - Inserts never replace an existing key. Retrying persistence reuses the same row.
63
+ - `household/behavior` participates in ordinary Cloud/Hub DataSync. Mode switches
64
+ merge immutable rows, preserve original keys/schema/YAML bytes, reject foreign
65
+ partitions and conflicting existing rows, and rely on the existing successful
66
+ import acknowledgement before source cleanup. A retry does not clear history.
50
67
  - YAML retains null, false, zero and typed values; no custom tags or raw JSON copy.
51
68
 
52
69
  Recording is best effort. Request code only captures immutable facts and offers
@@ -124,3 +124,10 @@ values, Duration values and schedule wall-clock times are not inferred to be dat
124
124
  Widget resources use `displayName` as their only human-readable name. Display names
125
125
  may repeat; identity and references use Widget IDs. Configuration patches may omit
126
126
  `displayName` to preserve it. Essential and Full both retain this name.
127
+
128
+ Device definition list/detail rows may carry `parent`, a provider-local physical
129
+ device grouping key scoped by Space, Integration and Connection. It does not name
130
+ a Core Device Group or require a separate parent Entity. Optional `setupStatus`
131
+ (`pending`, `failed`, `ready`) describes initial provider admission independently
132
+ of user enablement and subsequent online/offline observations. Essential device
133
+ lists retain both fields.
@@ -0,0 +1,28 @@
1
+ [
2
+ {
3
+ "source": "name: Bedtime\ndescription: Good night\ninputVars:\n - name: $time\n type: Time\n description: Bedtime\n internal: omit\n$time: \"23:00\"\n$enabled: false\n$count: 0\n$reset: null\ntask: internal-code\nscripts: secret-source\n",
4
+ "expected": {
5
+ "definition": {
6
+ "name": "Bedtime",
7
+ "description": "Good night",
8
+ "inputVariables": [
9
+ {
10
+ "name": "$time",
11
+ "type": "Time",
12
+ "description": "Bedtime"
13
+ }
14
+ ],
15
+ "parameters": {
16
+ "$time": "23:00",
17
+ "$enabled": false,
18
+ "$count": 0,
19
+ "$reset": null
20
+ }
21
+ }
22
+ }
23
+ },
24
+ {
25
+ "source": "task: internal-code",
26
+ "expected": null
27
+ }
28
+ ]
@@ -0,0 +1,6 @@
1
+ {
2
+ "pk": "t|s",
3
+ "sk": "0000000000100|on",
4
+ "schemaVersion": 1,
5
+ "payloadYaml": "id: on\noccurredAtMs: 100\nfinishedAtMs: 105\nactor:\n kind: user\n userId: user\nsource:\n kind: ui\ndata:\n event: widget.value.set\n status: success\n widgetId: w-d\n typedValue: false\n"
6
+ }
@@ -389,5 +389,256 @@
389
389
  "locationId": "home",
390
390
  "status": "success"
391
391
  }
392
+ },
393
+ {
394
+ "target": "/app/widget/button/trigger",
395
+ "input": {
396
+ "widgetId": "button-b",
397
+ "clickType": "single"
398
+ },
399
+ "outcome": {
400
+ "status": "success",
401
+ "data": {}
402
+ },
403
+ "expected": {
404
+ "event": "widget.button.pressed",
405
+ "widgetId": "button-b",
406
+ "clickType": "single",
407
+ "status": "success"
408
+ }
409
+ },
410
+ {
411
+ "target": "/app/automation/stop",
412
+ "input": {
413
+ "automationId": "A-1"
414
+ },
415
+ "outcome": {
416
+ "status": "success",
417
+ "data": {
418
+ "enabled": false,
419
+ "running": false
420
+ }
421
+ },
422
+ "expected": {
423
+ "event": "automation.stop",
424
+ "automationId": "A-1",
425
+ "enabled": false,
426
+ "running": false,
427
+ "status": "success"
428
+ }
429
+ },
430
+ {
431
+ "target": "/app/presentation/automation/generated/enable",
432
+ "input": {
433
+ "automationId": "P-1"
434
+ },
435
+ "outcome": {
436
+ "status": "success",
437
+ "data": {
438
+ "enabled": true,
439
+ "running": false
440
+ }
441
+ },
442
+ "expected": {
443
+ "event": "automation.enable",
444
+ "automationId": "P-1",
445
+ "enabled": true,
446
+ "running": false,
447
+ "status": "success"
448
+ }
449
+ },
450
+ {
451
+ "target": "/app/presentation/automation/generated/disable",
452
+ "input": {
453
+ "automationId": "P-1"
454
+ },
455
+ "outcome": {
456
+ "status": "success",
457
+ "data": {
458
+ "enabled": false,
459
+ "running": false
460
+ }
461
+ },
462
+ "expected": {
463
+ "event": "automation.disable",
464
+ "automationId": "P-1",
465
+ "enabled": false,
466
+ "running": false,
467
+ "status": "success"
468
+ }
469
+ },
470
+ {
471
+ "target": "/app/presentation/automation/generated/run",
472
+ "input": {
473
+ "automationId": "P-1"
474
+ },
475
+ "outcome": {
476
+ "status": "success",
477
+ "data": {
478
+ "enabled": false,
479
+ "running": true
480
+ }
481
+ },
482
+ "expected": {
483
+ "event": "automation.run",
484
+ "automationId": "P-1",
485
+ "enabled": false,
486
+ "running": true,
487
+ "status": "success"
488
+ }
489
+ },
490
+ {
491
+ "target": "/app/quickword/run",
492
+ "input": {
493
+ "quickWord": "good night",
494
+ "values": {
495
+ "time": "23:00"
496
+ }
497
+ },
498
+ "outcome": {
499
+ "status": "success",
500
+ "data": {
501
+ "dispatched": true
502
+ }
503
+ },
504
+ "expected": {
505
+ "event": "quickword.invoked",
506
+ "quickWord": "good night",
507
+ "values": {
508
+ "time": "23:00"
509
+ },
510
+ "dispatched": true,
511
+ "status": "success"
512
+ }
513
+ },
514
+ {
515
+ "target": "/app/automation/save",
516
+ "input": {
517
+ "singleUse": false,
518
+ "restoreEnabled": true,
519
+ "script": {
520
+ "script": "name: Bedtime\ndescription: Good night\n$time: \"23:00\"\ntask: internal-code"
521
+ }
522
+ },
523
+ "outcome": {
524
+ "status": "success",
525
+ "data": {
526
+ "automationId": "A-new"
527
+ }
528
+ },
529
+ "expected": {
530
+ "event": "automation.saved",
531
+ "singleUse": false,
532
+ "restoreEnabled": true,
533
+ "automationId": "A-new",
534
+ "definition": {
535
+ "name": "Bedtime",
536
+ "description": "Good night"
537
+ },
538
+ "status": "success"
539
+ }
540
+ },
541
+ {
542
+ "target": "/app/presentation/automation/overview/save",
543
+ "input": {
544
+ "sessionId": "editor",
545
+ "automationId": "A-1"
546
+ },
547
+ "outcome": {
548
+ "status": "success",
549
+ "data": {
550
+ "enabled": true
551
+ }
552
+ },
553
+ "expected": {
554
+ "event": "automation.saved",
555
+ "automationId": "A-1",
556
+ "enabled": true,
557
+ "status": "success"
558
+ }
559
+ },
560
+ {
561
+ "target": "/app/presentation/automation/enroll",
562
+ "input": {
563
+ "automationId": "S-source",
564
+ "name": "Bedtime"
565
+ },
566
+ "outcome": {
567
+ "status": "success",
568
+ "data": {
569
+ "automationId": "A-new"
570
+ }
571
+ },
572
+ "expected": {
573
+ "event": "automation.enroll",
574
+ "fromAutomationId": "S-source",
575
+ "name": "Bedtime",
576
+ "automationId": "A-new",
577
+ "status": "success"
578
+ }
579
+ },
580
+ {
581
+ "target": "/app/automation/delete",
582
+ "input": {
583
+ "automationIds": [
584
+ "A-1",
585
+ "A-2"
586
+ ]
587
+ },
588
+ "outcome": {
589
+ "status": "success",
590
+ "data": {}
591
+ },
592
+ "expected": {
593
+ "event": "automation.deleted",
594
+ "automationIds": [
595
+ "A-1",
596
+ "A-2"
597
+ ],
598
+ "status": "success"
599
+ }
600
+ },
601
+ {
602
+ "target": "/app/automation/snapshot/rollback",
603
+ "input": {
604
+ "automationId": "A-1",
605
+ "snapshotId": "snap"
606
+ },
607
+ "outcome": {
608
+ "status": "success",
609
+ "data": {
610
+ "automationId": "A-1"
611
+ }
612
+ },
613
+ "expected": {
614
+ "event": "automation.restored",
615
+ "automationId": "A-1",
616
+ "snapshotId": "snap",
617
+ "status": "success"
618
+ }
619
+ },
620
+ {
621
+ "target": "/app/widget/circadian/create",
622
+ "input": {
623
+ "locationId": "home",
624
+ "curve": "daylight",
625
+ "offset": 0,
626
+ "multiplier": 1.0
627
+ },
628
+ "outcome": {
629
+ "status": "success",
630
+ "data": {
631
+ "widgetId": "new-c"
632
+ }
633
+ },
634
+ "expected": {
635
+ "event": "circadian.configured",
636
+ "locationId": "home",
637
+ "curve": "daylight",
638
+ "offset": 0,
639
+ "multiplier": 1.0,
640
+ "widgetId": "new-c",
641
+ "status": "success"
642
+ }
392
643
  }
393
644
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "callSchema": "schema/facade-call.v1.schema.json",
5
5
  "routing": "manifest/routing.v1.json",
6
6
  "routingSchema": "schema/routing.v1.schema.json",
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.114.1",
2
+ "contractVersion": "1.116.0",
3
3
  "operations": {
4
4
  "/app/agent/context/get": "spaceRead",
5
5
  "/app/agent/credit/usage": "spaceRead",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.host-provision.targets.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "contract": "contract/host-provisioning-v1.md",
5
5
  "localTargets": [
6
6
  "/local/host/provision/start",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.hub.targets.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "appTargets": [
5
5
  "/app/hub/get",
6
6
  "/app/hub/remove",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.pod.targets.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "contract": "contract/pod-commissioning-v1.md",
5
5
  "localTargets": [
6
6
  "/local/pod/discovery/start",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.routing.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "targetPrefix": "/app/",
5
5
  "default": {
6
6
  "execution": "scopeMode"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.messaging.targets.v1",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "requestTargets": [
5
5
  "/app/messaging/provider/list",
6
6
  "/app/messaging/provider-account/list",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/app-facade-protocol",
3
- "version": "1.114.1",
3
+ "version": "1.116.0",
4
4
  "description": "Build-time protocol artifacts for mhome.app-facade",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "protocol": "mhome.app-facade",
3
- "contractVersion": "1.114.1",
3
+ "contractVersion": "1.116.0",
4
4
  "manifest": "manifest/app-facade.v1.json",
5
5
  "schemas": {
6
6
  "storage": "schema/storage.v1.schema.json",