@sharpee/stdlib 3.1.0 → 3.3.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.
Files changed (712) hide show
  1. package/actions/author/index.d.ts +1 -1
  2. package/actions/author/index.d.ts.map +1 -1
  3. package/actions/author/index.js +2 -2
  4. package/actions/author/index.js.map +1 -1
  5. package/actions/author/trace.d.ts +3 -3
  6. package/actions/author/trace.d.ts.map +1 -1
  7. package/actions/author/trace.js +2 -2
  8. package/actions/author/trace.js.map +1 -1
  9. package/actions/base/index.d.ts +2 -2
  10. package/actions/base/index.d.ts.map +1 -1
  11. package/actions/base/index.js +2 -2
  12. package/actions/base/index.js.map +1 -1
  13. package/actions/base/migration-shim.d.ts +1 -1
  14. package/actions/base/migration-shim.d.ts.map +1 -1
  15. package/actions/base/report-helpers.d.ts +1 -1
  16. package/actions/base/report-helpers.d.ts.map +1 -1
  17. package/actions/base/report-helpers.js +3 -3
  18. package/actions/base/report-helpers.js.map +1 -1
  19. package/actions/capability-dispatch.d.ts +3 -3
  20. package/actions/capability-dispatch.d.ts.map +1 -1
  21. package/actions/capability-dispatch.js +18 -8
  22. package/actions/capability-dispatch.js.map +1 -1
  23. package/actions/context-adapter.d.ts +2 -2
  24. package/actions/context-adapter.d.ts.map +1 -1
  25. package/actions/data-builder-types.d.ts +1 -1
  26. package/actions/data-builder-types.d.ts.map +1 -1
  27. package/actions/enhanced-context.d.ts +5 -4
  28. package/actions/enhanced-context.d.ts.map +1 -1
  29. package/actions/enhanced-context.js +85 -67
  30. package/actions/enhanced-context.js.map +1 -1
  31. package/actions/enhanced-types.d.ts +29 -3
  32. package/actions/enhanced-types.d.ts.map +1 -1
  33. package/actions/enhanced-types.js.map +1 -1
  34. package/actions/helpers/emit-illustrations.d.ts +1 -1
  35. package/actions/helpers/emit-illustrations.d.ts.map +1 -1
  36. package/actions/index.d.ts +10 -10
  37. package/actions/index.d.ts.map +1 -1
  38. package/actions/index.js +12 -12
  39. package/actions/index.js.map +1 -1
  40. package/actions/lifecycle/descriptor.d.ts +1 -1
  41. package/actions/lifecycle/descriptor.d.ts.map +1 -1
  42. package/actions/lifecycle/index.d.ts +3 -3
  43. package/actions/lifecycle/index.d.ts.map +1 -1
  44. package/actions/lifecycle/index.js +15 -14
  45. package/actions/lifecycle/index.js.map +1 -1
  46. package/actions/lifecycle/lifecycle-engine.d.ts +18 -2
  47. package/actions/lifecycle/lifecycle-engine.d.ts.map +1 -1
  48. package/actions/lifecycle/lifecycle-engine.js +26 -1
  49. package/actions/lifecycle/lifecycle-engine.js.map +1 -1
  50. package/actions/lifecycle/multi-object-lifecycle.d.ts +13 -5
  51. package/actions/lifecycle/multi-object-lifecycle.d.ts.map +1 -1
  52. package/actions/lifecycle/multi-object-lifecycle.js +14 -12
  53. package/actions/lifecycle/multi-object-lifecycle.js.map +1 -1
  54. package/actions/lifecycle/registry.d.ts +4 -3
  55. package/actions/lifecycle/registry.d.ts.map +1 -1
  56. package/actions/lifecycle/registry.js +79 -76
  57. package/actions/lifecycle/registry.js.map +1 -1
  58. package/actions/meta-action.d.ts +1 -1
  59. package/actions/meta-action.d.ts.map +1 -1
  60. package/actions/meta-action.js +2 -2
  61. package/actions/meta-action.js.map +1 -1
  62. package/actions/registry.d.ts +2 -2
  63. package/actions/registry.d.ts.map +1 -1
  64. package/actions/standard/about/about.d.ts +2 -2
  65. package/actions/standard/about/about.d.ts.map +1 -1
  66. package/actions/standard/about/about.js +4 -3
  67. package/actions/standard/about/about.js.map +1 -1
  68. package/actions/standard/about/index.d.ts +2 -2
  69. package/actions/standard/about/index.d.ts.map +1 -1
  70. package/actions/standard/about/index.js +2 -2
  71. package/actions/standard/about/index.js.map +1 -1
  72. package/actions/standard/again/again.d.ts +2 -2
  73. package/actions/standard/again/again.d.ts.map +1 -1
  74. package/actions/standard/again/again.js +4 -3
  75. package/actions/standard/again/again.js.map +1 -1
  76. package/actions/standard/again/index.d.ts +2 -2
  77. package/actions/standard/again/index.d.ts.map +1 -1
  78. package/actions/standard/again/index.js +2 -2
  79. package/actions/standard/again/index.js.map +1 -1
  80. package/actions/standard/asking/asking.d.ts +3 -3
  81. package/actions/standard/asking/asking.d.ts.map +1 -1
  82. package/actions/standard/asking/asking.js +35 -26
  83. package/actions/standard/asking/asking.js.map +1 -1
  84. package/actions/standard/asking/index.d.ts +1 -1
  85. package/actions/standard/asking/index.d.ts.map +1 -1
  86. package/actions/standard/asking/index.js +3 -3
  87. package/actions/standard/asking/index.js.map +1 -1
  88. package/actions/standard/attacking/attacking-data.d.ts +2 -2
  89. package/actions/standard/attacking/attacking-data.d.ts.map +1 -1
  90. package/actions/standard/attacking/attacking-events.d.ts +1 -1
  91. package/actions/standard/attacking/attacking-events.d.ts.map +1 -1
  92. package/actions/standard/attacking/attacking-types.d.ts +3 -0
  93. package/actions/standard/attacking/attacking-types.d.ts.map +1 -1
  94. package/actions/standard/attacking/attacking-types.js.map +1 -1
  95. package/actions/standard/attacking/attacking.d.ts +3 -3
  96. package/actions/standard/attacking/attacking.d.ts.map +1 -1
  97. package/actions/standard/attacking/attacking.js +75 -52
  98. package/actions/standard/attacking/attacking.js.map +1 -1
  99. package/actions/standard/attacking/index.d.ts +2 -2
  100. package/actions/standard/attacking/index.d.ts.map +1 -1
  101. package/actions/standard/attacking/index.js +4 -4
  102. package/actions/standard/attacking/index.js.map +1 -1
  103. package/actions/standard/climbing/climbing.d.ts +3 -3
  104. package/actions/standard/climbing/climbing.d.ts.map +1 -1
  105. package/actions/standard/climbing/climbing.js +72 -30
  106. package/actions/standard/climbing/climbing.js.map +1 -1
  107. package/actions/standard/climbing/index.d.ts +2 -2
  108. package/actions/standard/climbing/index.d.ts.map +1 -1
  109. package/actions/standard/climbing/index.js +2 -2
  110. package/actions/standard/climbing/index.js.map +1 -1
  111. package/actions/standard/closing/closing-data.d.ts +1 -1
  112. package/actions/standard/closing/closing-data.d.ts.map +1 -1
  113. package/actions/standard/closing/closing-data.js +3 -3
  114. package/actions/standard/closing/closing-data.js.map +1 -1
  115. package/actions/standard/closing/closing-event-data.d.ts +1 -1
  116. package/actions/standard/closing/closing-event-data.d.ts.map +1 -1
  117. package/actions/standard/closing/closing.d.ts +3 -3
  118. package/actions/standard/closing/closing.d.ts.map +1 -1
  119. package/actions/standard/closing/closing.js +36 -38
  120. package/actions/standard/closing/closing.js.map +1 -1
  121. package/actions/standard/closing/index.d.ts +3 -3
  122. package/actions/standard/closing/index.d.ts.map +1 -1
  123. package/actions/standard/closing/index.js +2 -2
  124. package/actions/standard/closing/index.js.map +1 -1
  125. package/actions/standard/cutting/cutting.d.ts +3 -3
  126. package/actions/standard/cutting/cutting.d.ts.map +1 -1
  127. package/actions/standard/cutting/cutting.js +40 -36
  128. package/actions/standard/cutting/cutting.js.map +1 -1
  129. package/actions/standard/cutting/index.d.ts +3 -3
  130. package/actions/standard/cutting/index.d.ts.map +1 -1
  131. package/actions/standard/cutting/index.js +5 -5
  132. package/actions/standard/cutting/index.js.map +1 -1
  133. package/actions/standard/deadly-room-death/deadly-room-death.d.ts +1 -1
  134. package/actions/standard/deadly-room-death/deadly-room-death.d.ts.map +1 -1
  135. package/actions/standard/deadly-room-death/deadly-room-death.js +5 -5
  136. package/actions/standard/deadly-room-death/deadly-room-death.js.map +1 -1
  137. package/actions/standard/deadly-room-death/index.d.ts +1 -1
  138. package/actions/standard/deadly-room-death/index.d.ts.map +1 -1
  139. package/actions/standard/deadly-room-death/index.js +2 -2
  140. package/actions/standard/deadly-room-death/index.js.map +1 -1
  141. package/actions/standard/digging/digging.d.ts +3 -3
  142. package/actions/standard/digging/digging.d.ts.map +1 -1
  143. package/actions/standard/digging/digging.js +40 -36
  144. package/actions/standard/digging/digging.js.map +1 -1
  145. package/actions/standard/digging/index.d.ts +3 -3
  146. package/actions/standard/digging/index.d.ts.map +1 -1
  147. package/actions/standard/digging/index.js +5 -5
  148. package/actions/standard/digging/index.js.map +1 -1
  149. package/actions/standard/drinking/drinking.d.ts +3 -3
  150. package/actions/standard/drinking/drinking.d.ts.map +1 -1
  151. package/actions/standard/drinking/drinking.js +25 -25
  152. package/actions/standard/drinking/drinking.js.map +1 -1
  153. package/actions/standard/drinking/index.d.ts +2 -2
  154. package/actions/standard/drinking/index.d.ts.map +1 -1
  155. package/actions/standard/drinking/index.js +3 -3
  156. package/actions/standard/drinking/index.js.map +1 -1
  157. package/actions/standard/dropping/dropping-data.d.ts +2 -2
  158. package/actions/standard/dropping/dropping-data.d.ts.map +1 -1
  159. package/actions/standard/dropping/dropping-data.js +9 -9
  160. package/actions/standard/dropping/dropping-data.js.map +1 -1
  161. package/actions/standard/dropping/dropping-events.d.ts +1 -1
  162. package/actions/standard/dropping/dropping-events.d.ts.map +1 -1
  163. package/actions/standard/dropping/dropping.d.ts +3 -3
  164. package/actions/standard/dropping/dropping.d.ts.map +1 -1
  165. package/actions/standard/dropping/dropping.js +74 -63
  166. package/actions/standard/dropping/dropping.js.map +1 -1
  167. package/actions/standard/dropping/index.d.ts +2 -2
  168. package/actions/standard/dropping/index.d.ts.map +1 -1
  169. package/actions/standard/dropping/index.js +2 -2
  170. package/actions/standard/dropping/index.js.map +1 -1
  171. package/actions/standard/eating/eating.d.ts +3 -3
  172. package/actions/standard/eating/eating.d.ts.map +1 -1
  173. package/actions/standard/eating/eating.js +25 -25
  174. package/actions/standard/eating/eating.js.map +1 -1
  175. package/actions/standard/eating/index.d.ts +2 -2
  176. package/actions/standard/eating/index.d.ts.map +1 -1
  177. package/actions/standard/eating/index.js +3 -3
  178. package/actions/standard/eating/index.js.map +1 -1
  179. package/actions/standard/entering/entering.d.ts +3 -3
  180. package/actions/standard/entering/entering.d.ts.map +1 -1
  181. package/actions/standard/entering/entering.js +32 -32
  182. package/actions/standard/entering/entering.js.map +1 -1
  183. package/actions/standard/entering/index.d.ts +2 -2
  184. package/actions/standard/entering/index.d.ts.map +1 -1
  185. package/actions/standard/entering/index.js +2 -2
  186. package/actions/standard/entering/index.js.map +1 -1
  187. package/actions/standard/examining/examining-data.d.ts +1 -1
  188. package/actions/standard/examining/examining-data.d.ts.map +1 -1
  189. package/actions/standard/examining/examining-data.js +72 -17
  190. package/actions/standard/examining/examining-data.js.map +1 -1
  191. package/actions/standard/examining/examining.d.ts +3 -3
  192. package/actions/standard/examining/examining.d.ts.map +1 -1
  193. package/actions/standard/examining/examining.js +31 -29
  194. package/actions/standard/examining/examining.js.map +1 -1
  195. package/actions/standard/examining/index.d.ts +2 -2
  196. package/actions/standard/examining/index.d.ts.map +1 -1
  197. package/actions/standard/examining/index.js +2 -2
  198. package/actions/standard/examining/index.js.map +1 -1
  199. package/actions/standard/exiting/exiting-messages.d.ts +2 -0
  200. package/actions/standard/exiting/exiting-messages.d.ts.map +1 -1
  201. package/actions/standard/exiting/exiting-messages.js +2 -0
  202. package/actions/standard/exiting/exiting-messages.js.map +1 -1
  203. package/actions/standard/exiting/exiting.d.ts +3 -3
  204. package/actions/standard/exiting/exiting.d.ts.map +1 -1
  205. package/actions/standard/exiting/exiting.js +46 -27
  206. package/actions/standard/exiting/exiting.js.map +1 -1
  207. package/actions/standard/exiting/index.d.ts +2 -2
  208. package/actions/standard/exiting/index.d.ts.map +1 -1
  209. package/actions/standard/exiting/index.js +2 -2
  210. package/actions/standard/exiting/index.js.map +1 -1
  211. package/actions/standard/giving/giving.d.ts +3 -3
  212. package/actions/standard/giving/giving.d.ts.map +1 -1
  213. package/actions/standard/giving/giving.js +39 -38
  214. package/actions/standard/giving/giving.js.map +1 -1
  215. package/actions/standard/giving/index.d.ts +2 -2
  216. package/actions/standard/giving/index.d.ts.map +1 -1
  217. package/actions/standard/giving/index.js +3 -3
  218. package/actions/standard/giving/index.js.map +1 -1
  219. package/actions/standard/going/going-data.d.ts +1 -1
  220. package/actions/standard/going/going-data.d.ts.map +1 -1
  221. package/actions/standard/going/going-data.js +6 -6
  222. package/actions/standard/going/going-data.js.map +1 -1
  223. package/actions/standard/going/going.d.ts +11 -3
  224. package/actions/standard/going/going.d.ts.map +1 -1
  225. package/actions/standard/going/going.js +80 -47
  226. package/actions/standard/going/going.js.map +1 -1
  227. package/actions/standard/going/index.d.ts +2 -2
  228. package/actions/standard/going/index.d.ts.map +1 -1
  229. package/actions/standard/going/index.js +5 -3
  230. package/actions/standard/going/index.js.map +1 -1
  231. package/actions/standard/help/help.d.ts +2 -2
  232. package/actions/standard/help/help.d.ts.map +1 -1
  233. package/actions/standard/help/help.js +4 -3
  234. package/actions/standard/help/help.js.map +1 -1
  235. package/actions/standard/help/index.d.ts +2 -2
  236. package/actions/standard/help/index.d.ts.map +1 -1
  237. package/actions/standard/help/index.js +2 -2
  238. package/actions/standard/help/index.js.map +1 -1
  239. package/actions/standard/hiding/concealment-break.js +19 -19
  240. package/actions/standard/hiding/concealment-break.js.map +1 -1
  241. package/actions/standard/hiding/hiding.d.ts +4 -4
  242. package/actions/standard/hiding/hiding.d.ts.map +1 -1
  243. package/actions/standard/hiding/hiding.js +28 -23
  244. package/actions/standard/hiding/hiding.js.map +1 -1
  245. package/actions/standard/hiding/index.d.ts +4 -4
  246. package/actions/standard/hiding/index.d.ts.map +1 -1
  247. package/actions/standard/hiding/index.js +6 -6
  248. package/actions/standard/hiding/index.js.map +1 -1
  249. package/actions/standard/hiding/revealing.d.ts +2 -2
  250. package/actions/standard/hiding/revealing.d.ts.map +1 -1
  251. package/actions/standard/hiding/revealing.js +4 -3
  252. package/actions/standard/hiding/revealing.js.map +1 -1
  253. package/actions/standard/index.d.ts +61 -61
  254. package/actions/standard/index.d.ts.map +1 -1
  255. package/actions/standard/index.js +179 -179
  256. package/actions/standard/index.js.map +1 -1
  257. package/actions/standard/inserting/index.d.ts +2 -2
  258. package/actions/standard/inserting/index.d.ts.map +1 -1
  259. package/actions/standard/inserting/index.js +3 -3
  260. package/actions/standard/inserting/index.js.map +1 -1
  261. package/actions/standard/inserting/inserting-data.d.ts +1 -1
  262. package/actions/standard/inserting/inserting-data.d.ts.map +1 -1
  263. package/actions/standard/inserting/inserting-data.js +3 -3
  264. package/actions/standard/inserting/inserting-data.js.map +1 -1
  265. package/actions/standard/inserting/inserting-events.d.ts +2 -2
  266. package/actions/standard/inserting/inserting-events.d.ts.map +1 -1
  267. package/actions/standard/inserting/inserting.d.ts +3 -3
  268. package/actions/standard/inserting/inserting.d.ts.map +1 -1
  269. package/actions/standard/inserting/inserting.js +40 -39
  270. package/actions/standard/inserting/inserting.js.map +1 -1
  271. package/actions/standard/inventory/index.d.ts +2 -2
  272. package/actions/standard/inventory/index.d.ts.map +1 -1
  273. package/actions/standard/inventory/index.js +3 -3
  274. package/actions/standard/inventory/index.js.map +1 -1
  275. package/actions/standard/inventory/inventory.d.ts +2 -2
  276. package/actions/standard/inventory/inventory.d.ts.map +1 -1
  277. package/actions/standard/inventory/inventory.js +20 -31
  278. package/actions/standard/inventory/inventory.js.map +1 -1
  279. package/actions/standard/listening/index.d.ts +2 -2
  280. package/actions/standard/listening/index.d.ts.map +1 -1
  281. package/actions/standard/listening/index.js +3 -3
  282. package/actions/standard/listening/index.js.map +1 -1
  283. package/actions/standard/listening/listening.d.ts +3 -3
  284. package/actions/standard/listening/listening.d.ts.map +1 -1
  285. package/actions/standard/listening/listening.js +20 -20
  286. package/actions/standard/listening/listening.js.map +1 -1
  287. package/actions/standard/lock-shared.d.ts +1 -1
  288. package/actions/standard/lock-shared.d.ts.map +1 -1
  289. package/actions/standard/lock-shared.js +10 -10
  290. package/actions/standard/lock-shared.js.map +1 -1
  291. package/actions/standard/locking/index.d.ts +2 -2
  292. package/actions/standard/locking/index.d.ts.map +1 -1
  293. package/actions/standard/locking/index.js +2 -2
  294. package/actions/standard/locking/index.js.map +1 -1
  295. package/actions/standard/locking/locking.d.ts +3 -3
  296. package/actions/standard/locking/locking.d.ts.map +1 -1
  297. package/actions/standard/locking/locking.js +37 -37
  298. package/actions/standard/locking/locking.js.map +1 -1
  299. package/actions/standard/looking/index.d.ts +4 -4
  300. package/actions/standard/looking/index.d.ts.map +1 -1
  301. package/actions/standard/looking/index.js +9 -9
  302. package/actions/standard/looking/index.js.map +1 -1
  303. package/actions/standard/looking/looking-data.d.ts +2 -2
  304. package/actions/standard/looking/looking-data.d.ts.map +1 -1
  305. package/actions/standard/looking/looking-data.js +15 -13
  306. package/actions/standard/looking/looking-data.js.map +1 -1
  307. package/actions/standard/looking/looking.d.ts +2 -2
  308. package/actions/standard/looking/looking.d.ts.map +1 -1
  309. package/actions/standard/looking/looking.js +15 -14
  310. package/actions/standard/looking/looking.js.map +1 -1
  311. package/actions/standard/looking/snippet-resolver.js +2 -2
  312. package/actions/standard/looking/snippet-resolver.js.map +1 -1
  313. package/actions/standard/lowering/index.d.ts +1 -1
  314. package/actions/standard/lowering/index.d.ts.map +1 -1
  315. package/actions/standard/lowering/index.js +2 -2
  316. package/actions/standard/lowering/index.js.map +1 -1
  317. package/actions/standard/lowering/lowering.d.ts +2 -2
  318. package/actions/standard/lowering/lowering.js +4 -4
  319. package/actions/standard/lowering/lowering.js.map +1 -1
  320. package/actions/standard/opening/index.d.ts +2 -2
  321. package/actions/standard/opening/index.d.ts.map +1 -1
  322. package/actions/standard/opening/index.js +2 -2
  323. package/actions/standard/opening/index.js.map +1 -1
  324. package/actions/standard/opening/opening-data.d.ts +2 -2
  325. package/actions/standard/opening/opening-data.d.ts.map +1 -1
  326. package/actions/standard/opening/opening.d.ts +3 -3
  327. package/actions/standard/opening/opening.d.ts.map +1 -1
  328. package/actions/standard/opening/opening.js +36 -38
  329. package/actions/standard/opening/opening.js.map +1 -1
  330. package/actions/standard/pulling/index.d.ts +2 -2
  331. package/actions/standard/pulling/index.d.ts.map +1 -1
  332. package/actions/standard/pulling/index.js +3 -3
  333. package/actions/standard/pulling/index.js.map +1 -1
  334. package/actions/standard/pulling/pulling.d.ts +3 -3
  335. package/actions/standard/pulling/pulling.d.ts.map +1 -1
  336. package/actions/standard/pulling/pulling.js +25 -25
  337. package/actions/standard/pulling/pulling.js.map +1 -1
  338. package/actions/standard/pushing/index.d.ts +2 -2
  339. package/actions/standard/pushing/index.d.ts.map +1 -1
  340. package/actions/standard/pushing/index.js +3 -3
  341. package/actions/standard/pushing/index.js.map +1 -1
  342. package/actions/standard/pushing/pushing-original.d.ts +2 -2
  343. package/actions/standard/pushing/pushing-original.d.ts.map +1 -1
  344. package/actions/standard/pushing/pushing-original.js +4 -4
  345. package/actions/standard/pushing/pushing-original.js.map +1 -1
  346. package/actions/standard/pushing/pushing.d.ts +3 -3
  347. package/actions/standard/pushing/pushing.d.ts.map +1 -1
  348. package/actions/standard/pushing/pushing.js +31 -31
  349. package/actions/standard/pushing/pushing.js.map +1 -1
  350. package/actions/standard/putting/index.d.ts +2 -2
  351. package/actions/standard/putting/index.d.ts.map +1 -1
  352. package/actions/standard/putting/index.js +3 -3
  353. package/actions/standard/putting/index.js.map +1 -1
  354. package/actions/standard/putting/putting-data.d.ts +1 -1
  355. package/actions/standard/putting/putting-data.d.ts.map +1 -1
  356. package/actions/standard/putting/putting-data.js +3 -3
  357. package/actions/standard/putting/putting-data.js.map +1 -1
  358. package/actions/standard/putting/putting.d.ts +3 -3
  359. package/actions/standard/putting/putting.d.ts.map +1 -1
  360. package/actions/standard/putting/putting.js +84 -84
  361. package/actions/standard/putting/putting.js.map +1 -1
  362. package/actions/standard/quitting/index.d.ts +2 -2
  363. package/actions/standard/quitting/index.d.ts.map +1 -1
  364. package/actions/standard/quitting/index.js +3 -3
  365. package/actions/standard/quitting/index.js.map +1 -1
  366. package/actions/standard/quitting/quitting.d.ts +2 -2
  367. package/actions/standard/quitting/quitting.d.ts.map +1 -1
  368. package/actions/standard/quitting/quitting.js +4 -3
  369. package/actions/standard/quitting/quitting.js.map +1 -1
  370. package/actions/standard/raising/index.d.ts +1 -1
  371. package/actions/standard/raising/index.d.ts.map +1 -1
  372. package/actions/standard/raising/index.js +2 -2
  373. package/actions/standard/raising/index.js.map +1 -1
  374. package/actions/standard/raising/raising.d.ts +2 -2
  375. package/actions/standard/raising/raising.js +4 -4
  376. package/actions/standard/raising/raising.js.map +1 -1
  377. package/actions/standard/reading/index.d.ts +2 -2
  378. package/actions/standard/reading/index.d.ts.map +1 -1
  379. package/actions/standard/reading/index.js +2 -2
  380. package/actions/standard/reading/index.js.map +1 -1
  381. package/actions/standard/reading/reading.d.ts +2 -2
  382. package/actions/standard/reading/reading.d.ts.map +1 -1
  383. package/actions/standard/reading/reading.js +25 -25
  384. package/actions/standard/reading/reading.js.map +1 -1
  385. package/actions/standard/removing/index.d.ts +1 -1
  386. package/actions/standard/removing/index.d.ts.map +1 -1
  387. package/actions/standard/removing/index.js +2 -2
  388. package/actions/standard/removing/index.js.map +1 -1
  389. package/actions/standard/removing/removing-data.d.ts +1 -1
  390. package/actions/standard/removing/removing-data.d.ts.map +1 -1
  391. package/actions/standard/removing/removing-data.js +4 -4
  392. package/actions/standard/removing/removing-data.js.map +1 -1
  393. package/actions/standard/removing/removing-events.d.ts +2 -2
  394. package/actions/standard/removing/removing-events.d.ts.map +1 -1
  395. package/actions/standard/removing/removing.d.ts +3 -3
  396. package/actions/standard/removing/removing.d.ts.map +1 -1
  397. package/actions/standard/removing/removing.js +83 -83
  398. package/actions/standard/removing/removing.js.map +1 -1
  399. package/actions/standard/restarting/index.d.ts +2 -2
  400. package/actions/standard/restarting/index.d.ts.map +1 -1
  401. package/actions/standard/restarting/index.js +3 -3
  402. package/actions/standard/restarting/index.js.map +1 -1
  403. package/actions/standard/restarting/restarting.d.ts +2 -2
  404. package/actions/standard/restarting/restarting.d.ts.map +1 -1
  405. package/actions/standard/restarting/restarting.js +4 -3
  406. package/actions/standard/restarting/restarting.js.map +1 -1
  407. package/actions/standard/restoring/index.d.ts +2 -2
  408. package/actions/standard/restoring/index.d.ts.map +1 -1
  409. package/actions/standard/restoring/index.js +3 -3
  410. package/actions/standard/restoring/index.js.map +1 -1
  411. package/actions/standard/restoring/restoring.d.ts +2 -2
  412. package/actions/standard/restoring/restoring.d.ts.map +1 -1
  413. package/actions/standard/restoring/restoring.js +4 -3
  414. package/actions/standard/restoring/restoring.js.map +1 -1
  415. package/actions/standard/saving/index.d.ts +2 -2
  416. package/actions/standard/saving/index.d.ts.map +1 -1
  417. package/actions/standard/saving/index.js +3 -3
  418. package/actions/standard/saving/index.js.map +1 -1
  419. package/actions/standard/saving/saving.d.ts +2 -2
  420. package/actions/standard/saving/saving.d.ts.map +1 -1
  421. package/actions/standard/saving/saving.js +4 -3
  422. package/actions/standard/saving/saving.js.map +1 -1
  423. package/actions/standard/scoring/index.d.ts +2 -2
  424. package/actions/standard/scoring/index.d.ts.map +1 -1
  425. package/actions/standard/scoring/index.js +2 -2
  426. package/actions/standard/scoring/index.js.map +1 -1
  427. package/actions/standard/scoring/scoring.d.ts +2 -2
  428. package/actions/standard/scoring/scoring.d.ts.map +1 -1
  429. package/actions/standard/scoring/scoring.js +4 -3
  430. package/actions/standard/scoring/scoring.js.map +1 -1
  431. package/actions/standard/searching/index.d.ts +2 -2
  432. package/actions/standard/searching/index.d.ts.map +1 -1
  433. package/actions/standard/searching/index.js +2 -2
  434. package/actions/standard/searching/index.js.map +1 -1
  435. package/actions/standard/searching/searching.d.ts +3 -3
  436. package/actions/standard/searching/searching.d.ts.map +1 -1
  437. package/actions/standard/searching/searching.js +29 -27
  438. package/actions/standard/searching/searching.js.map +1 -1
  439. package/actions/standard/searching-helpers.d.ts +1 -1
  440. package/actions/standard/searching-helpers.d.ts.map +1 -1
  441. package/actions/standard/searching-helpers.js +35 -23
  442. package/actions/standard/searching-helpers.js.map +1 -1
  443. package/actions/standard/showing/index.d.ts +2 -2
  444. package/actions/standard/showing/index.d.ts.map +1 -1
  445. package/actions/standard/showing/index.js +3 -3
  446. package/actions/standard/showing/index.js.map +1 -1
  447. package/actions/standard/showing/showing.d.ts +3 -3
  448. package/actions/standard/showing/showing.d.ts.map +1 -1
  449. package/actions/standard/showing/showing.js +28 -28
  450. package/actions/standard/showing/showing.js.map +1 -1
  451. package/actions/standard/sleeping/index.d.ts +2 -2
  452. package/actions/standard/sleeping/index.d.ts.map +1 -1
  453. package/actions/standard/sleeping/index.js +2 -2
  454. package/actions/standard/sleeping/index.js.map +1 -1
  455. package/actions/standard/sleeping/sleeping.d.ts +2 -2
  456. package/actions/standard/sleeping/sleeping.d.ts.map +1 -1
  457. package/actions/standard/sleeping/sleeping.js +4 -3
  458. package/actions/standard/sleeping/sleeping.js.map +1 -1
  459. package/actions/standard/smelling/index.d.ts +2 -2
  460. package/actions/standard/smelling/index.d.ts.map +1 -1
  461. package/actions/standard/smelling/index.js +3 -3
  462. package/actions/standard/smelling/index.js.map +1 -1
  463. package/actions/standard/smelling/smelling.d.ts +3 -3
  464. package/actions/standard/smelling/smelling.d.ts.map +1 -1
  465. package/actions/standard/smelling/smelling.js +21 -21
  466. package/actions/standard/smelling/smelling.js.map +1 -1
  467. package/actions/standard/switching-shared.d.ts +1 -1
  468. package/actions/standard/switching-shared.d.ts.map +1 -1
  469. package/actions/standard/switching_off/index.d.ts +2 -2
  470. package/actions/standard/switching_off/index.d.ts.map +1 -1
  471. package/actions/standard/switching_off/index.js +2 -2
  472. package/actions/standard/switching_off/index.js.map +1 -1
  473. package/actions/standard/switching_off/switching_off.d.ts +3 -3
  474. package/actions/standard/switching_off/switching_off.d.ts.map +1 -1
  475. package/actions/standard/switching_off/switching_off.js +29 -29
  476. package/actions/standard/switching_off/switching_off.js.map +1 -1
  477. package/actions/standard/switching_on/index.d.ts +2 -2
  478. package/actions/standard/switching_on/index.d.ts.map +1 -1
  479. package/actions/standard/switching_on/index.js +2 -2
  480. package/actions/standard/switching_on/index.js.map +1 -1
  481. package/actions/standard/switching_on/switching_on.d.ts +3 -3
  482. package/actions/standard/switching_on/switching_on.d.ts.map +1 -1
  483. package/actions/standard/switching_on/switching_on.js +34 -34
  484. package/actions/standard/switching_on/switching_on.js.map +1 -1
  485. package/actions/standard/taking/index.d.ts +1 -1
  486. package/actions/standard/taking/index.d.ts.map +1 -1
  487. package/actions/standard/taking/index.js +2 -2
  488. package/actions/standard/taking/index.js.map +1 -1
  489. package/actions/standard/taking/taking-data.d.ts +1 -1
  490. package/actions/standard/taking/taking-data.d.ts.map +1 -1
  491. package/actions/standard/taking/taking-data.js +5 -5
  492. package/actions/standard/taking/taking-data.js.map +1 -1
  493. package/actions/standard/taking/taking.d.ts +3 -3
  494. package/actions/standard/taking/taking.d.ts.map +1 -1
  495. package/actions/standard/taking/taking.js +69 -75
  496. package/actions/standard/taking/taking.js.map +1 -1
  497. package/actions/standard/taking_off/index.d.ts +1 -1
  498. package/actions/standard/taking_off/index.d.ts.map +1 -1
  499. package/actions/standard/taking_off/index.js +2 -2
  500. package/actions/standard/taking_off/index.js.map +1 -1
  501. package/actions/standard/taking_off/taking-off.d.ts +3 -3
  502. package/actions/standard/taking_off/taking-off.d.ts.map +1 -1
  503. package/actions/standard/taking_off/taking-off.js +34 -34
  504. package/actions/standard/taking_off/taking-off.js.map +1 -1
  505. package/actions/standard/talking/index.d.ts +2 -2
  506. package/actions/standard/talking/index.d.ts.map +1 -1
  507. package/actions/standard/talking/index.js +3 -3
  508. package/actions/standard/talking/index.js.map +1 -1
  509. package/actions/standard/talking/talking.d.ts +3 -3
  510. package/actions/standard/talking/talking.d.ts.map +1 -1
  511. package/actions/standard/talking/talking.js +22 -26
  512. package/actions/standard/talking/talking.js.map +1 -1
  513. package/actions/standard/telling/index.d.ts +1 -1
  514. package/actions/standard/telling/index.d.ts.map +1 -1
  515. package/actions/standard/telling/index.js +3 -3
  516. package/actions/standard/telling/index.js.map +1 -1
  517. package/actions/standard/telling/telling.d.ts +3 -3
  518. package/actions/standard/telling/telling.d.ts.map +1 -1
  519. package/actions/standard/telling/telling.js +35 -26
  520. package/actions/standard/telling/telling.js.map +1 -1
  521. package/actions/standard/throwing/index.d.ts +1 -1
  522. package/actions/standard/throwing/index.d.ts.map +1 -1
  523. package/actions/standard/throwing/index.js +2 -2
  524. package/actions/standard/throwing/index.js.map +1 -1
  525. package/actions/standard/throwing/throwing.d.ts +3 -3
  526. package/actions/standard/throwing/throwing.d.ts.map +1 -1
  527. package/actions/standard/throwing/throwing.js +40 -40
  528. package/actions/standard/throwing/throwing.js.map +1 -1
  529. package/actions/standard/tool-shared.d.ts +1 -1
  530. package/actions/standard/tool-shared.d.ts.map +1 -1
  531. package/actions/standard/tool-shared.js +5 -5
  532. package/actions/standard/tool-shared.js.map +1 -1
  533. package/actions/standard/touching/index.d.ts +2 -2
  534. package/actions/standard/touching/index.d.ts.map +1 -1
  535. package/actions/standard/touching/index.js +3 -3
  536. package/actions/standard/touching/index.js.map +1 -1
  537. package/actions/standard/touching/touching.d.ts +3 -3
  538. package/actions/standard/touching/touching.d.ts.map +1 -1
  539. package/actions/standard/touching/touching.js +22 -22
  540. package/actions/standard/touching/touching.js.map +1 -1
  541. package/actions/standard/turning/index.d.ts +4 -2
  542. package/actions/standard/turning/index.d.ts.map +1 -1
  543. package/actions/standard/turning/index.js +8 -4
  544. package/actions/standard/turning/index.js.map +1 -1
  545. package/actions/standard/turning/turning-messages.d.ts +14 -0
  546. package/actions/standard/turning/turning-messages.d.ts.map +1 -0
  547. package/actions/standard/turning/turning-messages.js +18 -0
  548. package/actions/standard/turning/turning-messages.js.map +1 -0
  549. package/actions/standard/turning/turning.d.ts +29 -6
  550. package/actions/standard/turning/turning.d.ts.map +1 -1
  551. package/actions/standard/turning/turning.js +184 -12
  552. package/actions/standard/turning/turning.js.map +1 -1
  553. package/actions/standard/undoing/index.d.ts +2 -2
  554. package/actions/standard/undoing/index.d.ts.map +1 -1
  555. package/actions/standard/undoing/index.js +3 -3
  556. package/actions/standard/undoing/index.js.map +1 -1
  557. package/actions/standard/undoing/undoing.d.ts +2 -2
  558. package/actions/standard/undoing/undoing.d.ts.map +1 -1
  559. package/actions/standard/undoing/undoing.js +2 -2
  560. package/actions/standard/undoing/undoing.js.map +1 -1
  561. package/actions/standard/unlocking/index.d.ts +2 -2
  562. package/actions/standard/unlocking/index.d.ts.map +1 -1
  563. package/actions/standard/unlocking/index.js +2 -2
  564. package/actions/standard/unlocking/index.js.map +1 -1
  565. package/actions/standard/unlocking/unlocking.d.ts +3 -3
  566. package/actions/standard/unlocking/unlocking.d.ts.map +1 -1
  567. package/actions/standard/unlocking/unlocking.js +35 -35
  568. package/actions/standard/unlocking/unlocking.js.map +1 -1
  569. package/actions/standard/version/engine-version.d.ts +6 -0
  570. package/actions/standard/version/engine-version.d.ts.map +1 -0
  571. package/actions/standard/version/engine-version.js +9 -0
  572. package/actions/standard/version/engine-version.js.map +1 -0
  573. package/actions/standard/version/index.d.ts +2 -2
  574. package/actions/standard/version/index.d.ts.map +1 -1
  575. package/actions/standard/version/index.js +3 -3
  576. package/actions/standard/version/index.js.map +1 -1
  577. package/actions/standard/version/version.d.ts +4 -4
  578. package/actions/standard/version/version.d.ts.map +1 -1
  579. package/actions/standard/version/version.js +10 -6
  580. package/actions/standard/version/version.js.map +1 -1
  581. package/actions/standard/waiting/index.d.ts +2 -2
  582. package/actions/standard/waiting/index.d.ts.map +1 -1
  583. package/actions/standard/waiting/index.js +2 -2
  584. package/actions/standard/waiting/index.js.map +1 -1
  585. package/actions/standard/waiting/waiting.d.ts +2 -2
  586. package/actions/standard/waiting/waiting.d.ts.map +1 -1
  587. package/actions/standard/waiting/waiting.js +4 -3
  588. package/actions/standard/waiting/waiting.js.map +1 -1
  589. package/actions/standard/wearable-shared.d.ts +1 -1
  590. package/actions/standard/wearable-shared.d.ts.map +1 -1
  591. package/actions/standard/wearable-shared.js +2 -2
  592. package/actions/standard/wearable-shared.js.map +1 -1
  593. package/actions/standard/wearing/index.d.ts +1 -1
  594. package/actions/standard/wearing/index.d.ts.map +1 -1
  595. package/actions/standard/wearing/index.js +2 -2
  596. package/actions/standard/wearing/index.js.map +1 -1
  597. package/actions/standard/wearing/wearing.d.ts +3 -3
  598. package/actions/standard/wearing/wearing.d.ts.map +1 -1
  599. package/actions/standard/wearing/wearing.js +31 -31
  600. package/actions/standard/wearing/wearing.js.map +1 -1
  601. package/capabilities/index.d.ts +6 -6
  602. package/capabilities/index.d.ts.map +1 -1
  603. package/capabilities/index.js +21 -21
  604. package/capabilities/index.js.map +1 -1
  605. package/chains/index.d.ts +2 -2
  606. package/chains/index.d.ts.map +1 -1
  607. package/chains/index.js +7 -7
  608. package/chains/index.js.map +1 -1
  609. package/channels/index.d.ts +5 -5
  610. package/channels/index.d.ts.map +1 -1
  611. package/channels/index.js +43 -43
  612. package/channels/index.js.map +1 -1
  613. package/channels/registry.js +6 -6
  614. package/channels/registry.js.map +1 -1
  615. package/channels/standard.js +9 -9
  616. package/channels/standard.js.map +1 -1
  617. package/combat/index.d.ts +1 -1
  618. package/combat/index.d.ts.map +1 -1
  619. package/combat/index.js +2 -2
  620. package/combat/index.js.map +1 -1
  621. package/death/index.d.ts +4 -4
  622. package/death/index.d.ts.map +1 -1
  623. package/death/index.js +11 -11
  624. package/death/index.js.map +1 -1
  625. package/death/kill-player.js +2 -2
  626. package/death/kill-player.js.map +1 -1
  627. package/events/event-registry.d.ts +34 -34
  628. package/events/event-registry.d.ts.map +1 -1
  629. package/events/index.d.ts +4 -4
  630. package/events/index.d.ts.map +1 -1
  631. package/events/index.js +4 -4
  632. package/events/index.js.map +1 -1
  633. package/helpers/index.d.ts +1 -1
  634. package/helpers/index.d.ts.map +1 -1
  635. package/helpers/index.js +1 -1
  636. package/helpers/index.js.map +1 -1
  637. package/helpers/multi-object-handler.d.ts +1 -1
  638. package/helpers/multi-object-handler.d.ts.map +1 -1
  639. package/helpers/multi-object-handler.js +8 -5
  640. package/helpers/multi-object-handler.js.map +1 -1
  641. package/index.d.ts +16 -16
  642. package/index.d.ts.map +1 -1
  643. package/index.js +16 -16
  644. package/index.js.map +1 -1
  645. package/inference/implicit-inference.d.ts +1 -1
  646. package/inference/implicit-inference.d.ts.map +1 -1
  647. package/inference/index.d.ts +1 -1
  648. package/inference/index.d.ts.map +1 -1
  649. package/inference/index.js +4 -4
  650. package/inference/index.js.map +1 -1
  651. package/npc/behaviors.d.ts +1 -1
  652. package/npc/behaviors.d.ts.map +1 -1
  653. package/npc/behaviors.js +11 -11
  654. package/npc/behaviors.js.map +1 -1
  655. package/npc/character-observer.js +6 -6
  656. package/npc/character-observer.js.map +1 -1
  657. package/npc/index.d.ts +7 -7
  658. package/npc/index.d.ts.map +1 -1
  659. package/npc/index.js +23 -23
  660. package/npc/index.js.map +1 -1
  661. package/npc/lucidity-decay.js +2 -2
  662. package/npc/lucidity-decay.js.map +1 -1
  663. package/npc/npc-service.d.ts +1 -1
  664. package/npc/npc-service.d.ts.map +1 -1
  665. package/npc/npc-service.js +14 -14
  666. package/npc/npc-service.js.map +1 -1
  667. package/package.json +7 -7
  668. package/query-handlers/index.d.ts +2 -2
  669. package/query-handlers/index.d.ts.map +1 -1
  670. package/query-handlers/index.js +3 -3
  671. package/query-handlers/index.js.map +1 -1
  672. package/scope/index.d.ts +3 -3
  673. package/scope/index.d.ts.map +1 -1
  674. package/scope/index.js +3 -3
  675. package/scope/index.js.map +1 -1
  676. package/scope/scope-resolver.d.ts +1 -1
  677. package/scope/scope-resolver.d.ts.map +1 -1
  678. package/scope/scope-resolver.js +13 -15
  679. package/scope/scope-resolver.js.map +1 -1
  680. package/scope/witness-system.d.ts +1 -1
  681. package/scope/witness-system.d.ts.map +1 -1
  682. package/scope/witness-system.js +16 -16
  683. package/scope/witness-system.js.map +1 -1
  684. package/services/index.d.ts +1 -1
  685. package/services/index.d.ts.map +1 -1
  686. package/services/index.js +2 -2
  687. package/services/index.js.map +1 -1
  688. package/utils/index.d.ts +1 -1
  689. package/utils/index.d.ts.map +1 -1
  690. package/utils/index.js +2 -2
  691. package/utils/index.js.map +1 -1
  692. package/utils/noun-phrase.d.ts.map +1 -1
  693. package/utils/noun-phrase.js +5 -0
  694. package/utils/noun-phrase.js.map +1 -1
  695. package/validation/command-validator.d.ts +68 -16
  696. package/validation/command-validator.d.ts.map +1 -1
  697. package/validation/command-validator.js +275 -211
  698. package/validation/command-validator.js.map +1 -1
  699. package/validation/index.d.ts +3 -3
  700. package/validation/index.d.ts.map +1 -1
  701. package/validation/index.js +2 -2
  702. package/validation/index.js.map +1 -1
  703. package/validation/types.d.ts +1 -1
  704. package/validation/types.d.ts.map +1 -1
  705. package/vocabulary/index.d.ts +1 -1
  706. package/vocabulary/index.d.ts.map +1 -1
  707. package/vocabulary/index.js +1 -1
  708. package/vocabulary/index.js.map +1 -1
  709. package/vocabulary/standard-english.d.ts +1 -1
  710. package/vocabulary/standard-english.d.ts.map +1 -1
  711. package/vocabulary/standard-english.js +5 -5
  712. package/vocabulary/standard-english.js.map +1 -1
@@ -8,8 +8,17 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.CommandValidator = void 0;
10
10
  const world_model_1 = require("@sharpee/world-model");
11
- const types_1 = require("../scope/types");
12
- const scope_resolver_1 = require("../scope/scope-resolver");
11
+ const types_js_1 = require("../scope/types.js");
12
+ const scope_resolver_js_1 = require("../scope/scope-resolver.js");
13
+ /**
14
+ * Match tiers for name resolution (ADR-231 D3, PIN 2).
15
+ * EXACT (query text equals full name/alias/type) outranks WORDS (every
16
+ * query content word matches the entity's vocabulary).
17
+ */
18
+ const MATCH_TIER_EXACT = 3;
19
+ const MATCH_TIER_WORDS = 2;
20
+ /** Leading articles stripped from query text before matching (D3 defect fix). */
21
+ const QUERY_ARTICLES = new Set(['the', 'a', 'an']);
13
22
  /**
14
23
  * Enhanced command validator with full entity resolution
15
24
  */
@@ -20,10 +29,12 @@ class CommandValidator {
20
29
  systemEvents;
21
30
  /** Current action ID being validated (for disambiguation scoring) */
22
31
  currentActionId;
32
+ /** The current action's preferredScope, staged for resolveAmbiguity. */
33
+ currentPreferredScope;
23
34
  constructor(world, actionRegistry, scopeResolver) {
24
35
  this.world = world;
25
36
  this.actionRegistry = actionRegistry;
26
- this.scopeResolver = scopeResolver || new scope_resolver_1.StandardScopeResolver(world);
37
+ this.scopeResolver = scopeResolver || new scope_resolver_js_1.StandardScopeResolver(world);
27
38
  }
28
39
  /**
29
40
  * Set system event source for debug events
@@ -59,8 +70,9 @@ class CommandValidator {
59
70
  }
60
71
  };
61
72
  }
62
- // Store current action ID for disambiguation scoring
73
+ // Store current action ID + scope preference for disambiguation scoring
63
74
  this.currentActionId = actionHandler.id;
75
+ this.currentPreferredScope = this.getActionMetadata(actionHandler).preferredScope;
64
76
  // 2. Resolve direct object if present in parsed command
65
77
  let directObject;
66
78
  if (command.structure?.directObject) {
@@ -75,7 +87,7 @@ class CommandValidator {
75
87
  else {
76
88
  // Normal single-entity resolution
77
89
  const metadata = this.getActionMetadata(actionHandler);
78
- const scope = metadata.directObjectScope || types_1.ScopeLevel.VISIBLE;
90
+ const scope = metadata.directObjectScope || types_js_1.ScopeLevel.VISIBLE;
79
91
  const resolved = this.resolveEntity(nounPhrase, 'direct', scope, command);
80
92
  if (!resolved.success) {
81
93
  return resolved;
@@ -88,7 +100,7 @@ class CommandValidator {
88
100
  let indirectObject;
89
101
  if (command.structure?.indirectObject) {
90
102
  const metadata = this.getActionMetadata(actionHandler);
91
- const scope = metadata.indirectObjectScope || types_1.ScopeLevel.VISIBLE;
103
+ const scope = metadata.indirectObjectScope || types_js_1.ScopeLevel.VISIBLE;
92
104
  const resolved = this.resolveEntity(command.structure.indirectObject, 'indirect', scope, command);
93
105
  if (!resolved.success) {
94
106
  return resolved;
@@ -100,12 +112,17 @@ class CommandValidator {
100
112
  let instrument;
101
113
  if (command.instrument) {
102
114
  // Instruments are typically carried or reachable
103
- const resolved = this.resolveEntity(command.instrument, 'instrument', types_1.ScopeLevel.REACHABLE, command);
115
+ const resolved = this.resolveEntity(command.instrument, 'instrument', types_js_1.ScopeLevel.REACHABLE, command);
104
116
  if (!resolved.success) {
105
117
  return resolved;
106
118
  }
107
119
  instrument = resolved.value;
108
120
  }
121
+ // 3c. Resolve topic if present (ADR-231 D4): entity-first with text
122
+ // fallback. Quiet resolution only — a topic NEVER produces
123
+ // ENTITY_NOT_FOUND or a disambiguation prompt; on miss or tie the
124
+ // verbatim text flows through with entity undefined.
125
+ const topic = command.topic ? this.resolveTopic(command.topic.text) : undefined;
109
126
  // 4. Check scope constraints based on action metadata
110
127
  const metadata = this.getActionMetadata(actionHandler);
111
128
  // Check direct object scope
@@ -196,6 +213,7 @@ class CommandValidator {
196
213
  directObject,
197
214
  indirectObject,
198
215
  instrument,
216
+ topic,
199
217
  metadata: {
200
218
  validationTime,
201
219
  warnings: warnings.length > 0 ? warnings : undefined
@@ -235,6 +253,7 @@ class CommandValidator {
235
253
  };
236
254
  }
237
255
  this.currentActionId = actionHandler.id;
256
+ this.currentPreferredScope = this.getActionMetadata(actionHandler).preferredScope;
238
257
  // 2. Resolve direct object - use selection if provided
239
258
  let directObject;
240
259
  if (command.structure?.directObject) {
@@ -269,7 +288,7 @@ class CommandValidator {
269
288
  else {
270
289
  // Normal resolution
271
290
  const metadata = this.getActionMetadata(actionHandler);
272
- const scope = metadata.directObjectScope || types_1.ScopeLevel.VISIBLE;
291
+ const scope = metadata.directObjectScope || types_js_1.ScopeLevel.VISIBLE;
273
292
  const resolved = this.resolveEntity(nounPhrase, 'direct', scope, command);
274
293
  if (!resolved.success) {
275
294
  return resolved;
@@ -304,7 +323,7 @@ class CommandValidator {
304
323
  }
305
324
  else {
306
325
  const metadata = this.getActionMetadata(actionHandler);
307
- const scope = metadata.indirectObjectScope || types_1.ScopeLevel.VISIBLE;
326
+ const scope = metadata.indirectObjectScope || types_js_1.ScopeLevel.VISIBLE;
308
327
  const resolved = this.resolveEntity(command.structure.indirectObject, 'indirect', scope, command);
309
328
  if (!resolved.success) {
310
329
  return resolved;
@@ -338,13 +357,16 @@ class CommandValidator {
338
357
  };
339
358
  }
340
359
  else {
341
- const resolved = this.resolveEntity(command.instrument, 'instrument', types_1.ScopeLevel.REACHABLE, command);
360
+ const resolved = this.resolveEntity(command.instrument, 'instrument', types_js_1.ScopeLevel.REACHABLE, command);
342
361
  if (!resolved.success) {
343
362
  return resolved;
344
363
  }
345
364
  instrument = resolved.value;
346
365
  }
347
366
  }
367
+ // 3c. Resolve topic if present (ADR-231 D4) — same quiet entity-first
368
+ // pass as validate(); topics are never disambiguation slots.
369
+ const topic = command.topic ? this.resolveTopic(command.topic.text) : undefined;
348
370
  // 4. Check scope constraints based on action metadata
349
371
  const metadata = this.getActionMetadata(actionHandler);
350
372
  if (directObject && metadata.directObjectScope) {
@@ -432,6 +454,7 @@ class CommandValidator {
432
454
  directObject,
433
455
  indirectObject,
434
456
  instrument,
457
+ topic,
435
458
  metadata: {
436
459
  validationTime,
437
460
  warnings: warnings.length > 0 ? warnings : undefined
@@ -474,94 +497,34 @@ class CommandValidator {
474
497
  }
475
498
  // Entity ID was set but entity not found - fall through to error
476
499
  }
477
- // Maximal munch entity resolution (ISSUE-057):
478
- // Try full text first (e.g., "brass lantern"), fall back to head noun (e.g., "lantern").
479
- // The parser's slot consumer already builds multi-word phrases correctly;
480
- // this ensures the validator uses them for entity lookup.
481
- const fullText = ref.text;
482
- const headNoun = ref.head || ref.text;
483
- let candidates = [];
484
- let searchTerm = fullText;
485
- // For AWARE scope (hearing/smelling), we need to search more broadly
486
- // because entities might be in other rooms
487
- const needsBroadSearch = requiredScope === types_1.ScopeLevel.AWARE;
500
+ // Tiered word-level candidate search (ADR-231 D3, PIN 2): a candidate
501
+ // is any entity the noun phrase matches at EXACT tier (full text equals
502
+ // name/alias/type) or WORDS tier (every query content word matches the
503
+ // entity's name/alias/adjective vocabulary). This replaces the old
504
+ // exact-match cascade (full text → head noun → adjective fallback) —
505
+ // "x key" now finds the brass key with zero authoring, while a query
506
+ // word matching nothing disqualifies ("x brass sword" never resolves
507
+ // the brass key).
508
+ let candidates;
509
+ // For AWARE scope (hearing/smelling), search all entities except
510
+ // rooms/player because entities might be in other rooms; scope
511
+ // filtering below handles perceivability.
512
+ const needsBroadSearch = requiredScope === types_js_1.ScopeLevel.AWARE;
488
513
  if (needsBroadSearch) {
489
- // For audible/detectable, search all entities (except rooms/player)
490
- // and let scope filtering handle visibility
491
- candidates = this.world.getAllEntities().filter(e => e.type !== 'room' && e.id !== this.world.getPlayer()?.id);
492
- // Filter candidates by name/type/synonym match — try full text first, then head noun
493
- candidates = candidates.filter(entity => {
494
- const name = this.getEntityName(entity).toLowerCase();
495
- const type = entity.type?.toLowerCase() || '';
496
- const synonyms = this.getEntitySynonyms(entity).map(s => s.toLowerCase());
497
- const fullTextLower = fullText.toLowerCase();
498
- return name === fullTextLower || type === fullTextLower || synonyms.includes(fullTextLower);
499
- });
500
- // Fall back to head noun if full text found nothing
501
- if (candidates.length === 0 && headNoun !== fullText) {
502
- searchTerm = headNoun;
503
- candidates = this.world.getAllEntities().filter(e => e.type !== 'room' && e.id !== this.world.getPlayer()?.id);
504
- candidates = candidates.filter(entity => {
505
- const name = this.getEntityName(entity).toLowerCase();
506
- const type = entity.type?.toLowerCase() || '';
507
- const synonyms = this.getEntitySynonyms(entity).map(s => s.toLowerCase());
508
- const headLower = headNoun.toLowerCase();
509
- return name === headLower || type === headLower || synonyms.includes(headLower);
510
- });
511
- }
514
+ candidates = this.world.getAllEntities().filter(e => e.type !== 'room' &&
515
+ e.id !== this.world.getPlayer()?.id &&
516
+ this.matchEntityName(e, ref) !== null);
512
517
  }
513
518
  else {
514
- // Try full text first (maximal munch)
515
- candidates = this.findCandidatesByTerm(fullText);
516
- this.emitDebugEvent('entity_search', command, {
517
- searchTerm: fullText,
518
- fullTextCandidates: candidates.length,
519
- strategy: 'maximal_munch_full_text'
520
- });
521
- // Fall back to head noun if full text found nothing and they differ
522
- if (candidates.length === 0 && headNoun !== fullText) {
523
- searchTerm = headNoun;
524
- candidates = this.findCandidatesByTerm(headNoun);
525
- this.emitDebugEvent('entity_search', command, {
526
- searchTerm: headNoun,
527
- headNounCandidates: candidates.length,
528
- strategy: 'maximal_munch_head_fallback'
529
- });
530
- }
531
- // Fallback: If no candidates found by name/type/synonym, try adjective search
532
- // This handles "press yellow" when yellow is an adjective on "yellow button"
533
- if (candidates.length === 0) {
534
- const byAdjective = this.getEntitiesByAdjective(searchTerm);
535
- if (byAdjective.length > 0) {
536
- candidates = byAdjective;
537
- this.emitDebugEvent('entity_search', command, {
538
- searchTerm,
539
- byAdjective: byAdjective.length,
540
- fallback: true
541
- });
542
- }
543
- }
519
+ candidates = this.findCandidates(ref);
544
520
  }
521
+ this.emitDebugEvent('entity_search', command, {
522
+ searchTerm: ref.text,
523
+ candidateCount: candidates.length,
524
+ strategy: 'tiered_word_match'
525
+ });
545
526
  // Now filter by scope
546
- let entitiesInScope = this.filterByScope(candidates, requiredScope);
547
- // Second adjective fallback: if scope filtering eliminated all candidates,
548
- // try adjective search and filter those by scope
549
- if (entitiesInScope.length === 0 && candidates.length > 0) {
550
- const byAdjective = this.getEntitiesByAdjective(searchTerm);
551
- if (byAdjective.length > 0) {
552
- const adjectiveInScope = this.filterByScope(byAdjective, requiredScope);
553
- if (adjectiveInScope.length > 0) {
554
- candidates = byAdjective;
555
- entitiesInScope = adjectiveInScope;
556
- this.emitDebugEvent('entity_search', command, {
557
- searchTerm,
558
- byAdjective: byAdjective.length,
559
- adjectiveInScope: adjectiveInScope.length,
560
- fallbackAfterScope: true
561
- });
562
- }
563
- }
564
- }
527
+ const entitiesInScope = this.filterByScope(candidates, requiredScope);
565
528
  // Get detailed scope information for all candidates
566
529
  const candidateScopes = [];
567
530
  const player = this.world.getPlayer();
@@ -597,8 +560,11 @@ class CommandValidator {
597
560
  });
598
561
  // Score only the entities that are in scope
599
562
  const scoredMatches = this.scoreEntities(entitiesInScope, ref);
600
- // Filter out zero-score matches
601
- const viableMatches = scoredMatches.filter(m => m.score > 0);
563
+ // PIN 2 ranking: keep only the dominant (tier, wordsMatched) group.
564
+ // Higher tier wins outright; within a tier, more matched words win
565
+ // outright. Only true ties flow into the disambiguation path below;
566
+ // a single survivor auto-resolves.
567
+ const viableMatches = this.dominantMatches(scoredMatches);
602
568
  if (viableMatches.length === 0) {
603
569
  this.emitDebugEvent('validation_error', command, {
604
570
  errorType: 'NO_MATCHES',
@@ -720,71 +686,169 @@ class CommandValidator {
720
686
  };
721
687
  }
722
688
  /**
723
- * Find candidate entities by name, type, or synonym for a given search term.
724
- * Returns deduplicated results.
689
+ * Resolve a topic's text against VISIBLE scope, quietly (ADR-231 D4).
690
+ *
691
+ * Entity-first with text fallback: reuses the D3 tiered matcher, but a
692
+ * topic is NEVER an entity slot — no ENTITY_NOT_FOUND, no scope
693
+ * rejection, no disambiguation prompt. Exactly one dominant in-scope
694
+ * match carries its EntityId (interceptors and future conversation
695
+ * systems key on it); a miss or a tie falls back to the verbatim text.
696
+ *
697
+ * @param text Verbatim topic text as typed (articles preserved)
698
+ * @returns The validated topic — `entity` set only on a unique match
725
699
  */
726
- findCandidatesByTerm(term) {
727
- const byName = this.getEntitiesByName(term);
728
- const byType = this.getEntitiesByType(term);
729
- const bySynonym = this.getEntitiesBySynonym(term);
730
- const candidates = [...byName, ...byType, ...bySynonym];
731
- // Remove duplicates
732
- return candidates.filter((e, i, arr) => arr.findIndex(x => x.id === e.id) === i);
700
+ resolveTopic(text) {
701
+ const words = this.stripLeadingArticles(text.toLowerCase().trim()).split(/\s+/);
702
+ const ref = {
703
+ tokens: [],
704
+ text,
705
+ head: words[words.length - 1] || text,
706
+ modifiers: [],
707
+ articles: [],
708
+ determiners: [],
709
+ candidates: [text]
710
+ };
711
+ const candidates = this.findCandidates(ref);
712
+ const inScope = this.filterByScope(candidates, types_js_1.ScopeLevel.VISIBLE);
713
+ const viable = this.dominantMatches(this.scoreEntities(inScope, ref));
714
+ if (viable.length === 1) {
715
+ return { text, entity: viable[0].entity.id };
716
+ }
717
+ return { text };
733
718
  }
734
719
  /**
735
- * Get entities by exact name match
720
+ * Find candidate entities the noun phrase matches at any tier
721
+ * (ADR-231 D3). Rooms are skipped; the player IS resolvable here: a
722
+ * player with an IdentityTrait ("yourself", aliases me/self/myself)
723
+ * must match "examine me", "x yourself", etc. (ISSUE #154).
736
724
  */
737
- getEntitiesByName(name) {
738
- // For now, use findWhere until WorldModel has a name index
739
- const normalizedName = name.toLowerCase();
725
+ findCandidates(ref) {
740
726
  return this.world.findWhere(entity => {
741
- // Skip rooms. The player IS resolvable here: a player with an
742
- // IdentityTrait ("yourself", aliases me/self/myself) must match
743
- // "examine me", "x yourself", etc. (ISSUE #154).
744
727
  if (entity.type === 'room') {
745
728
  return false;
746
729
  }
747
- // Check exact name match
748
- const entityName = this.getEntityName(entity).toLowerCase();
749
- return entityName === normalizedName;
730
+ return this.matchEntityName(entity, ref) !== null;
750
731
  });
751
732
  }
752
733
  /**
753
- * Get entities by type
734
+ * Match a noun phrase against one entity's naming surface (ADR-231 D3,
735
+ * PIN 2's tiered model).
736
+ *
737
+ * Tier EXACT: the query text — tried with its leading articles restored
738
+ * first (so proper names beginning with an article-like word survive),
739
+ * then as parsed, then article-stripped — equals the full name, a full
740
+ * alias, or the entity type, case-insensitively.
741
+ *
742
+ * Tier WORDS: EVERY query content word (stopwords dropped by
743
+ * `deriveNameVocabulary`) matches a word of the entity's vocabulary
744
+ * (name content words + alias content words + authored adjectives).
745
+ * Any query word matching nothing DISQUALIFIES the candidate:
746
+ * "x brass sword" never resolves to the brass key.
747
+ *
748
+ * @returns The tier and matched-word count, or null when neither
749
+ * tier matches.
754
750
  */
755
- getEntitiesByType(type) {
756
- const normalizedType = type.toLowerCase();
757
- return this.world.findByType(normalizedType);
751
+ matchEntityName(entity, ref) {
752
+ const rawText = ref.text?.toLowerCase().trim() || '';
753
+ if (!rawText) {
754
+ return null;
755
+ }
756
+ // Full-text-first: reconstruct the original query (leading articles the
757
+ // parser split off) before trying the stripped forms.
758
+ const articles = (ref.articles || []).map(a => a.toLowerCase());
759
+ const queries = [];
760
+ if (articles.length > 0) {
761
+ queries.push(`${articles.join(' ')} ${rawText}`);
762
+ }
763
+ queries.push(rawText);
764
+ const stripped = this.stripLeadingArticles(rawText);
765
+ if (!queries.includes(stripped)) {
766
+ queries.push(stripped);
767
+ }
768
+ const name = this.getEntityName(entity).toLowerCase();
769
+ const aliases = this.getEntitySynonyms(entity).map(s => s.toLowerCase());
770
+ const wordsMatchedFor = (q) => Math.max(1, (0, world_model_1.deriveNameVocabulary)(q).length);
771
+ // Tier EXACT — full text equals name, alias, or type
772
+ for (const query of queries) {
773
+ if (name === query) {
774
+ return {
775
+ tier: MATCH_TIER_EXACT,
776
+ wordsMatched: wordsMatchedFor(query),
777
+ reasons: ['exact_name_match']
778
+ };
779
+ }
780
+ if (aliases.includes(query)) {
781
+ // getEntitySynonyms includes the entity type, so type equality
782
+ // lands here too (preserves pre-D3 type matching).
783
+ return {
784
+ tier: MATCH_TIER_EXACT,
785
+ wordsMatched: wordsMatchedFor(query),
786
+ reasons: ['exact_synonym_match']
787
+ };
788
+ }
789
+ }
790
+ // Tier WORDS — every query content word must match the vocabulary
791
+ const queryWords = (0, world_model_1.deriveNameVocabulary)(stripped);
792
+ if (queryWords.length === 0) {
793
+ return null;
794
+ }
795
+ const vocabulary = this.getEntityVocabulary(entity);
796
+ for (const word of queryWords) {
797
+ if (!vocabulary.has(word)) {
798
+ return null; // disqualified — a query word matched nothing
799
+ }
800
+ }
801
+ return {
802
+ tier: MATCH_TIER_WORDS,
803
+ wordsMatched: queryWords.length,
804
+ reasons: queryWords.map(w => `word_match_${w}`)
805
+ };
758
806
  }
759
807
  /**
760
- * Get entities by synonym
808
+ * The entity's word-level matching vocabulary (PIN 2): name content
809
+ * words + alias content words + authored adjectives (per-side for walls
810
+ * via getEntityAdjectives). Always derived on demand from the CURRENT
811
+ * name — never stored — so renames can't leave stale vocabulary and
812
+ * Chord-loaded and TS-authored entities are uniform by construction.
761
813
  */
762
- getEntitiesBySynonym(synonym) {
763
- const normalizedSynonym = synonym.toLowerCase();
764
- return this.world.findWhere(entity => {
765
- // Skip rooms. The player IS resolvable here so its IdentityTrait
766
- // aliases (me/self/myself) match (ISSUE #154).
767
- if (entity.type === 'room') {
768
- return false;
814
+ getEntityVocabulary(entity) {
815
+ const vocabulary = new Set((0, world_model_1.deriveNameVocabulary)(this.getEntityName(entity)));
816
+ const identity = entity.getTrait(world_model_1.IdentityTrait);
817
+ if (identity?.aliases) {
818
+ for (const alias of identity.aliases) {
819
+ for (const word of (0, world_model_1.deriveNameVocabulary)(alias)) {
820
+ vocabulary.add(word);
821
+ }
769
822
  }
770
- const synonyms = this.getEntitySynonyms(entity).map(s => s.toLowerCase());
771
- return synonyms.includes(normalizedSynonym);
772
- });
823
+ }
824
+ for (const adjective of this.getEntityAdjectives(entity)) {
825
+ vocabulary.add(adjective.toLowerCase());
826
+ }
827
+ return vocabulary;
773
828
  }
774
829
  /**
775
- * Get entities by adjective (fallback for "press yellow" style commands)
776
- * When no name/alias match exists, find entities where the search term is an adjective
830
+ * Strip leading articles ("the", "a", "an") from query text, always
831
+ * keeping at least one word.
777
832
  */
778
- getEntitiesByAdjective(adjective) {
779
- const normalizedAdjective = adjective.toLowerCase();
780
- return this.world.findWhere(entity => {
781
- // Skip rooms. The player IS resolvable here (ISSUE #154).
782
- if (entity.type === 'room') {
783
- return false;
784
- }
785
- const adjectives = this.getEntityAdjectives(entity).map(a => a.toLowerCase());
786
- return adjectives.includes(normalizedAdjective);
787
- });
833
+ stripLeadingArticles(text) {
834
+ const words = text.split(/\s+/);
835
+ let start = 0;
836
+ while (start < words.length - 1 && QUERY_ARTICLES.has(words[start])) {
837
+ start++;
838
+ }
839
+ return words.slice(start).join(' ');
840
+ }
841
+ /**
842
+ * Keep only the dominant (tier, wordsMatched) group of an already-sorted
843
+ * scored list (PIN 2: higher tier wins; within a tier, more matched
844
+ * words win; only true ties reach disambiguation).
845
+ */
846
+ dominantMatches(scored) {
847
+ if (scored.length <= 1) {
848
+ return scored;
849
+ }
850
+ const top = scored[0];
851
+ return scored.filter(m => m.tier === top.tier && m.wordsMatched === top.wordsMatched);
788
852
  }
789
853
  /**
790
854
  * Filter entities by scope level
@@ -797,19 +861,19 @@ class CommandValidator {
797
861
  const entityScope = this.scopeResolver.getScope(player, entity);
798
862
  // Check if entity meets the required scope level
799
863
  switch (scope) {
800
- case types_1.ScopeLevel.CARRIED:
801
- return entityScope === types_1.ScopeLevel.CARRIED;
802
- case types_1.ScopeLevel.REACHABLE:
803
- return entityScope === types_1.ScopeLevel.CARRIED || entityScope === types_1.ScopeLevel.REACHABLE;
804
- case types_1.ScopeLevel.VISIBLE:
805
- return entityScope === types_1.ScopeLevel.CARRIED ||
806
- entityScope === types_1.ScopeLevel.REACHABLE ||
807
- entityScope === types_1.ScopeLevel.VISIBLE;
808
- case types_1.ScopeLevel.AWARE:
864
+ case types_js_1.ScopeLevel.CARRIED:
865
+ return entityScope === types_js_1.ScopeLevel.CARRIED;
866
+ case types_js_1.ScopeLevel.REACHABLE:
867
+ return entityScope === types_js_1.ScopeLevel.CARRIED || entityScope === types_js_1.ScopeLevel.REACHABLE;
868
+ case types_js_1.ScopeLevel.VISIBLE:
869
+ return entityScope === types_js_1.ScopeLevel.CARRIED ||
870
+ entityScope === types_js_1.ScopeLevel.REACHABLE ||
871
+ entityScope === types_js_1.ScopeLevel.VISIBLE;
872
+ case types_js_1.ScopeLevel.AWARE:
809
873
  // For aware, check if we can hear or smell it
810
874
  const canHear = this.scopeResolver.canHear && this.scopeResolver.canHear(player, entity);
811
875
  const canSmell = this.scopeResolver.canSmell && this.scopeResolver.canSmell(player, entity);
812
- return canHear || canSmell || entityScope >= types_1.ScopeLevel.AWARE;
876
+ return canHear || canSmell || entityScope >= types_js_1.ScopeLevel.AWARE;
813
877
  default:
814
878
  // Use numeric comparison for other scope levels
815
879
  return entityScope >= scope;
@@ -817,14 +881,17 @@ class CommandValidator {
817
881
  });
818
882
  }
819
883
  /**
820
- * Score entities against a reference
884
+ * Score entities against a reference (ADR-231 D3 tiered model).
885
+ *
886
+ * The tier and matched-word count come from `matchEntityName` and carry
887
+ * PIN 2's ranking; the numeric `score` is the within-tie heuristic
888
+ * (modifier/visibility/inventory/author scope priority bonuses) that the
889
+ * normal disambiguation flow uses to break residual ties.
821
890
  */
822
891
  scoreEntities(entities, ref) {
823
892
  if (!ref)
824
893
  return [];
825
894
  const scored = [];
826
- const fullText = ref.text?.toLowerCase() || '';
827
- const headNoun = (ref.head || ref.text).toLowerCase();
828
895
  // Extract modifiers from ref, or infer from text vs head if not set
829
896
  // (The parser may not always populate the modifiers field)
830
897
  let modifiers = ref.modifiers || [];
@@ -835,13 +902,7 @@ class CommandValidator {
835
902
  modifiers = words.filter(w => !nonModifiers.includes(w));
836
903
  }
837
904
  for (const entity of entities) {
838
- let score = 0;
839
- const matchReasons = [];
840
- // Get entity properties
841
- const name = this.getEntityName(entity).toLowerCase();
842
- const type = entity.type?.toLowerCase() || '';
843
905
  const adjectives = this.getEntityAdjectives(entity).map(a => a.toLowerCase());
844
- const synonyms = this.getEntitySynonyms(entity).map(s => s.toLowerCase());
845
906
  // ADR-173: walls require strict modifier match. When the user specifies
846
907
  // modifiers, a wall whose current-side adjective doesn't match at least
847
908
  // one of them is removed from candidacy entirely — falling back on the
@@ -853,43 +914,23 @@ class CommandValidator {
853
914
  continue;
854
915
  }
855
916
  }
856
- // Full text match scores highest (maximal munchlonger match = more specific)
857
- if (fullText && fullText !== headNoun) {
858
- if (name === fullText) {
859
- score += 15;
860
- matchReasons.push('full_text_name_match');
861
- }
862
- else if (synonyms.includes(fullText)) {
863
- score += 12;
864
- matchReasons.push('full_text_synonym_match');
865
- }
866
- }
867
- // Base score for matching the head noun (falls through if full text already matched)
868
- if (score === 0) {
869
- if (name === headNoun) {
870
- score += 10;
871
- matchReasons.push('exact_name_match');
872
- }
873
- else if (type === headNoun) {
874
- score += 8;
875
- matchReasons.push('type_match');
876
- }
877
- else if (synonyms.includes(headNoun)) {
878
- score += 6;
879
- matchReasons.push('synonym_match');
880
- }
881
- else if (adjectives.includes(headNoun)) {
882
- // Adjective fallback: "press yellow" finds "yellow button"
883
- score += 4;
884
- matchReasons.push('adjective_match');
885
- }
917
+ // Tiered name match (PIN 2)no match at either tier disqualifies
918
+ const match = this.matchEntityName(entity, ref);
919
+ if (!match) {
920
+ continue;
886
921
  }
887
- // Modifier matching - this is key for disambiguation
888
- // If the user specified modifiers, entities that match them score higher
889
- for (const modifier of modifiers) {
890
- if (adjectives.includes(modifier.toLowerCase())) {
891
- score += 5;
892
- matchReasons.push(`modifier_match_${modifier}`);
922
+ let score = 10;
923
+ const matchReasons = [...match.reasons];
924
+ // Modifier matching — an explicitly specified modifier the entity's
925
+ // vocabulary covers (adjective, name word, or alias word) marks the
926
+ // candidate as modifier-consistent for the disambiguation flow.
927
+ if (modifiers.length > 0) {
928
+ const vocabulary = this.getEntityVocabulary(entity);
929
+ for (const modifier of modifiers) {
930
+ if (vocabulary.has(modifier.toLowerCase())) {
931
+ score += 5;
932
+ matchReasons.push(`modifier_match_${modifier}`);
933
+ }
893
934
  }
894
935
  }
895
936
  // Penalty if entity has adjectives that weren't specified
@@ -925,12 +966,16 @@ class CommandValidator {
925
966
  matchReasons.push(`scope_priority_${priority}`);
926
967
  }
927
968
  }
928
- if (score > 0) {
929
- scored.push({ entity, score, matchReasons });
930
- }
969
+ scored.push({
970
+ entity,
971
+ tier: match.tier,
972
+ wordsMatched: match.wordsMatched,
973
+ score,
974
+ matchReasons
975
+ });
931
976
  }
932
- // Sort by score descending
933
- scored.sort((a, b) => b.score - a.score);
977
+ // Sort by PIN 2 rank (tier, then matched words), then heuristic score
978
+ scored.sort((a, b) => b.tier - a.tier || b.wordsMatched - a.wordsMatched || b.score - a.score);
934
979
  return scored;
935
980
  }
936
981
  /**
@@ -984,6 +1029,25 @@ class CommandValidator {
984
1029
  return perfectMatches[0];
985
1030
  }
986
1031
  }
1032
+ // Action scope preference (Phase 6/10): when the action declares a
1033
+ // preferredScope and exactly ONE candidate sits at it, that candidate
1034
+ // wins — "drop book" with the black book in hand and a guidebook on the
1035
+ // floor means the carried one, even though dropping resolves VISIBLE so
1036
+ // its own refusal can speak for un-held targets.
1037
+ if (this.currentPreferredScope !== undefined) {
1038
+ const player = this.world.getPlayer();
1039
+ if (player) {
1040
+ const preferred = matches.filter(m => this.scopeResolver.getScope(player, m.entity) >= this.currentPreferredScope);
1041
+ if (preferred.length === 1) {
1042
+ this.emitDebugEvent('ambiguity_resolution', command, {
1043
+ resolved: true,
1044
+ method: 'action_preferred_scope',
1045
+ chosen: preferred[0].entity.id
1046
+ });
1047
+ return preferred[0];
1048
+ }
1049
+ }
1050
+ }
987
1051
  // If only one is visible and reachable, use it
988
1052
  const reachableMatches = matches.filter(m => this.isEntityVisible(m.entity) && this.isEntityReachable(m.entity));
989
1053
  if (reachableMatches.length === 1) {
@@ -1070,32 +1134,32 @@ class CommandValidator {
1070
1134
  const entityScope = this.scopeResolver.getScope(player, entity);
1071
1135
  // Check if entity meets the required scope level
1072
1136
  switch (requiredScope) {
1073
- case types_1.ScopeLevel.CARRIED:
1074
- if (entityScope !== types_1.ScopeLevel.CARRIED) {
1137
+ case types_js_1.ScopeLevel.CARRIED:
1138
+ if (entityScope !== types_js_1.ScopeLevel.CARRIED) {
1075
1139
  return {
1076
1140
  success: false,
1077
1141
  code: 'NOT_CARRIED'
1078
1142
  };
1079
1143
  }
1080
1144
  break;
1081
- case types_1.ScopeLevel.REACHABLE:
1082
- if (entityScope !== types_1.ScopeLevel.CARRIED && entityScope !== types_1.ScopeLevel.REACHABLE) {
1145
+ case types_js_1.ScopeLevel.REACHABLE:
1146
+ if (entityScope !== types_js_1.ScopeLevel.CARRIED && entityScope !== types_js_1.ScopeLevel.REACHABLE) {
1083
1147
  return {
1084
1148
  success: false,
1085
1149
  code: 'NOT_REACHABLE'
1086
1150
  };
1087
1151
  }
1088
1152
  break;
1089
- case types_1.ScopeLevel.VISIBLE:
1090
- if (entityScope < types_1.ScopeLevel.VISIBLE) {
1153
+ case types_js_1.ScopeLevel.VISIBLE:
1154
+ if (entityScope < types_js_1.ScopeLevel.VISIBLE) {
1091
1155
  return {
1092
1156
  success: false,
1093
1157
  code: 'NOT_VISIBLE'
1094
1158
  };
1095
1159
  }
1096
1160
  break;
1097
- case types_1.ScopeLevel.AWARE:
1098
- if (entityScope === types_1.ScopeLevel.UNAWARE) {
1161
+ case types_js_1.ScopeLevel.AWARE:
1162
+ if (entityScope === types_js_1.ScopeLevel.UNAWARE) {
1099
1163
  return {
1100
1164
  success: false,
1101
1165
  code: 'NOT_AWARE'
@@ -1210,8 +1274,8 @@ class CommandValidator {
1210
1274
  return {
1211
1275
  requiresDirectObject: false,
1212
1276
  requiresIndirectObject: false,
1213
- directObjectScope: types_1.ScopeLevel.VISIBLE,
1214
- indirectObjectScope: types_1.ScopeLevel.VISIBLE
1277
+ directObjectScope: types_js_1.ScopeLevel.VISIBLE,
1278
+ indirectObjectScope: types_js_1.ScopeLevel.VISIBLE
1215
1279
  };
1216
1280
  }
1217
1281
  /**