55 lines
1.9 KiB
Plaintext
55 lines
1.9 KiB
Plaintext
local M = {}
|
|
-- versions.lua
|
|
-- Module for version checking according to LMCP contract
|
|
|
|
-- Only the new version. The old one (2025-06-18) no longer exists: with
|
|
-- SEP-2575 initialize is removed, the negotiation of the old version
|
|
-- is dead. Listing 2025-06-18 in the list would be a lie in the
|
|
-- discover response. Dual protocol (old + new) is a later phase.
|
|
M.SUPPORTED = {'2026-07-28'}
|
|
|
|
--- Checks whether a version is supported.
|
|
-- @param version The version to check (string or nil)
|
|
-- @return boolean true if supported, otherwise false
|
|
-- @return table|nil error details if not supported
|
|
function M.check(version)
|
|
-- (a) version == nil or '' -> true, nil
|
|
if version == nil or version == '' then
|
|
return true, nil
|
|
end
|
|
|
|
-- (b) exact match in M.SUPPORTED -> true, nil
|
|
for _, supported_version in ipairs(M.SUPPORTED) do
|
|
if version == supported_version then
|
|
return true, nil
|
|
end
|
|
end
|
|
|
|
-- (c) everything else -> false, { code = -32022, data = { supported = <copy> } }
|
|
--
|
|
-- COPY, not M.SUPPORTED itself. Previously the module table leaked out:
|
|
-- a caller that keeps the error object and err.data.supported[1]
|
|
-- overwrites, changes the module's list for EVERY subsequent
|
|
-- call -- demonstrated on 2026-08-09: after
|
|
-- e.data.supported[1] = 'CAPTURED' check('2025-06-18') is false and
|
|
-- check('CAPTURED') is true. Contract rule 5 ('A call must not shift the list of
|
|
-- the next') was thereby broken, and test 5 did not see it
|
|
-- because it never writes over the returned reference.
|
|
-- As long as no one called the module, this was theoretical. Since it is attached to
|
|
-- initialize, it is reachable.
|
|
local copy = {}
|
|
for i = 1, #M.SUPPORTED do
|
|
copy[i] = M.SUPPORTED[i]
|
|
end
|
|
return false, {
|
|
code = -32022,
|
|
data = {
|
|
supported = copy
|
|
}
|
|
}
|
|
end
|
|
|
|
-- No new globals, no side effects, M.SUPPORTED is not modified
|
|
|
|
return M
|