Scope first channel extension as GLAS-WP-0003, closing GLAS-WP-0002-T04
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

GLAS-WP-0002 is now fully done (4/4): formalize the CLI as the first
Channel extension (contract + refactor + tests + second-channel
documentation), not building a second channel yet -- same
generalize-from-a-real-second-example discipline as ADR-002/ADR-004.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-26 20:23:48 +02:00
parent 8309c32a1b
commit aaf8cc5f7a
3 changed files with 95 additions and 3 deletions

View file

@ -20,7 +20,7 @@
| task | GLAS-WP-0001-T04 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
| task | GLAS-WP-0001-T05 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
| task | GLAS-WP-0001-T06 | done | — | workplans/GLAS-WP-0001-harness-router-foundation.md |
| task | GLAS-WP-0002-T01 | todo | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |
| task | GLAS-WP-0002-T02 | todo | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |
| task | GLAS-WP-0002-T01 | done | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |
| task | GLAS-WP-0002-T02 | wait | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |
| task | GLAS-WP-0002-T03 | done | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |
| task | GLAS-WP-0002-T04 | todo | — | workplans/GLAS-WP-0002-observability-and-composability-followups.md |

View file

@ -124,9 +124,15 @@ before a second channel is attempted). Produce a scoped follow-up
workplan (`GLAS-WP-0003` or later) rather than expanding this task
indefinitely.
**Done (2026-07-26).** Scoped as
`workplans/GLAS-WP-0003-first-channel-extension.md`: formalize the CLI
as the first `Channel` extension (contract + refactor + tests +
second-channel documentation), explicitly not building a second channel
now — same discipline as ADR-002/ADR-004.
```task
id: GLAS-WP-0002-T04
status: todo
status: done
priority: low
state_hub_task_id: "98d4be61-5923-4445-b1f8-5135ada13ad9"
```

View file

@ -0,0 +1,86 @@
---
id: GLAS-WP-0003
title: "First channel extension: formalize the CLI channel contract"
status: proposed
---
Scoped by `GLAS-WP-0002-T04`: of glas-harness's four charter pillars
(unified API, profile catalog, extension platform, observability),
"extension platform" is entirely unbuilt for channels — `glas_harness.cli`
is a channel in substance (a way a caller invokes a harness session) but
not in form (no `Channel` contract exists; it's just a CLI module).
This workplan does **one thing**: formalize the CLI as the first
channel extension, so the *contract* exists before a second channel
(Slack, HTTP, whatever) is attempted — not build a second channel now.
Same discipline as ADR-002/ADR-004: generalize from a real second
example, not in anticipation of one.
## Task: Define the Channel contract
A `Channel` mirrors `Rein`'s shape at a different layer: it turns an
external invocation (CLI args, a Slack message, an HTTP request) into
the `sandbox_profile`/`repo`/`title`/`description`/`rein` inputs
`run_task_through_rein` needs, and turns its `dict[str, Any]` result back
into whatever the invocation medium expects (stdout JSON for CLI, a
Slack reply, an HTTP response body). Minimal ABC:
```python
class Channel(ABC):
@abstractmethod
def parse_invocation(self, raw: Any) -> GatewayInvocation: ...
@abstractmethod
def render_result(self, result: dict[str, Any]) -> Any: ...
```
Document in `docs/channel-contract.md`, parallel to
`docs/harness-contract.md`.
```task
id: GLAS-WP-0003-T01
status: todo
priority: medium
```
## Task: Refactor glas_harness.cli into a CLIChannel
`src/glas_harness/channels/cli_channel.py`: `CLIChannel(Channel)`
implementing `parse_invocation` (argparse → `GatewayInvocation`) and
`render_result` (→ `json.dumps(..., indent=2)`, matching today's output
exactly — this is a refactor, not a behavior change). `cli.py` becomes a
thin `main()` that constructs a `CLIChannel` and calls it; existing CLI
usage and output are unchanged.
```task
id: GLAS-WP-0003-T02
status: todo
priority: medium
```
## Task: Tests + verify no behavior change
Unit tests for `CLIChannel.parse_invocation`/`render_result` in
isolation, plus re-running the existing live-proof commands (both
reins) to confirm identical CLI output before/after the refactor.
```task
id: GLAS-WP-0003-T03
status: todo
priority: medium
```
## Task: Document the pattern for a second channel
A short section in `docs/channel-contract.md` sketching what a second
channel (e.g. a Slack or HTTP channel) would need to implement,
without building one — this workplan stops at "the contract exists and
one real implementation proves it," matching the discipline applied
throughout this session's other deferred-until-a-second-example
decisions.
```task
id: GLAS-WP-0003-T04
status: todo
priority: low
```