From aaf8cc5f7a2dcb748ca05504f3327c5ccd0514e1 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 26 Jul 2026 20:23:48 +0200 Subject: [PATCH] Scope first channel extension as GLAS-WP-0003, closing GLAS-WP-0002-T04 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 --- WORK-RECORDS.md | 4 +- ...servability-and-composability-followups.md | 8 +- .../GLAS-WP-0003-first-channel-extension.md | 86 +++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 workplans/GLAS-WP-0003-first-channel-extension.md diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 2d9e004..c185996 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -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 | diff --git a/workplans/GLAS-WP-0002-observability-and-composability-followups.md b/workplans/GLAS-WP-0002-observability-and-composability-followups.md index f9d6655..4b596c9 100644 --- a/workplans/GLAS-WP-0002-observability-and-composability-followups.md +++ b/workplans/GLAS-WP-0002-observability-and-composability-followups.md @@ -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" ``` diff --git a/workplans/GLAS-WP-0003-first-channel-extension.md b/workplans/GLAS-WP-0003-first-channel-extension.md new file mode 100644 index 0000000..7204e3b --- /dev/null +++ b/workplans/GLAS-WP-0003-first-channel-extension.md @@ -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 +```