convertible-cli 0.1.2__tar.gz → 0.2.1__tar.gz

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 (101) hide show
  1. convertible_cli-0.2.1/.devague/current +1 -0
  2. convertible_cli-0.2.1/.devague/current_plan +1 -0
  3. convertible_cli-0.2.1/.devague/frames/convertible-v0-ships-point-it-at-a-repo-task-and-i.json +334 -0
  4. convertible_cli-0.2.1/.devague/plans/convertible-v0-ships-point-it-at-a-repo-task-and-i.json +422 -0
  5. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.gitignore +3 -0
  6. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.markdownlint-cli2.yaml +6 -0
  7. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/CHANGELOG.md +30 -0
  8. convertible_cli-0.2.1/CLAUDE.md +91 -0
  9. convertible_cli-0.2.1/PKG-INFO +149 -0
  10. convertible_cli-0.2.1/README.md +132 -0
  11. convertible_cli-0.2.1/convertible/artifact.py +57 -0
  12. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/__init__.py +5 -3
  13. convertible_cli-0.2.1/convertible/cli/_commands/drive.py +123 -0
  14. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/learn.py +4 -0
  15. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/overview.py +2 -0
  16. convertible_cli-0.2.1/convertible/cli/_commands/wheels.py +78 -0
  17. convertible_cli-0.2.1/convertible/config.py +97 -0
  18. convertible_cli-0.2.1/convertible/contract.py +189 -0
  19. convertible_cli-0.2.1/convertible/engine.py +38 -0
  20. convertible_cli-0.2.1/convertible/engines/__init__.py +7 -0
  21. convertible_cli-0.2.1/convertible/engines/mock.py +54 -0
  22. convertible_cli-0.2.1/convertible/engines/vllm_openai.py +97 -0
  23. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/explain/catalog.py +46 -1
  24. convertible_cli-0.2.1/convertible/handoff.py +143 -0
  25. convertible_cli-0.2.1/convertible/loop.py +154 -0
  26. convertible_cli-0.2.1/convertible/registry.py +61 -0
  27. convertible_cli-0.2.1/convertible/tools.py +197 -0
  28. convertible_cli-0.2.1/docs/plans/2026-05-26-convertible-v0-ships-point-it-at-a-repo-task-and-i.md +124 -0
  29. convertible_cli-0.2.1/docs/specs/2026-05-26-convertible-v0-ships-point-it-at-a-repo-task-and-i.md +71 -0
  30. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/pyproject.toml +8 -1
  31. convertible_cli-0.2.1/tests/test_artifact.py +71 -0
  32. convertible_cli-0.2.1/tests/test_config.py +45 -0
  33. convertible_cli-0.2.1/tests/test_contract.py +54 -0
  34. convertible_cli-0.2.1/tests/test_drive.py +131 -0
  35. convertible_cli-0.2.1/tests/test_e2e_mock.py +130 -0
  36. convertible_cli-0.2.1/tests/test_engine.py +35 -0
  37. convertible_cli-0.2.1/tests/test_handoff.py +116 -0
  38. convertible_cli-0.2.1/tests/test_loop.py +93 -0
  39. convertible_cli-0.2.1/tests/test_mock_engine.py +39 -0
  40. convertible_cli-0.2.1/tests/test_registry.py +71 -0
  41. convertible_cli-0.2.1/tests/test_tools.py +76 -0
  42. convertible_cli-0.2.1/tests/test_vllm_live.py +50 -0
  43. convertible_cli-0.2.1/tests/test_vllm_openai.py +86 -0
  44. convertible_cli-0.2.1/tests/test_wheels.py +38 -0
  45. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/uv.lock +1 -1
  46. convertible_cli-0.1.2/CLAUDE.md +0 -28
  47. convertible_cli-0.1.2/PKG-INFO +0 -73
  48. convertible_cli-0.1.2/README.md +0 -56
  49. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/agent-config/SKILL.md +0 -0
  50. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  51. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
  52. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
  53. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
  54. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/SKILL.md +0 -0
  55. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
  56. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
  57. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
  58. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
  59. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  60. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/SKILL.md +0 -0
  61. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  62. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  63. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  64. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  65. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
  66. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
  67. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  68. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  69. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  70. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  71. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/run-tests/SKILL.md +0 -0
  72. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  73. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
  74. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  75. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/spec-to-plan/SKILL.md +0 -0
  76. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
  77. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/think/SKILL.md +0 -0
  78. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/think/scripts/think.sh +0 -0
  79. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/version-bump/SKILL.md +0 -0
  80. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
  81. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.claude/skills.local.yaml.example +0 -0
  82. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.flake8 +0 -0
  83. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.github/workflows/publish.yml +0 -0
  84. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/.github/workflows/tests.yml +0 -0
  85. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/LICENSE +0 -0
  86. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/__init__.py +0 -0
  87. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/__main__.py +0 -0
  88. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/__init__.py +0 -0
  89. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/cli.py +0 -0
  90. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/doctor.py +0 -0
  91. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/explain.py +0 -0
  92. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_commands/whoami.py +0 -0
  93. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_errors.py +0 -0
  94. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/cli/_output.py +0 -0
  95. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/convertible/explain/__init__.py +0 -0
  96. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/culture.yaml +0 -0
  97. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/docs/skill-sources.md +0 -0
  98. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/sonar-project.properties +0 -0
  99. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/tests/__init__.py +0 -0
  100. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/tests/test_cli.py +0 -0
  101. {convertible_cli-0.1.2 → convertible_cli-0.2.1}/tests/test_cli_introspection.py +0 -0
@@ -0,0 +1 @@
1
+ convertible-v0-ships-point-it-at-a-repo-task-and-i
@@ -0,0 +1 @@
1
+ convertible-v0-ships-point-it-at-a-repo-task-and-i
@@ -0,0 +1,334 @@
1
+ {
2
+ "slug": "convertible-v0-ships-point-it-at-a-repo-task-and-i",
3
+ "title": "Convertible v0 ships: point it at a repo task and it drives the work through a swappable coder engine behind one shared task contract \u2014 the first real engine is a local coding model served via a vLLM OpenAI-compatible API.",
4
+ "schema_version": 1,
5
+ "status": "exported",
6
+ "created": "2026-05-26T23:20:12Z",
7
+ "updated": "2026-05-26T23:29:03Z",
8
+ "claims": [
9
+ {
10
+ "id": "c1",
11
+ "kind": "announcement",
12
+ "text": "Convertible v0 ships: point it at a repo task and it drives the work through a swappable coder engine behind one shared task contract \u2014 the first real engine is a local coding model served via a vLLM OpenAI-compatible API.",
13
+ "origin": "user",
14
+ "status": "confirmed",
15
+ "honesty_conditions": [
16
+ {
17
+ "id": "h8",
18
+ "text": "End-to-end proof: 'convertible drive' against the live vLLM server at localhost:8001 (Qwen3-32B) edits a real repo correctly AND opens a PR; the same task on the mock engine yields an identically-shaped result with no network \u2014 demonstrating one contract, swappable engines.",
19
+ "status": "confirmed"
20
+ }
21
+ ],
22
+ "hard_questions": [],
23
+ "links": []
24
+ },
25
+ {
26
+ "id": "c2",
27
+ "kind": "audience",
28
+ "text": "Culture/Guildmaster/Taskmaster operators who assign repo work without caring which coding engine runs it, plus Convertible developers who build engine wheels.",
29
+ "origin": "llm",
30
+ "status": "confirmed",
31
+ "honesty_conditions": [
32
+ {
33
+ "id": "h9",
34
+ "text": "The audience is real and reachable: at least one concrete consumer (Guildmaster/Taskmaster/Steward, or a Convertible engine-wheel developer) can drive a task through v0 without bespoke per-backend integration.",
35
+ "status": "confirmed"
36
+ }
37
+ ],
38
+ "hard_questions": [],
39
+ "links": []
40
+ },
41
+ {
42
+ "id": "c3",
43
+ "kind": "before_state",
44
+ "text": "Each coder backend (Codex, Claude Code, local models) has its own invocation, controls, and output shape; assigning repo work means coding against one specific backend, and swapping engines means rewriting the integration.",
45
+ "origin": "llm",
46
+ "status": "confirmed",
47
+ "honesty_conditions": [
48
+ {
49
+ "id": "h10",
50
+ "text": "The pain is real today: adding a new coder backend currently requires backend-specific invocation and output handling \u2014 exactly what v0 removes behind one contract.",
51
+ "status": "confirmed"
52
+ }
53
+ ],
54
+ "hard_questions": [],
55
+ "links": []
56
+ },
57
+ {
58
+ "id": "c4",
59
+ "kind": "after_state",
60
+ "text": "An operator runs 'convertible drive' against a task + repo; Convertible executes it via a selected engine (mock or vLLM-OpenAI) and emits structured logs + a result artifact for handoff \u2014 the caller never needs to know which engine ran.",
61
+ "origin": "llm",
62
+ "status": "confirmed",
63
+ "honesty_conditions": [
64
+ {
65
+ "id": "h11",
66
+ "text": "After v0, 'convertible drive' produces the described handoff (logs + JSON result artifact + PR) for both engines, and the caller's invocation is identical regardless of which engine ran.",
67
+ "status": "confirmed"
68
+ }
69
+ ],
70
+ "hard_questions": [],
71
+ "links": []
72
+ },
73
+ {
74
+ "id": "c5",
75
+ "kind": "why_it_matters",
76
+ "text": "Culture can assign repo work behind one contract; the model becomes a swappable engine, not a hardwired dependency.",
77
+ "origin": "llm",
78
+ "status": "confirmed",
79
+ "honesty_conditions": [
80
+ {
81
+ "id": "h12",
82
+ "text": "Swapping the engine (mock <-> vllm-openai) requires no change to the task contract or caller code \u2014 only --engine/config selects it.",
83
+ "status": "confirmed"
84
+ }
85
+ ],
86
+ "hard_questions": [],
87
+ "links": []
88
+ },
89
+ {
90
+ "id": "c6",
91
+ "kind": "boundary",
92
+ "text": "v0 is NOT a multi-engine router/policy selector, NOT a sandboxed execution environment, and NOT a daemon; it ships the chassis (task contract + lifecycle), the wheel/plugin discovery contract, and exactly two engine drivers \u2014 a mock/local wheel and a vLLM OpenAI-compatible wheel. No Codex/Claude/Gemini drivers in v0.",
93
+ "origin": "llm",
94
+ "status": "confirmed",
95
+ "honesty_conditions": [
96
+ {
97
+ "id": "h13",
98
+ "text": "v0 ships exactly the in-scope set (chassis + wheel discovery + 2 engines + PR handoff) and none of the excluded items (router/policy/sandbox/daemon); any excluded feature appearing means scope crept.",
99
+ "status": "confirmed"
100
+ }
101
+ ],
102
+ "hard_questions": [],
103
+ "links": []
104
+ },
105
+ {
106
+ "id": "c7",
107
+ "kind": "success_signal",
108
+ "text": "'convertible drive' runs a task end-to-end against both a live vLLM OpenAI server and the mock engine, producing identically-shaped task results/artifacts; the engine is swappable via --engine/config with zero change to the task contract; wheels are discovered via Python entry points ('convertible wheels list').",
109
+ "origin": "llm",
110
+ "status": "confirmed",
111
+ "honesty_conditions": [
112
+ {
113
+ "id": "h14",
114
+ "text": "The success signal is observable: one test/demo runs the same task on both mock and vllm-openai and asserts identically-shaped results, a working --engine swap, and 'wheels list' showing both engines.",
115
+ "status": "confirmed"
116
+ }
117
+ ],
118
+ "hard_questions": [],
119
+ "links": []
120
+ },
121
+ {
122
+ "id": "c8",
123
+ "kind": "requirement",
124
+ "text": "R1 Task contract: a typed Task (id, repo path, instruction, optional context/constraints, engine selection) and typed TaskResult (status, summary, changed_files, step trace, usage, artifacts path) that every engine driver consumes/produces identically.",
125
+ "origin": "llm",
126
+ "status": "confirmed",
127
+ "honesty_conditions": [
128
+ {
129
+ "id": "h1",
130
+ "text": "A Task and TaskResult round-trip through any engine unchanged in shape: the mock and vllm-openai engines both consume the same Task and produce a TaskResult with the same fields; serializing a TaskResult to JSON and reloading yields an identical object.",
131
+ "status": "confirmed"
132
+ }
133
+ ],
134
+ "hard_questions": [],
135
+ "links": []
136
+ },
137
+ {
138
+ "id": "c9",
139
+ "kind": "requirement",
140
+ "text": "R2 Engine driver protocol: an abstract Engine interface with a drive(task, repo, tools, budget) -> TaskResult; the vllm-openai driver implements it via an OpenAI-compatible /v1/chat/completions endpoint (configurable base_url, api_key, model) using tool/function calling.",
141
+ "origin": "llm",
142
+ "status": "confirmed",
143
+ "honesty_conditions": [
144
+ {
145
+ "id": "h2",
146
+ "text": "The vllm-openai driver touches only the OpenAI-compatible surface (base_url/api_key/model + /v1/chat/completions with tools); pointing base_url at any OpenAI-compatible server is a config change, not a code change.",
147
+ "status": "confirmed"
148
+ }
149
+ ],
150
+ "hard_questions": [],
151
+ "links": []
152
+ },
153
+ {
154
+ "id": "c10",
155
+ "kind": "requirement",
156
+ "text": "R3 Agentic tool-loop: Convertible runs a bounded loop offering tools read_file, write_file, list_dir, run_command, finish; executes the model's tool_calls against the target repo working tree; feeds tool results back; terminates on finish() or a max_steps budget.",
157
+ "origin": "llm",
158
+ "status": "confirmed",
159
+ "honesty_conditions": [
160
+ {
161
+ "id": "h3",
162
+ "text": "The agentic loop always terminates (model finish() OR max_steps reached), and write_file/run_command act only inside the target repo path \u2014 no writes escape it.",
163
+ "status": "confirmed"
164
+ }
165
+ ],
166
+ "hard_questions": [],
167
+ "links": []
168
+ },
169
+ {
170
+ "id": "c11",
171
+ "kind": "requirement",
172
+ "text": "R4 Wheel/plugin discovery: engines register as Python entry points (group convertible.engines); 'convertible wheels list' enumerates discovered engines; --engine <name>/config selects one; bundled mock and vllm-openai engines register through the same mechanism an external wheel would.",
173
+ "origin": "llm",
174
+ "status": "confirmed",
175
+ "honesty_conditions": [
176
+ {
177
+ "id": "h4",
178
+ "text": "An engine shipped by an out-of-tree wheel installed in the same env appears in 'convertible wheels list' and is selectable via --engine with no core change, proven by the bundled engines using the identical entry-point mechanism.",
179
+ "status": "confirmed"
180
+ }
181
+ ],
182
+ "hard_questions": [],
183
+ "links": []
184
+ },
185
+ {
186
+ "id": "c12",
187
+ "kind": "requirement",
188
+ "text": "R5 Dashboard/handoff output: each run writes structured logs + a result artifact (JSON) capturing status, changed_files, step trace, and usage, suitable for handoff back to Guildmaster/Taskmaster/Steward.",
189
+ "origin": "llm",
190
+ "status": "confirmed",
191
+ "honesty_conditions": [
192
+ {
193
+ "id": "h5",
194
+ "text": "Every drive run writes a result artifact that is valid JSON with at least {status, changed_files, steps, usage}; a failed run still writes one with status=error and the failure reason.",
195
+ "status": "confirmed"
196
+ }
197
+ ],
198
+ "hard_questions": [],
199
+ "links": []
200
+ },
201
+ {
202
+ "id": "c13",
203
+ "kind": "requirement",
204
+ "text": "R6 Mock engine: a deterministic in-process engine that performs scripted tool calls (e.g. write a file) so 'drive' works in CI with no network, exercising the same task contract + tool-loop as the real engine.",
205
+ "origin": "llm",
206
+ "status": "confirmed",
207
+ "honesty_conditions": [
208
+ {
209
+ "id": "h6",
210
+ "text": "The mock engine completes a drive run with zero network access and deterministic output, exercising the full task contract + tool-loop, so CI validates the chassis without a live model.",
211
+ "status": "confirmed"
212
+ }
213
+ ],
214
+ "hard_questions": [],
215
+ "links": []
216
+ },
217
+ {
218
+ "id": "c14",
219
+ "kind": "decision",
220
+ "text": "D1 CLI-first for v0 with an importable core library; daemon/library-server mode is reserved, not built.",
221
+ "origin": "llm",
222
+ "status": "confirmed",
223
+ "honesty_conditions": [],
224
+ "hard_questions": [],
225
+ "links": []
226
+ },
227
+ {
228
+ "id": "c15",
229
+ "kind": "decision",
230
+ "text": "D2 Wheels are trusted code only in v0, loaded via entry points; no untrusted-plugin sandboxing. run_command executes in the target repo with the operator's privileges.",
231
+ "origin": "llm",
232
+ "status": "confirmed",
233
+ "honesty_conditions": [],
234
+ "hard_questions": [],
235
+ "links": []
236
+ },
237
+ {
238
+ "id": "c16",
239
+ "kind": "decision",
240
+ "text": "D3 vLLM is driven purely through its OpenAI-compatible API (no vLLM-specific SDK), so the same driver works against any OpenAI-compatible server; reference config = base_url http://localhost:8001/v1, model Qwen3-32B (NVFP4).",
241
+ "origin": "llm",
242
+ "status": "confirmed",
243
+ "honesty_conditions": [],
244
+ "hard_questions": [],
245
+ "links": []
246
+ },
247
+ {
248
+ "id": "c17",
249
+ "kind": "decision",
250
+ "text": "D4 PyPI distribution = convertible-cli; command + import package = convertible; a single distribution ships core + bundled engines.",
251
+ "origin": "llm",
252
+ "status": "confirmed",
253
+ "honesty_conditions": [],
254
+ "hard_questions": [],
255
+ "links": []
256
+ },
257
+ {
258
+ "id": "c18",
259
+ "kind": "decision",
260
+ "text": "D5 v0 mutates the target repo working tree in place and leaves git (branch/commit/PR) to the operator; the result artifact lists changed files.",
261
+ "origin": "llm",
262
+ "status": "rejected",
263
+ "honesty_conditions": [],
264
+ "hard_questions": [],
265
+ "links": []
266
+ },
267
+ {
268
+ "id": "c19",
269
+ "kind": "non_goal",
270
+ "text": "No gearbox in v0: no multi-engine routing/strategy/policy selection, no artifact-publisher/handoff-target wheels, and no repo-adapter abstraction beyond a local filesystem path.",
271
+ "origin": "llm",
272
+ "status": "confirmed",
273
+ "honesty_conditions": [],
274
+ "hard_questions": [],
275
+ "links": []
276
+ },
277
+ {
278
+ "id": "c20",
279
+ "kind": "assumption",
280
+ "text": "The configured vLLM server is reachable and serves an OpenAI-compatible /v1/chat/completions with working tool/function calling for the model (Qwen3-32B may need vLLM's --enable-auto-tool-choice --tool-call-parser hermes).",
281
+ "origin": "llm",
282
+ "status": "confirmed",
283
+ "honesty_conditions": [],
284
+ "hard_questions": [],
285
+ "links": []
286
+ },
287
+ {
288
+ "id": "c21",
289
+ "kind": "requirement",
290
+ "text": "R7 Git/PR handoff: after a successful drive, Convertible edits the working tree, then creates a branch, commits, pushes, and opens a PR via the gh CLI; the result artifact records branch name + PR URL. PR creation is gated (a --no-pr flag or absent remote/auth) so the same drive completes edit+local-commit and records pr_url=null offline/in CI.",
291
+ "origin": "llm",
292
+ "status": "confirmed",
293
+ "honesty_conditions": [
294
+ {
295
+ "id": "h7",
296
+ "text": "A drive with a configured remote + gh auth ends with a pushed branch and an open PR whose URL is in the result artifact; a drive with --no-pr or no remote completes edit + local commit and records pr_url=null.",
297
+ "status": "confirmed"
298
+ }
299
+ ],
300
+ "hard_questions": [],
301
+ "links": []
302
+ },
303
+ {
304
+ "id": "c22",
305
+ "kind": "decision",
306
+ "text": "D5 Handoff model: working-tree edits are the substrate; git capture (branch/commit/push) + 'gh pr create' is the default handoff. Requires a git remote + gh auth on the target repo; --no-pr or a missing remote degrades gracefully to a local commit so CI/offline runs never push.",
307
+ "origin": "llm",
308
+ "status": "confirmed",
309
+ "honesty_conditions": [],
310
+ "hard_questions": [],
311
+ "links": []
312
+ }
313
+ ],
314
+ "open_vagueness": [
315
+ {
316
+ "id": "v1",
317
+ "text": "Exact result-artifact JSON schema + versioning, and how it maps to the handoff shape Guildmaster/Taskmaster/Steward expect \u2014 aligned with those consumers after v0 lands a first shape.",
318
+ "kind": "unknown_nonblocking",
319
+ "claim_id": null
320
+ },
321
+ {
322
+ "id": "v2",
323
+ "text": "Context-gathering strategy for large repos (how much file tree / which files to surface up front) beyond on-demand read_file/list_dir.",
324
+ "kind": "unknown_nonblocking",
325
+ "claim_id": null
326
+ },
327
+ {
328
+ "id": "v3",
329
+ "text": "run_command sandboxing / resource limits \u2014 v0 trusts the operator's environment (D2); isolation is a later sandbox wheel.",
330
+ "kind": "out_of_scope",
331
+ "claim_id": null
332
+ }
333
+ ]
334
+ }