@xema/omni-protocol 0.1.50 → 0.1.51

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.
@@ -1796,6 +1796,16 @@ export function validateTaskCommand(command, task, path = "command") {
1796
1796
  }
1797
1797
  if (!isPlainObject(task))
1798
1798
  return into.violations;
1799
+ // The task the command is held to has to be one the wire published. A host's own mapping of it,
1800
+ // handed in for want of the original, is not, and checking a command against it would be
1801
+ // checking against a task nobody has -- so the task is validated first, and a command is held
1802
+ // only to a task that stands.
1803
+ const published = new Collector();
1804
+ validateTaskInto(task, { channel: channel ?? "voice" }, `${path}.task`, published);
1805
+ if (published.violations.length > 0) {
1806
+ into.add("command.task", `${path}.task`, `the task the command is held to is not one the wire published (${published.violations.map(v => v.rule).join(", ")}): pass the task as the provider sent it, or validate the command's shape alone`);
1807
+ return into.violations;
1808
+ }
1799
1809
  // What the task has to offer or be in for the command to be issuable.
1800
1810
  const capabilities = isPlainObject(task.capabilities) ? task.capabilities : {};
1801
1811
  const offered = (name) => {
package/guide.md CHANGED
@@ -3887,7 +3887,13 @@ declared:
3887
3887
  | Everything else | Its own named capability. |
3888
3888
 
3889
3889
  `validateTaskCommand(command, task)` holds a command to this table at runtime, both ways: the
3890
- capability it needs, the phase it belongs to, and the state that has to stand.
3890
+ capability it needs, the phase it belongs to, and the state that has to stand. The task it wants
3891
+ is the one the provider published, not a host's own mapping of it: a host that keeps only its
3892
+ mapped shape has nothing honest to pass, and then checks shape alone, which is still worth doing
3893
+ -- it names a command the wire never had -- but is not the table. Keeping the published task
3894
+ beside the mapped one is what the full check costs a host; an adapter has it for free. The
3895
+ validator holds a command only to a task that stands: a task handed in that is not one the wire
3896
+ published is named (`command.task`) rather than checked against.
3891
3897
 
3892
3898
  Declining or rejecting a pending offer ends it without accepting or completing it. The provider
3893
3899
  confirms the end with `task-ended` and a `cancelled` outcome.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xema/omni-protocol",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "description": "The Omni protocol: the contract every provider adapter implements",
5
5
  "type": "module",
6
6
  "license": "MIT",