Skip to content

Commit 92e76b9

Browse files
committed
chore: add architecton loop task artifacts
1 parent 9436bca commit 92e76b9

229 files changed

Lines changed: 48226 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
{
2+
"recorded": "2026-02-28",
3+
"task": "Task 0034 — pre-implementation baseline (mcp-bridge init wizard + templates)",
4+
"git_commit": "79e96a5 (HEAD main — style: fix cargo fmt formatting in mcp bridge and doctor modules)",
5+
"artifact": {
6+
"path": "target/release/great",
7+
"size_bytes": 8971264,
8+
"size_human": "8.556 MiB",
9+
"profile": {
10+
"lto": true,
11+
"strip": true,
12+
"codegen-units": 1
13+
}
14+
},
15+
"previous_baseline": {
16+
"recorded": "2026-02-28",
17+
"task": "Task 0030 — MCP Bridge Hardening (Item E: LTO+strip+codegen-units=1 applied)",
18+
"size_bytes": 8957728,
19+
"size_human": "8.543 MiB",
20+
"delta_bytes": 13536,
21+
"delta_pct": "+0.151%",
22+
"note": "Incremental drift between task 0030 and task 0034 pre-baseline. Within noise range."
23+
},
24+
"build_time": {
25+
"cold_release_s": 62.2,
26+
"note": "Full LTO cold build (re-timed 2026-02-28). Subsequent incremental builds ~1-2s."
27+
},
28+
"test_suite": {
29+
"unit_tests": 231,
30+
"integration_tests": 98,
31+
"hook_state_tests": 1,
32+
"total": 330,
33+
"ignored": 1,
34+
"wall_time_ms": 1778,
35+
"result": "all passed"
36+
},
37+
"template_sizes_bytes": {
38+
"ai-fullstack-py.toml": 420,
39+
"ai-fullstack-ts.toml": 462,
40+
"ai-minimal.toml": 226,
41+
"saas-multi-tenant.toml": 722,
42+
"total": 1830
43+
},
44+
"target_threshold_bytes": 13107200,
45+
"target_threshold_human": "12.5 MiB",
46+
"headroom_bytes": 4135936,
47+
"headroom_human": "3.944 MiB",
48+
"dependencies": {
49+
"runtime": [
50+
"clap 4.5",
51+
"anyhow 1.0",
52+
"serde 1.0",
53+
"serde_json 1.0",
54+
"toml 0.8",
55+
"tokio 1.0",
56+
"reqwest 0.12",
57+
"zip 2",
58+
"dirs 6.0",
59+
"colored 3.0",
60+
"indicatif 0.17",
61+
"regex 1.0",
62+
"toml_edit 0.22",
63+
"semver 1.0",
64+
"which 7",
65+
"rmcp 0.16",
66+
"uuid 1",
67+
"tracing 0.1",
68+
"tracing-subscriber 0.3",
69+
"schemars 1.0",
70+
"libc 0.2 (unix only)"
71+
],
72+
"dev": [
73+
"assert_cmd 2.0",
74+
"predicates 3.0",
75+
"tempfile 3.0"
76+
],
77+
"new_in_0034": "none expected — S-complexity text/config change only"
78+
},
79+
"duplicates": {
80+
"getrandom": ["0.2.17 (ring)", "0.3.4 (zip)", "0.4.1 (uuid, tempfile)"],
81+
"note": "Pre-existing triple getrandom. Unavoidable — ring/zip/uuid have incompatible version requirements."
82+
},
83+
"compiler_warnings": [
84+
"DEPRECATED: assert_cmd::Command::cargo_bin in tests/cli_smoke.rs — pre-existing, not a regression"
85+
],
86+
"site_bundle": {
87+
"recorded": "2026-02-28",
88+
"task": "Task 0036 — site-only content changes (first formal site baseline)",
89+
"vite_version": "7.3.1",
90+
"js_bundle_kb": 326.02,
91+
"js_bundle_gzip_kb": 104.16,
92+
"css_kb": 15.36,
93+
"css_gzip_kb": 3.80,
94+
"modules_transformed": 2046,
95+
"build_time_s": 2.06,
96+
"wall_time_s": 3.80,
97+
"previous_informal_baseline": {
98+
"source": "iter-030 memory",
99+
"js_bundle_kb": 326.03,
100+
"js_bundle_gzip_kb": 104.17,
101+
"delta_kb": -0.01,
102+
"delta_pct": "-0.003%",
103+
"verdict": "PASS — sub-byte rounding noise, content-only edit confirmed"
104+
},
105+
"threshold_warn_pct": 5,
106+
"threshold_block_pct": 10
107+
},
108+
"notes": "Pre-task-0034 baseline. 13,536-byte increase from task 0030 baseline is within noise. 12.5 MiB target met with 3.944 MiB headroom. Task 0034 is S-complexity (55 lines text/config); binary delta expected < 1 KB; no new dependencies expected. Site bundle formally baselined at task 0036: 326.02 kB JS (gzip: 104.16 kB)."
109+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# 0001: Platform Detection Engine
2+
3+
**Priority:** P0 (foundation -- everything else depends on this)
4+
**Type:** feature
5+
**Module:** `src/platform/`
6+
**Status:** pending
7+
8+
## Context
9+
10+
The current `src/platform/detection.rs` contains a minimal `Platform` enum with five flat variants (MacOS, Linux, Wsl, Windows, Unknown) and basic WSL detection via `/proc/version`. This must be enriched into a full detection engine that downstream modules (config, doctor, apply, init) can rely on for platform-aware behavior.
11+
12+
The legacy repo at `/home/isaac/src/great-sh/src/platform/detection.rs` contains extensive prior art including: rich `Platform` enum with per-variant fields, `Architecture` enum using `std::env::consts::ARCH`, `LinuxDistribution` detection from `/etc/os-release`, `command_exists()` via `which`, `detect_package_managers()`, admin/root detection, and GPU detection via `lspci`. This logic should be consulted and adapted -- not copied wholesale -- to fit the new monorepo's conventions (anyhow for errors, no unwrap, no panics).
13+
14+
## Requirements
15+
16+
1. **Enrich the `Platform` enum** to carry architecture (`Architecture` enum: ARM64, X86_64, Unknown), OS version string, and admin/root status as fields on each variant. The existing `Display` impl in `src/platform/mod.rs` must be updated to match.
17+
18+
2. **Detect all target platforms**: macOS ARM64 (Apple Silicon), macOS x86_64, Ubuntu bare metal, Ubuntu WSL2, other Linux distros (Debian, Fedora, Arch, RHEL at minimum). WSL2 detection must use a dual check: file existence at `/proc/sys/fs/binfmt_misc/WSLInterop` AND the `WSL_DISTRO_NAME` environment variable (either one triggers WSL2). This improves on the legacy check which only used `/proc/version`.
19+
20+
3. **Add a `PlatformCapabilities` struct** returned by a `detect_capabilities()` function with fields: `has_homebrew: bool`, `has_apt: bool`, `has_snap: bool`, `has_systemd: bool`, `is_wsl2: bool`, `gpu_available: bool`. Each capability is detected by probing the filesystem or PATH (e.g., `command_exists("brew")`, checking `/run/systemd/system` for systemd).
21+
22+
4. **Add utility functions**: `command_exists(name: &str) -> bool` (check PATH using `which` on Unix, `where` on Windows), `detect_architecture() -> Architecture` (using `std::env::consts::ARCH`), and `detect_linux_distro() -> LinuxDistribution` (parsing `/etc/os-release` for ID field).
23+
24+
5. **Safety invariant**: All detection functions must be safe -- no `.unwrap()`, no `panic!()`, no `expect()` in production paths. Return `Unknown` / `false` / default values on any IO or parse failure. Use `anyhow::Result` only where the caller needs to distinguish failure from unknown.
25+
26+
## Acceptance Criteria
27+
28+
- [ ] `cargo test` passes with unit tests covering: architecture detection returns a valid variant on the current machine, `command_exists("cargo")` returns true, `command_exists("nonexistent_binary_xyz")` returns false, WSL2 dual-check logic (mock or conditional), and `PlatformCapabilities` struct is populated without panics.
29+
- [ ] `cargo clippy` produces zero warnings for the `platform` module.
30+
- [ ] Running `great doctor` (or a test binary) on the current Linux machine correctly reports the architecture, distro, and capabilities.
31+
- [ ] No `.unwrap()` or `.expect()` calls exist anywhere in `src/platform/`.
32+
33+
## Dependencies
34+
35+
- None (this is the foundation layer).
36+
37+
## Notes
38+
39+
- The legacy repo's `detect_current_platform()` at `/home/isaac/src/great-sh/src/platform/detection.rs:980` is the closest prior art for the enriched platform detection function.
40+
- The legacy `command_exists()` at line 276 uses `which` -- this works on Linux/macOS but consider `std::process::Command::new(name).arg("--version")` as a cross-platform alternative if needed later.
41+
- The existing `src/platform/mod.rs` re-exports `detect_platform` and `Platform` and has a `Display` impl -- this must stay in sync with enum changes.
42+
- GPU detection can be basic for now (`lspci` grep for VGA/3D on Linux, `system_profiler SPDisplaysDataType` on macOS) -- it will be refined in a later iteration.
43+
- Consider adding `#[cfg(test)]` mock helpers for filesystem-dependent detection so tests run in CI without real `/etc/os-release`.

.tasks/done/0002-config-schema.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# 0002: TOML Config Parser -- great.toml Schema
2+
3+
**Priority:** P0 (foundation)
4+
**Type:** feature
5+
**Module:** `src/config/`
6+
**Status:** pending
7+
8+
## Context
9+
10+
The current `src/config/schema.rs` defines a minimal `GreatConfig` with flat `Vec` fields for tools, agents, and mcp. The TOML structure needs to match the product spec's section-based design (`[project]`, `[platform]`, `[tools]`, `[agents.*]`, `[mcp.*]`, `[secrets]`) using proper serde deserialization with HashMap-based named entries for agents and MCP servers.
11+
12+
The existing `src/config/mod.rs` already has working `load()`, `discover_config()`, `data_dir()`, and `config_dir()` functions. The schema upgrade must remain compatible with the existing `load()` pipeline (read file, `toml::from_str`).
13+
14+
The legacy repo at `/home/isaac/src/great-sh/src/core/config.rs` used JSON-based config with a different structure. The new schema is TOML-first and should not follow the legacy layout -- it should follow the `great.toml` spec.
15+
16+
## Requirements
17+
18+
1. **Define the complete `GreatConfig` struct** with serde `Deserialize` and `Serialize` derives. Top-level sections: `project: Option<ProjectConfig>`, `platform: Option<PlatformConfig>`, `tools: Option<ToolsConfig>`, `agents: Option<HashMap<String, AgentConfig>>`, `mcp: Option<HashMap<String, McpConfig>>`, `secrets: Option<SecretsConfig>`. Each section is optional so partial configs are valid.
19+
20+
2. **Define section structs**: `ProjectConfig` (name, version, description), `PlatformConfig` with optional sub-tables `macos: Option<MacOSConfig>` and `wsl2: Option<Wsl2Config>`, `ToolsConfig` with `cli: Option<Vec<ToolEntry>>` for declarative tool lists, `AgentConfig` (provider, model, api_key reference, enabled), `McpConfig` (command, args, env HashMap, enabled), `SecretsConfig` (provider, path). All string fields that may contain `${SECRET_NAME}` references should be typed as `String`.
21+
22+
3. **Implement validation on parse**: after deserialization, run a `validate()` method on `GreatConfig` that returns `anyhow::Result<Vec<String>>` where `Ok(warnings)` means valid with optional warnings (e.g., unknown keys logged as warnings) and `Err` means a required field is missing or invalid with an actionable error message (e.g., "agents.claude: missing 'provider' field -- set to 'anthropic' or 'openai'").
23+
24+
4. **Detect `${SECRET_NAME}` variable references**: add a `find_secret_refs(&self) -> Vec<String>` method that scans all string fields and returns a deduplicated list of secret names referenced. This does not resolve them -- just identifies them for the vault module to resolve later. Use the `regex` crate (already in deps) with pattern `\$\{([A-Z_][A-Z0-9_]*)\}`.
25+
26+
5. **Provide sensible defaults**: implement `Default` for all config structs so that `GreatConfig::default()` produces a minimal valid config. The `load()` function in `mod.rs` should continue to work unchanged -- schema changes are internal to the struct definitions.
27+
28+
## Acceptance Criteria
29+
30+
- [ ] A sample `great.toml` with all sections can be parsed into `GreatConfig` and serialized back to TOML without data loss (round-trip test).
31+
- [ ] Parsing a TOML file with a missing optional section (e.g., no `[secrets]`) succeeds and returns `None` for that field.
32+
- [ ] Parsing a malformed TOML file (syntax error) returns a clear `toml::de::Error` message, not a panic.
33+
- [ ] `find_secret_refs()` correctly extracts `["ANTHROPIC_KEY", "OPENAI_KEY"]` from a config containing `api_key = "${ANTHROPIC_KEY}"` and `api_key = "${OPENAI_KEY}"`.
34+
- [ ] Unit tests cover: valid full config, valid partial config (project-only), invalid TOML syntax, and secret reference extraction.
35+
36+
## Dependencies
37+
38+
- None directly, but task 0001 (platform detection) informs which `PlatformConfig` sub-tables are meaningful.
39+
- Existing `src/config/mod.rs` functions (`load`, `discover_config`, `data_dir`, `config_dir`) must continue to compile and work.
40+
41+
## Notes
42+
43+
- The current schema at `src/config/schema.rs` uses `Vec<ToolConfig>` etc. This needs to change to the HashMap/section-based approach. This is a breaking change to the struct layout but since all subcommands are stubs (`not yet implemented`), there are no downstream consumers to migrate.
44+
- The `toml` crate (0.8) supports `#[serde(deny_unknown_fields)]` but this is too strict for forward compatibility. Instead, use the default (ignore unknown fields) and log warnings in the `validate()` method.
45+
- Keep the `McpConfig` struct compatible with the MCP server JSON format used by Claude and other AI tools -- the `command`, `args`, `env` pattern is standard.
46+
- The `regex` crate is already in `Cargo.toml` dependencies.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# 0003: CLI Framework -- Shared Infrastructure
2+
3+
**Priority:** P0 (foundation)
4+
**Type:** feature
5+
**Module:** `src/cli/` + `src/main.rs`
6+
**Status:** done
7+
8+
## Context
9+
10+
The current CLI framework in `src/cli/mod.rs` defines a `Cli` struct with a `Command` enum dispatched in `src/main.rs`. All 10 subcommands are stubbed with `println!("not yet implemented")`. There are no shared output helpers, no global flags for verbosity or interactivity control, and no config auto-discovery wired into the dispatch pipeline.
11+
12+
The `colored` crate (3.0) and `indicatif` crate (0.17) are already in `Cargo.toml` dependencies but unused. The `config::discover_config()` function exists but is not called from `main.rs`.
13+
14+
## Requirements
15+
16+
1. **Colored output helper module** (`src/cli/output.rs`): Implement functions `success(msg: &str)`, `warning(msg: &str)`, `error(msg: &str)`, `info(msg: &str)` that print to stderr with consistent formatting. Success: green with check mark prefix. Warning: yellow with warning prefix. Error: red with X prefix. Info: blue with info prefix. Each function respects a global verbosity level -- `quiet` suppresses info and success, `verbose` is the default pass-through. Use the `colored` crate for ANSI color output.
17+
18+
2. **Progress spinner**: Add a `spinner(message: &str) -> ProgressBar` convenience function in `output.rs` that creates an `indicatif::ProgressBar` with a spinner style and the given message. Callers use `.finish_with_message()` when done. This gives all subcommands a consistent loading indicator.
19+
20+
3. **Global flags on the `Cli` struct**: Add `--verbose` (`-v`), `--quiet` (`-q`), and `--non-interactive` flags as clap args on the top-level `Cli` struct (not on each subcommand). These must be parsed before subcommand dispatch and made available to subcommand `run()` functions. Consider passing them via a shared `Context` struct or by storing them in a thread-local / static after parse.
21+
22+
4. **Config auto-discovery in dispatch**: In `main.rs`, after parsing CLI args but before dispatching to a subcommand, attempt `config::discover_config()`. If found, load it with `config::load()` and pass the `GreatConfig` (or `None` if not found) to subcommand handlers. The `init` subcommand should work without an existing config (it creates one). Other subcommands should warn if no config is found but not hard-fail (doctor, status can report "no config found").
23+
24+
5. **Wire output helpers into existing stubs**: Replace the `println!("... not yet implemented")` in each subcommand stub with `output::warning("... not yet implemented")` so all output immediately uses the new formatting system. Update each subcommand's `run()` signature if needed to accept the shared context.
25+
26+
## Acceptance Criteria
27+
28+
- [x] `output::success("done")` prints a green-colored line with check mark prefix to stderr, and `output::error("failed")` prints red with X prefix.
29+
- [x] `great --verbose status` and `great --quiet status` are both accepted by the CLI parser without errors (integration test via `assert_cmd`).
30+
- [x] Running `great status` from a directory without `great.toml` prints a warning (not a hard error/panic) and exits cleanly.
31+
- [x] Running `great init` from a directory without `great.toml` does not error on missing config (init creates config).
32+
- [x] All 10 existing subcommand stubs use `output::warning()` instead of raw `println!()`.
33+
34+
## Dependencies
35+
36+
- Task 0002 (config schema) should ideally land first or concurrently, since the config struct loaded in dispatch comes from that schema. However, the current minimal `GreatConfig` is sufficient to wire up the plumbing -- the schema can be enriched independently.
37+
38+
## Notes
39+
40+
- The `Cli` struct currently has no fields other than `command`. Adding global args means changing `Cli` to:
41+
```rust
42+
pub struct Cli {
43+
#[arg(short, long, global = true)]
44+
pub verbose: bool,
45+
#[arg(short, long, global = true)]
46+
pub quiet: bool,
47+
#[arg(long, global = true)]
48+
pub non_interactive: bool,
49+
#[command(subcommand)]
50+
pub command: Command,
51+
}
52+
```
53+
The `global = true` attribute makes these flags available before or after the subcommand name.
54+
- For the shared context pattern, a simple struct works:
55+
```rust
56+
pub struct Context {
57+
pub config: Option<GreatConfig>,
58+
pub verbose: bool,
59+
pub quiet: bool,
60+
pub non_interactive: bool,
61+
}
62+
```
63+
Each subcommand's `run()` changes from `run(args: Args) -> Result<()>` to `run(args: Args, ctx: &Context) -> Result<()>`.
64+
- The `colored` crate respects `NO_COLOR` env var automatically, which is good for CI environments.
65+
- Output goes to stderr so that stdout remains clean for machine-parseable output in future commands (e.g., `great status --json`).

0 commit comments

Comments
 (0)