ctx_driver 0.2.5 → 0.2.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 598a02dcecf58f317a71bbd0bb6591eeb00de1a7af012f0b8630a60c409b97f0
4
- data.tar.gz: c0a6abd65a443d0084e69be5c533a150c31fd037c6c23e6ab5e1663a4e893ca4
3
+ metadata.gz: 80d06361fc6394791573257eb9fb244193ef62c3af63f2c4840bf06d8899a18f
4
+ data.tar.gz: 27f328d64cd3ae09a108aed29e26ddebbaa6c60131299dcabff8bc85179f76b3
5
5
  SHA512:
6
- metadata.gz: 2b54944316508e0ba40ca5b9b582ea437b2a8e5684e58dbae1b3c7326d5c942e3d36c62e9bf9de2005522e9ad6c531b866faaad56b9f38ea4b64b384ff11b703
7
- data.tar.gz: 9c7095540378d3d58aea63fbc22710043899a10277e0d068174033898c108ca21fd846db11549e2f9ff4d254b34e429df62caa3fb892fa8c595d7eb94d69700a
6
+ metadata.gz: dd4ea380ec3eaeb44475259809a66ad3e8bd1b306bd98846ce70d5f3181cc428777b68c80bbf04184309016a2be9ce4e877986315eeb0887ec3d7258f17bedee
7
+ data.tar.gz: 354b3de16106cf86cad5c19b63982cd71d199c194dd2b3d8c441ffe30e61eff8bd9323179d2c8561c4787a6b00cd5805fd73ae0327f708b6022c65c7762d06a5
data/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ Changes to the public contract are recorded here. Versions follow Semantic Versi
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.2.7 (2026-10-23)
8
+
9
+ - Skip subsequent queries after malformed single-command receipts while preserving valid command failure and local decoding isolation.
10
+ - Update the documented session protocol and declare the required parser version.
11
+
12
+ ## 0.2.6 (2026-10-23)
13
+
14
+ - Validate single-command receipts consistently without legacy rejection hooks; preserve borrowed-session ownership.
15
+
7
16
  ## 0.2.5 (2026-10-21)
8
17
 
9
18
  - Add repository-specific AGENTS.md guidance for responsibilities, Ruby conventions, evidence boundaries and validation.
data/README-zh.md CHANGED
@@ -74,7 +74,7 @@ puts "SHA-256: #{capture.evidence.first[:sha256]}"
74
74
 
75
75
  `Reader.new(session:, clock:).read(command)` 返回 `Capture`。通过 `success?`、`skipped?`、`failure`、`evidence` 检查结果;正文仅显式通过 `body` 读取,`to_h`、`as_json`、`inspect` 不包含正文。`Reader`、借用会话适配器 `Session` 及其回执的 `inspect`/`PP` 不展开调用方对象,也不查询连接状态;回执的字符串插值同样安全。原始输出与解码正文仍可通过回执的显式 API 访问。
76
76
 
77
- 自定义会话实现 `connected?` 和 `send_commands([command])`。回执提供 `output`、布尔 `success?`、数组 `steps`、成功正文 `value!` 及失败时的 `error`。成功读取必须只有一个完成步骤。只有会话显式声明 `preserve_session_on_rejection:` 关键字时才传入该选项。
77
+ 自定义会话实现 `connected?` 和 `send_commands([command])`。回执提供 `output`、布尔 `success?`、数组 `steps`、成功正文 `value!` 及失败时的 `error`。成功读取必须只有一个完成步骤。失败回执最多包含一个完成步骤。输出、状态或步骤数量非法时,即使连接仍在线也会跳过后续查询;回执有效后的本地解码或时钟失败不改变会话同步状态。
78
78
 
79
79
  net-connector 仍为可选依赖,使用适配器的宿主需自行声明 `gem "net-connector", ">= 0.13.0"`。`examples/connector.rb` 通过本地 PTY 子进程验证已安装连接器,不连接网络设备。
80
80
 
data/README.md CHANGED
@@ -74,7 +74,7 @@ puts "SHA-256: #{capture.evidence.first[:sha256]}"
74
74
 
75
75
  `Reader.new(session:, clock:).read(command)` returns a `Capture`. Inspect `success?`, `skipped?`, `failure`, and `evidence`; access the body explicitly through `body`. `to_h`, `as_json`, and `inspect` omit the body. `Reader`, the borrowed `Session` adapter, and its response use safe `inspect`/`PP` displays that do not traverse caller-owned objects or consult connection state. Response string interpolation is also safe; raw output and decoded bodies remain available through explicit response APIs.
76
76
 
77
- A custom session implements `connected?` and `send_commands([command])`. Already loaded `Net::Connector::Base` sessions from net-connector **0.13.0 or newer** are adapted automatically through `execute_operation`, without connecting or requesting privilege. The adapter removes the matched prompt and first-line command echo, and keeps raw bytes only in the explicit capture evidence boundary. A native connector that closes on command rejection stays closed; later reads are skipped. A response exposes `output`, a boolean `success?`, an array `steps`, `value!` for a successful body, and `error` on failure. A successful read must contain exactly one completed step. The optional `preserve_session_on_rejection:` keyword is supplied only when the session explicitly declares it.
77
+ A custom session implements `connected?` and `send_commands([command])`. Already loaded `Net::Connector::Base` sessions from net-connector **0.13.0 or newer** are adapted automatically through `execute_operation`, without connecting or requesting privilege. The adapter removes the matched prompt and first-line command echo, and keeps raw bytes only in the explicit capture evidence boundary. A native connector that closes on command rejection stays closed; later reads are skipped. A response exposes `output`, a boolean `success?`, an array `steps`, `value!` for a successful body, and `error` on failure. A successful read must contain exactly one completed step. A failed receipt may contain at most one completed step. Invalid output, status or step counts stop later queries even when the session remains connected; validated receipts with local decoding or clock errors do not invalidate session synchronization.
78
78
 
79
79
  net-connector remains optional: applications using this adapter must declare `gem "net-connector", ">= 0.13.0"` themselves. `examples/connector.rb` exercises the installed adapter through a local PTY process without opening network connections.
80
80
 
@@ -28,7 +28,7 @@ capture.evidence # command / sha256 / bytes / observed_at
28
28
  `output` 用于原始来源摘要,`value!` 是连接器处理后的正文,两者不要求相等。
29
29
  自定义协议由宿主清理正文;net-connector 0.13.0 及以上版本的原生 `Net::Connector::Base` 由可选适配器绑定当前完整提示符,并在证据摘要生成后去除命令回显及提示符。适配器不主动加载 net-connector,不连接、不提权。调用方只传目录中已批准的查询。
30
30
 
31
- 只有会话方法显式声明 `preserve_session_on_rejection:` 时,才传 `true`。
31
+ 失败回执最多包含一个完成步骤。回执输出、状态或步骤数量非法时,连接在线不能证明同步状态,Reader 保留首个失败并跳过后续查询;回执有效后的本地解码或时钟错误仍按单命令失败隔离。
32
32
  原生 net-connector 关闭拒绝命令后的会话时,Reader 保留该关闭状态;自定义适配器只有确认会话仍可用,才允许下一条独立命令。
33
33
  断线或状态未知时记忆首个原因,后续命令返回 skipped,不自动重连或重放。
34
34
  `reader.failure` 可供不提交命令的分支检查会话状态。
@@ -58,12 +58,9 @@ module CtxDriver
58
58
  def capture_command(command, started_at)
59
59
  stage, evidence, command_failure, body = :execute, [], nil, nil
60
60
  capture_completed = false
61
+ receipt_validated = false
61
62
  begin
62
- receipt = if supports_session_preservation?
63
- @session.send_commands([ command ], preserve_session_on_rejection: true)
64
- else
65
- @session.send_commands([ command ])
66
- end
63
+ receipt = @session.send_commands([ command ])
67
64
  stage = :response
68
65
  output = receipt.output
69
66
  raise TypeError, "Command output must be text" unless output.is_a?(String)
@@ -74,6 +71,7 @@ module CtxDriver
74
71
  unless [ true, false ].include?(success) && steps.is_a?(Array) && (success ? steps.one? : steps.size <= 1)
75
72
  raise TypeError, "One query must return one completed command"
76
73
  end
74
+ receipt_validated = true
77
75
  if success
78
76
  body = receipt.value!
79
77
  raise TypeError, "Command body must be text" unless body.is_a?(String)
@@ -85,6 +83,8 @@ module CtxDriver
85
83
  rescue StandardError => error
86
84
  fallback = stage == :execute ? :command_execution_failed : :invalid_command_result
87
85
  command_failure = Failure.details(error, fallback: fallback, stage: stage)
86
+ # 在线状态不能证明畸形回执对应的单命令边界;不复用未知同步状态。
87
+ @session_failure ||= command_failure if stage == :response && !receipt_validated
88
88
  end
89
89
  # 外部时钟回调只在正文与摘要固定后调用,不能复用本条响应缓冲区。
90
90
  begin
@@ -108,13 +108,6 @@ module CtxDriver
108
108
  @session_failure ||= command_failure || { code: :command_aborted, stage: stage || :execute }.freeze unless capture_completed
109
109
  end
110
110
 
111
- # 仅在明确支持时复用命令拒绝后的会话;未知提示符仍由连接器关闭处理。
112
- def supports_session_preservation?
113
- @session.method(:send_commands).parameters.any? do |kind, name|
114
- %i[key keyreq].include?(kind) && name == :preserve_session_on_rejection
115
- end
116
- end
117
-
118
111
  # 连接状态不确定时视为不可用,后续跳过的查询保留首次失败原因。
119
112
  def detect_session_failure
120
113
  state = @session.connected?
@@ -2,5 +2,5 @@
2
2
 
3
3
  module CtxDriver
4
4
  # 公开包版本,供 RubyGems 元数据和运行时调用方共用。
5
- VERSION = "0.2.5"
5
+ VERSION = "0.2.7"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ctx_driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gatework contributors
@@ -13,16 +13,16 @@ dependencies:
13
13
  name: ctx_parser
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.2.0
18
+ version: 0.2.7
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 0.2.0
25
+ version: 0.2.7
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: digest
28
28
  requirement: !ruby/object:Gem::Requirement