Skip to content

Latest commit

 

History

History
1655 lines (1322 loc) · 191 KB

File metadata and controls

1655 lines (1322 loc) · 191 KB

한국어: progress.ko.md

Mirror sync policy: This file and progress.ko.md are structural/content mirrors. When you modify one, you must update the other to match in the same commit (or the immediately following commit). Full policy: CLAUDE.md §Bilingual Mirror Policy.

Genasis — Progress Tracker

Follows milestones from blueprint.md §15 (first-release scope) and §12 (repo structure). Each item uses [ ][x] on completion; blocked items are marked [!] with inline reason.

Started: 2026-05-03 Target first release: v0.1.0 (git tag after M14.0 ratification) Current milestone: M14 planning + Phase F design (Debug History feedback loop, ADR-012). M0–M12 + Phase D all complete. Phase F (M15–M17) designed 2026-05-05. v0.1.0 release tag after M14.0 (ADR-010 ratify).


Convention

  • Checkbox notation:
    • [ ] = not started
    • [~] = in progress
    • [x] = completed
    • [!] = blocked (state reason)
    • [s] = skipped (state reason)
  • New ADRs are written immediately upon discovery during work, in docs/ADR/
  • Decisions requiring blueprint.md changes get their own ADR first, then blueprint amendment

M0 — Bootstrap

Repo initial structure and progress tracking infra. Full source tree under genasis/, install.sh is a launcher only.

Top-level files

  • blueprint.md
  • progress.md
  • README.md
  • LICENSE (MIT)
  • .gitignore
  • .editorconfig
  • rustfmt.toml
  • clippy.toml
  • rust-toolchain.toml (1.78)

Workspace

  • Cargo.toml (workspace, 9 members)
  • Cargo.lock — rustup stable installed + cargo build green, then committed (14 crates compiled).

Crate stubs (Cargo.toml + minimal src skeleton)

  • crates/genasis-cli/ (main.rs + cmd_*.rs stubs ×11 + tui_attach.rs + scripts/)
  • crates/genasis-core/ (lib + config + env + fs + marker + error)
  • crates/genasis-overlay/ (lib + detector + role_inference + merger + validator + dry_run)
  • crates/genasis-providers/ (lib + plane/* + mattermost/* + github)
  • crates/genasis-db/ (lib + kernel + guard + adapters/*) — guard has first unit tests
  • crates/genasis-design/ (lib + extractor + change_protocol + diff + ticket_emitter)
  • crates/genasis-tui/ (lib + theme + layout + widgets/*)
  • crates/genasis-monitor/ (lib + app + state + widgets/* + actions/*)
  • crates/genasis-templates/ (lib + templates/ Tera dir skeleton)

install.sh launcher

  • OS/arch detection (linux x86_64/arm64, macOS arm64/x86_64, Windows→WSL guidance)
  • Linux distro detection (/etc/os-release)
  • Prerequisite check (required: git, curl, tar, bash / optional: node≥18, gh, atlas, psql/mysql/sqlite3/duckdb, rtk, claude)
  • Missing-package install commands per OS (apt, dnf, pacman, zypper, apk, brew, port, nvm)
  • GitHub Releases asset URL → download → sha256 verify → tar extract
  • Install to ~/.local/bin/genasis or /usr/local/bin/genasis + PATH guidance
  • --no-run, --prefix=PATH, --version=X.Y.Z, --skip-prereqs, -h/--help flags
  • Auto-invoke genasis attach at end (opt-out available)
  • Clean exit codes + explicit error messages on failure
  • Local smoke test (Ubuntu/apt) — OS/package detect + graceful fail verified

.github

  • .github/workflows/ci.yml
  • .github/workflows/release.yml (cross-rs for linux-arm64 cross-compile)
  • .github/workflows/nightly-e2e.yml
  • .github/ISSUE_TEMPLATE/bug.md
  • .github/ISSUE_TEMPLATE/feature.md
  • .github/PULL_REQUEST_TEMPLATE.md

docs

  • docs/ARCHITECTURE.md
  • docs/PROVIDERS.md
  • docs/MIGRATION-FROM-GENESIS.md
  • docs/TOKEN-ECONOMICS.md
  • docs/MONITOR.md
  • docs/ADR/ADR-000-template.md

tests

  • tests/golden/{ecc-only,kw-plugins,blank,legacy-bash-genesis,with-drizzle,with-duckdb}/{input,expected}/.gitkeep (6 fixtures)
  • tests/golden/SHARED.md (scenario table + conventions)
  • Per-fixture README.md ×6
  • tests/e2e/.gitkeep, tests/unit/.gitkeep

templates skeleton (Tera placeholders)

  • crates/genasis-templates/templates/GENASIS.md.tera
  • crates/genasis-templates/templates/genasis.toml.tera
  • crates/genasis-templates/templates/env.agents.tera
  • crates/genasis-templates/templates/mcp.json.tera
  • crates/genasis-templates/templates/design-system.md.tera
  • crates/genasis-templates/templates/agent-overlays/README.md + .gitkeep
  • crates/genasis-templates/templates/commands/README.md + .gitkeep
  • crates/genasis-templates/templates/skills/README.md + .gitkeep
  • crates/genasis-templates/templates/hooks/README.md + .gitkeep

Verification

  • cargo build --workspace green (14 crates) — verified after rustup stable install.
  • cargo test --workspace --no-fail-fast → 120 passed (28 suites).
  • bash install.sh --version=v0.0.0-test --no-run smoke — Ubuntu/apt detected, packages diagnosed, non-existent release graceful.

Retrospective

  • M0 retro: 1) install.sh per-distro package guide matrix took 70% of core effort — 7 managers × 9 packages. 2) include_dir!() embed for Tera means single-binary distribution. 3) No local Rust toolchain — increased CI dependency; first push → immediate CI check needed. 4) Marker fence hash uses 4-byte truncation: collision vs readability trade-off — revisit in M2.

M1 — Core Infra (genasis-core, genasis-cli skeleton)

genasis-core operational + CLI skeleton's first working command (version).

  • crates/genasis-core/ operational
    • config.rsgenasis.toml schema + load/save + parent-dir walk-up discover() (3 unit tests)
    • env.rs.env.agents read/write, comment/blank/quoting round-trip preserved (5 unit + 2 integration tests)
    • fs.rs — atomic write (sibling tmp + rename + dir fsync), snapshot, optional read (4 unit tests)
    • marker.rs — fence parse/serialise/hash/find/inject/replace/upsert/remove, idempotency guaranteed (10 unit + 4 integration tests)
    • error.rs — shared error type (NotImplemented, Io, Toml, Json, Config, Overlay, Provider, Db)
  • crates/genasis-cli/ operational
    • main.rs + clap v4 dispatch (12 subcommands wired)
    • [s] cmd_init.rs — placeholder (actual provisioning in M3)
    • [s] cmd_attach.rs — placeholder (M2)
    • [s] cmd_detach.rs — placeholder (M2)
    • [s] cmd_doctor.rs — placeholder (M8)
    • [s] cmd_upgrade.rs — placeholder (M8)
    • [s] cmd_design.rs — placeholder (M7)
    • [s] cmd_db.rs — placeholder (M5)
    • [s] cmd_monitor.rs — placeholder (M9)
    • cmd_version.rs — operational (--json option, outputs fence v1.0 / build profile / git_sha)
  • crates/genasis-overlay/role_inference.rs seeded (10 roles + Custom, slug round-trip guaranteed)
  • crates/genasis-db/guard.rs strengthened — comment removal, string-literal-aware split, EXPLAIN/ANALYZE/PRAGMA/SHOW/DESC/VALUES allowed, transaction control rejected (10 unit + 5 integration tests)
  • Unit tests: marker fence idempotency + env round-trip + role inference round-trip + SQL guard
  • Integration tests: crates/genasis-core/tests/{marker_idempotent,env_round_trip}.rs, crates/genasis-overlay/tests/role_inference.rs, crates/genasis-db/tests/sql_guard.rs
  • CI green — GitHub Actions CI success from commit b7bffaa.
  • ADR-001: Overlay = Marker Fence
  • ADR-002: Rust single binary

Retrospective

  • M1 retro: 1) Single-fence invariant in find() (BEGIN/END exactly one pair, else error) was correct early enforcement — duplicate fences are immediately rejected. 2) .env.agents comment preservation needs Vec<Line> enum, not IndexMap — lower-level representation. 3) SQL guard's string-literal-aware split uses hand-rolled lexer, simpler than sqlparser-rs dependency (only regex needed). 4) Workspace dev-dependencies declared per-crate — pulled tempfile up to workspace dep with tempfile.workspace = true.

M2 — Detector + Overlay Merger

Existing team asset recognition and fence injection engine.

  • crates/genasis-core/src/frontmatter.rs (YAML head/body splitter + scalar reader, 6 unit tests)
  • crates/genasis-overlay/ operational
    • detector.rs.claude/agents/*.md scan, classify, has_existing_fence detection (4 unit tests)
    • role_inference.rs — 10 roles + Custom (seeded M1, integrated M2)
    • merger.rsplan_attach / plan_detach / apply (3-phase: plan→apply→report) — Tera-based fence body rendering, snapshot then atomic write (3 unit tests)
    • validator.rsFenceState (Absent/Pristine/Outdated/Tampered/RoleMismatch) + WriteDecision (5 unit tests)
    • dry_run.rssummary (one-line glyph format) + unified_diff (via similar) + counts (3 unit tests)
  • Golden fixture: tests/golden/ecc-only/input/ (3 agent files — frontend canonical / backend canonical / loop-operator custom). Other 4 fixtures deferred to M6 (meaningful expected/ snapshots require all role templates).
  • crates/genasis-templates/templates/agent-overlays/frontend.patch.md.tera (first real template)
  • cmd_attach.rs operational — --project / --dry-run / --diff / --force / --fence-version options + summary/diff output + apply (Plane/MM calls added in M3)
  • cmd_detach.rs operational — --project / --dry-run / --diff options
  • E2E: crates/genasis-overlay/tests/golden_ecc_only.rs — round-trip equality + double-attach idempotency (2 integration tests)

Retrospective

  • M2 retro: 1) Tera embed via include_dir!() validated — auto-discovered at build time, no manifest needed. 2) Validator's 5-state FenceState is essential: Pristine/Outdated/Tampered/RoleMismatch must be explicitly distinguished for --force semantics. 3) MergePlan plan/apply separation gives dry-run as a natural byproduct. 4) similar crate's TextDiff::from_lines is sufficient for unified diff — no git-style hunk headers needed. 5) AppliedReport returning backup paths enables future genasis upgrade --rollback.

M3 — Plane / Mattermost Providers (direct API)

  • crates/genasis-providers/plane/{mod,upstream,agent_aware,detect,factory}.rs operational
  • crates/genasis-providers/mattermost/{mod,upstream,agent_aware,detect,factory}.rs operational
  • github.rsgh CLI wrapper + branch-protection helper
  • cmd_init.rs operational — config load → Plane health → MM ping → optional --probe-only, project + label provisioning
  • cmd_plane.rs / cmd_mm.rs health/ping debug subcommands
  • tests/flavor_parse.rs integration test
  • ADR-003 (direct API) + ADR-005 (Flavor system)

Retrospective

  • M3 retro: agent-aware is near-identical to upstream — delegation pattern overwhelmingly simple. Flavor detection is one response header line; mock-HTTP integration tests deferred (nightly E2E against real instances is more meaningful).

M4 — Plane User Provisioner (Playwright Node sub-process)

  • crates/genasis-cli/scripts/provision-plane-users.mjs — stdio JSON protocol + Playwright import + stub responses
  • crates/genasis-providers/src/plane/user_provisioner.rs — Rust spawn + stdin write + stdout parse + exit code handling
  • Explicit error messages on failure (Node missing / Playwright missing / JSON parse failure)

Retrospective

  • M4 retro: stdio JSON envelope as the single process-boundary contract — testable on both sides. Actual UI automation code is incrementally ported from Genesis bash assets (first release stays at stub stage).

M5 — Schema Kernel & DB Adapters

  • crates/genasis-db/kernel.rs — Driver enum + MigrationTool enum + parse + dispatch
  • crates/genasis-db/adapters/{postgres,mysql,sqlite,duckdb,atlas,drizzle_kit,raw_runner}.rs operational
  • crates/genasis-db/guard.rs strengthened (seeded M1, M5 integration)
  • cmd_db.rs operational — query / schema / migrate / diff / status / doctor subcommands
  • ADR-004 (DB channel separation)
  • [s] Mock HTTP server integration tests deferred (each driver CLI must be host-installed to be meaningful — verified in nightly CI)

Retrospective

  • M5 retro: Atlas is the declarative default; drizzle-kit auto-delegates when drizzle.config.ts exists in user repo; DuckDB falls back to raw_runner. URL redaction added to status output to prevent secret leaks.

M6 — Hooks · Skills · Commands templates

  • templates/agent-overlays/*.patch.md.tera ×10 (frontend from M2 + 9 added)
  • templates/commands/*.md.tera ×16 (sprint-, intake-review, issue-, design-change, db-, agent-, check-inbox, record-progress)
  • templates/skills/<name>/SKILL.md.tera ×6 (scrum-protocol, plane-ops, mm-ops, design-aware, schema-ops, tdd-enforce)
  • templates/hooks/*.tera ×6 (session-start, pre-tool-branch-guard, pre-tool-worktree-guard, post-tool-mm-sync, post-tool-trim, user-prompt-submit-mm)
  • templates/mcp.json.tera (Playwright only — authored M0)
  • templates/env.agents.tera (authored M0)

Retrospective

  • M6 retro: 9 role overlays are thin variants of frontend — only token/bot env-var names differ, lifecycle contract is identical. 16 slash commands are thin pointers delegating to GENASIS.md as single source.

M7 — Design Hot-Swap

  • crates/genasis-design/extractor.rssnapshot_existing + write_design_system
  • crates/genasis-design/diff.rsImpactArea enum + keyword categorisation + changed_areas
  • crates/genasis-design/ticket_emitter.rsPlannedIssue plan
  • crates/genasis-design/change_protocol.rs — 5-phase run orchestrator
  • cmd_design.rs swap / status operational
  • [s] Golden design-swap fixture deferred (replaced by real migration data at M11)

Retrospective

  • M7 retro: Extractor delegates to designer agent's ui-style-extractor skill — Genasis does not self-implement CSS parsing. 6 impact areas (color-tokens, typography, spacing, layout, components, motion) + Other fallback. Line-level keyword categorisation generates one issue per changed area.

M8 — Doctor / Upgrade / Detach polish

  • cmd_doctor.rs — required/optional tool checks, Genasis asset existence, config load, env secret presence
  • cmd_upgrade.rs — fence-version arg + dry-run/diff/force options, Tampered/RoleMismatch guard
  • cmd_detach.rs — completed in M2 (dry-run/diff options included)

Retrospective

  • M8 retro: doctor mirrors install.sh's check matrix in Rust — protects even when users bypass install.sh. upgrade is a thin wrapper on attach but warrants a separate command (version bump is explicitly visible intent).

M9 — Monitor (Ratatui TUI)

  • crates/genasis-monitor/app.rs — main loop, alternate-screen / raw-mode, 250ms poll
  • widgets/{sprint,tokens,agents,deploy,network,log_tail}.rs ×6 operational
  • widgets/deploy.rs — dev/prod LEDs + REFRESHED badge + deploy action key hints
  • state.rs — AppState + AgentActivity + DeployState + WidgetFocus
  • cmd_monitor.rs — delegates to genasis_monitor::app::run
  • ADR-007 (Monitor TUI first-release inclusion)
  • [s] Live data source ingest (rtk gain, Plane API poll, manifest watch) is incremental — first release covers widget skeleton

Retrospective

  • M9 retro: ratatui 0.27's Frame::area() + Layout::default().constraints(...) simplifies 4-row grid. 250ms poll is the right trade-off (CPU <1%, key response immediate). Data ingest will use hook+agent-emitted JSON lines via file-tail, added incrementally.

M10 — Token Economics wrap-up

  • templates/hooks/session-start.sh.tera — RTK detection + design-bootstrap flag surface
  • templates/hooks/post-tool-trim.sh.tera${GENASIS_TRIM_THRESHOLD_KB:-32} threshold
  • genasis.toml [token_economics] trim_threshold_kb = 32 schema (authored M0, wired M10)
  • ADR-006 (Token Economics)

Retrospective

  • M10 retro: No self-hosted mcp-proxy in v1 is the right call — maintenance burden vs visible impact unfavorable. RTK + Anthropic prompt cache + trim hook 3-tier achieves 80% of the benefit with lifecycle simplicity.

M11 — Migration & Release

  • cmd_plane, cmd_mm debug subcommands (health/ping)
  • docs/ADR/ADR-001 ~ ADR-007 — all 7 ADRs written
  • docs/PROVIDERS.md updated (authored M0, flavor guide aligned with M3)
  • docs/MIGRATION-FROM-GENESIS.md updated (authored M0, mapping table aligned)
  • [s] Full cmd migrate-from-genesis implementation deferred — requires real Genesis bash team operational data. First-release is docs-only.
  • [s] GitHub Release first cross-compile / demo video / v0.1.0 tag — triggers on first PR merge to release pipeline.

Retrospective

  • M11 retro: All milestone code/docs in place. Remaining: (a) run one real sprint to validate data-ingest hooks, (b) verify cross-compile end-to-end via install.sh, (c) cut v0.1.0 tag.

M12 — Internationalization (install-time language selector + active singularity)

Per blueprint §19 decisions:

  • User repo agent context is always single-language (--lang en|ko)
  • Tera template tree split to templates/{en,ko}/ + genasis lang switch provided
  • Runtime i18n: rust-i18n — new crate genasis-i18n (lighter than fluent-rs by ~150KB for ~50 messages)
  • install.sh also branches on --lang: inline case block (zero dependencies)
  • --lang both rejected + cites docs/impact-of-multilang-prompts.md
  • CI 3-tier: normal PR warn / release-prep strict / auto translation-completion PR

Rationale: docs/impact-of-multilang-prompts.md (Claude Code language drift bugs #46846/#24941, arXiv 2406.20052 Korean line-level confusion, OSS ecosystem single-language consensus, prompt cache prefix conflict).

Required human approval before start — approved M12 v5, 2026-05-04.

M12.0 — Human approval gate

  • blueprint.md §19 + docs/impact-of-multilang-prompts.md reviewed + approved (M12 v5 plan, 2026-05-04)
  • ADR-008 draft written and merged (install-time language selector + active singularity, commit e8b3793)

M12.1 — i18n infra (runtime — rust-i18n)

  • crates/genasis-i18n/ new crate (commit 9a12ed6)
    • Cargo.toml (deps: rust-i18n = "3", once_cell)
    • src/lib.rsLang enum (En/Ko), resolve() (CLI flag / toml / env / $LANG / fallback en), install() calls rust_i18n::set_locale, LangSource diagnostic enum
    • i18n!("locales", fallback = "en") macro root declaration, t! re-export
    • locales/en.yml (key definition source — 49 keys, 12 namespaces)
    • locales/ko.yml (Korean mirror, 100% parity, _meta.bcp47 specified)
  • Cargo.toml workspace member added + dependency registered (rust-i18n = "3", once_cell = "1", internal alias)
  • Unit tests: tests/i18n_lookup.rsLang::parse (canonical/case-insensitive/locale modifier/friendly names/unknown reject), resolve() 5-tier priority + unknown skip-through, t! macro en/ko render + fallback semantics, Lang::code round-trip, LangSource::label. 16 #[test], serial-mutex for process-global state.

M12.2 — Rust user-facing messages i18n (t!() macro)

  • genasis-cli prose messages wrapped via t!() (commit 17b6b99). Structured debug/JSON dump lines intentionally kept in English — grep/IDE friendly + cmd_doctor diagnostic key=value form preserved.
    • cmd_attach.rs (refused, wrote_summary)
    • cmd_detach.rs (wrote_summary)
    • cmd_upgrade.rs (refused, wrote_summary)
    • cmd_init.rs (resolving_plane, resolving_mm, ensure_project, ensure_channel, next_step, mm_team_id_missing, probe_only_skip)
    • cmd_doctor.rs (section headers, pass/warn/error)
    • cmd_design.rs (swap messages)
    • cmd_version.rs (label strings)
  • genasis-monitor/ TUI labels i18n (widget titles, footer hints)

M12.3 — Tera template tree split (templates/{en,ko}/) — ✅ commit 1fd1e6d

  • Flat templates/ directory reorganised to templates/{en,ko}/ parallel subtrees
  • All overlay / command / skill / hook / top-level templates duplicated to both subtrees
  • genasis-templates::lib.rs include_dir!() unchanged (auto-embeds new structure)
  • build_tera_lang(lang) plumbed through merger, fetches from <lang>/agent-overlays/
  • Parity test: english_and_korean_have_same_top_level_files

M12.4 — genasis init / attach / detach --lang + interactive prompt — ✅ commits 39d1032, e2e added

  • Global --lang <en|ko> clap flag on CLI root (not per-subcommand)
  • TTY interactive prompt (bilingual banner) when --lang omitted + stdin is a TTY
  • Non-TTY fallback: $LANGen default
  • --lang both rejection with bilingual banner citing docs/impact-of-multilang-prompts.md
  • --non-interactive / --yes bypass for CI
  • genasis.toml [i18n].active persisted on first attach
  • Integration tests: tests/install_lang_e2e.rs (flag_en, flag_ko, both_rejected, non_tty_fallback, lang_status, lang_switch_no_op)

M12.5 — genasis lang switch <lang> new command — ✅ commit 39d1032

  • Atomic swap: re-renders all templates/<new-lang>/.claude/genasis/{skills,commands,hooks}/ + GENASIS.md
  • Fence-internal-only update policy: user edits outside fences preserved
  • genasis.toml [i18n].active updated
  • genasis lang status — reports active locale + reference docs path

M12.6 — install.sh --lang branch + interactive prompt (Bash) — ✅ commit 54ed32e

  • --lang en|ko|both parsing
  • --lang both bilingual rejection message (no dependency)
  • Interactive TTY prompt when --lang omitted (mirrors Rust CLI UX)
  • Passes resolved --lang to post-install genasis attach invocation
  • bash -n syntax-check green
  • [s] Full round-trip (en → ko → en + fence hash equality) — git commit not wrapped inside lang switch (tests run outside git repo), only partial E2E. Revisit at M12.13 release polish.

M12.7 — Document dual tree (rename + translate + cross-link)

M12.7.a Rename pass — ✅ commit ea1e9d6

  • README.md / blueprint.md / progress.md*.ko.md (git mv)
  • docs/{ARCHITECTURE,PROVIDERS,MIGRATION-FROM-GENESIS,TOKEN-ECONOMICS,MONITOR}.mddocs/ko/
  • docs/impact-of-multilang-prompts.md mirror (docs/ko/impact-of-multilang-prompts.md)
  • docs/ADR/ADR-000 ~ ADR-007 (8 files) → docs/ko/ADR/

M12.7.b Translate pass — ✅ commits ccc1cac, b268d6f, 7c05d94, 23251ae, ea1e9d6

  • README.md (English) — 18-section SEO structure + bilingual badge row + Star History
  • blueprint.md (English) — TL;DR + section index + i18n decision summary (full §0–§19 body at release polish stage)
  • progress.md (English) — milestone summary + M12 sub-step status table
  • docs/ARCHITECTURE.md — TL;DR + source tree map + ASCII layer diagram + ADR cross-link
  • docs/PROVIDERS.md — flavor system + 5-step add recipe + detection priority + sample toml
  • docs/MIGRATION-FROM-GENESIS.md — mapping table + step-by-step CLI flow
  • docs/TOKEN-ECONOMICS.md — 3-tier model + 1.0 exclusion rationale
  • docs/MONITOR.md — 6-widget table + key bindings + i18n flow
  • docs/impact-of-multilang-prompts.md (M12 pre-stage artifact)
  • docs/ADR/ADR-008-i18n-install-time-selector.md new English + Korean stub mirror
  • [s] docs/ADR/ADR-001 ~ ADR-007 English body — Korean canonical is single source. English mirrors written at release polish (each ADR's Korean body is short + code/table-heavy, absorbed by release-prep auto-PR).
  • Code blocks / env vars / CLI commands / external URLs left untranslated (lint-i18n verifies via grep)

M12.7.c Cross-link pass — ✅ commit ea1e9d6, ccc1cac

  • All English source files: top cross-link batch
  • All Korean mirrors: top > English: ... batch (M12.7.b-completed files: "(English version pending)" caveat removed)
  • Root README.md top bilingual badge row (shields.io English / 한국어 / Add a language) + cross-link batch
  • Root README.ko.md top same toggle (current language bolded)

M12.8 — Golden fixture added + cleanup — ✅ commit ea1e9d6

  • tests/golden/with-ko-locale/{input,expected}/ + README new
  • Existing 6 fixtures remain English-only
  • tests/golden/SHARED.mdwith-ko-locale scenario row added
  • expected/ snapshot populated — genasis attach --lang ko --non-interactive --yes. Korean fence body confirmed ((Genasis Overlay) Plane / Mattermost 프로토콜).

M12.9 — .github English-only verification — ✅ commit ea1e9d6

  • All workflow YAML + issue/PR templates confirmed English-only
  • No i18n overhead in CI config

M12.10 — CI 3-tier guard + drift script + Translation Completion automation — ✅ commit ea1e9d6, 022ca37

  • scripts/check-i18n-drift.sh (--warn/--strict/--list/--check-mirror-not-empty)
  • scripts/i18n-extract-keys.sh (fluent key parity)
  • ci.yml lint-i18n job (warn)
  • release.yml lint-i18n-strict job (hard-fail)
  • release.yml auto-opens [i18n] Translation completion for vX.Y.Z PR when drift detected

M12.11 — genasis doctor [i18n] extension — ✅ commit ea1e9d6

  • Active locale reported
  • Template tree presence verified for active locale
  • Drift check (calls check-i18n-drift.sh --list inline)
  • Key parity check (calls i18n-extract-keys.sh)
  • Integration test: lang_status_reports_active_locale

M12.12 — Retrospective + DoD

  • lint-i18n CI passes — lint-i18n job, lint-i18n-strict both authored, CI success verified at commit b7bffaa
  • release-prep workflow — workflow_dispatch with v0.1.0 trigger success, drift=0 correct needs_pr=false branch
  • drift 0 — scripts/check-i18n-drift.sh --strict clean (all mirrors synced)
  • genasis doctor [i18n] section green — lang_status_reports_active_locale E2E passes
  • E2E auto-test scenarios — tests/install_lang_e2e.rs 6 tests (flag_en/flag_ko/both_rejected/non_tty_fallback/lang_status/lang_switch_no_op)
  • install.sh --lang ko Bash branch + bash -n passes
  • with-ko-locale golden fixture (input + README + SHARED.md row)
  • README.md / README.ko.md 18-section SEO + 3-step toggle applied
  • GitHub repo Topics ×18 registered (REST API)
  • GitHub Pages routing enabled (REST API, from b7bffaa build success)
  • M12 retro — commit 158aada body + inline retro items in this progress file

M12.13 — README SEO + multilingual toggle (blueprint §19.13)

M12.13.a README.md (English) SEO optimisation + structure rewrite — ✅ commits 2e9cdd8, 7c05d94

  • 18-section structure (§19.13.5 compliance)
  • H1 + tagline + badge row above the fold
  • "Why Genasis" narrative section
  • Architecture mermaid flowchart
  • Comparison table (Genasis vs ECC vs kw-plugins vs claude-code-templates)
  • Documentation index table (en/ko dual links)
  • Status section linking to progress tracker
  • Contributing section with prerequisite pointer

M12.13.b Multilingual toggle 3-step fallback — ✅ commit 2e9cdd8

  • Badge row (shields.io) at top — English / 한국어 / Add a language
  • Cross-link in first paragraph
  • Bottom navigation: same 3-way toggle

M12.13.c README.ko.md (Korean mirror) — ✅ commit 2e9cdd8

  • Same 18-section structure, Korean body
  • Badge row mirrors English (current language bolded)
  • All internal links point to *.ko.md / docs/ko/ counterparts

M12.13.d GitHub repo metadata — ✅ API call

  • 18 GitHub Topics registered via REST API
  • [s] Social preview image upload — REST API unsupported, Web UI only. docs/assets/og-image.png prepared for user to upload via Settings → Social preview. M12.13.h Pages OG meta works first.

M12.13.e Open Graph + visual assets — ✅ commits 2e9cdd8, 23251ae, follow-up

  • docs/assets/og-image.png (English)
  • docs/assets/og-image.ko.png (Korean)
  • Jekyll _config.yml OG meta tags
  • <head> OG tags in Pages layout

M12.13.f Auto SEO signals (badges) — ✅ commit 2e9cdd8

  • CI badge (shields.io + GitHub Actions)
  • Release badge (pre-release aware)
  • License badge
  • Stars badge
  • Coverage badge (Codecov)
  • Rust version badge
  • Star History chart (dark/light mode)

M12.13.g Multilingual contributor guide — ✅ commit ea1e9d6

  • docs/i18n/CONTRIBUTE-LANG.md — 4-step procedure (README + docs + templates + i18n bundle)
  • Referenced from CONTRIBUTING.md and README.md

M12.13.h GitHub Pages auto-routing — ✅ commits 2e9cdd8 + Pages enable API

  • Pages enabled via REST API
  • Accept-Language header → /ko/ /en/ branch (Jekyll _config.yml)
  • JSON-LD SoftwareApplication schema
  • Jekyll sitemap plugin
  • [s] Custom domain — user decision (CNAME + DNS setup needed).

M12.13.i Measurement + retro hook

  • [s] GitHub Insights baseline — repo just published so baseline = 0. First measurement meaningful after 1 week.
  • [s] Google Search Console — Pages domain verify (DNS TXT or HTML meta) needed. User proceeds in their GSC account.
  • [s] 3-month retro — operational item, calendar reminder. Retrospective issue template written at v0.1.0 tag.

M-D — Design Catalog Integration (post-M12)

User-approved 2026-05-04. External design provider (getdesign npm) delegation + two-mode design-system.md (pristine / external-pointer) + user-override accumulation + pristine restore + non-npx --from <path> entry point.

Key design decisions

  • No vendoring: awesome-design-md content is not re-owned. npx getdesign add <slug> delegation. License compliance is getdesign upstream's responsibility.
  • Two modes: docs/design-system.md at mode = pristine has body as truth; at mode = external has §A pointer (external DESIGN.md) + §B user overrides + §C usage manual only.
  • External DESIGN.md location: docs/design-system/DESIGN.md. Read-only treatment.
  • State file: docs/.design-state.toml (mode/slug/source/template_hash/applied_at/previous_slug/gallery_preview/override_count).
  • Backup: pristine body backed up to docs/design-system/pristine.bak before swap. restore moves docs/design-system/ to docs/design-system.archive-<ts>/ then restores from backup.
  • Issue flood policy: changed_areas.len() ≥ 4 triggers auto EPIC mode (1 EPIC + N children). Child descriptions include EPIC ID (Plane upstream compatible). --per-area / --full-rewrite explicit flags exposed.
  • Telemetry default OFF: genasis design swap auto-sets GETDESIGN_DISABLE_TELEMETRY=1. User can enable via [design].disable_telemetry = false or --telemetry on. No genasis-side collection server.
  • Gallery abstraction: genasis.toml [design] add_command template ({slug}, {out} substitution) allows replacing getdesign with a self-hosted gallery without code changes.

M-D1 — Pristine/External mode + swap/restore + skill (done 2026-05-04)

  • genasis-core Config gains [design] DesignConfig (gallery_index_url, gallery_url_template, add_command, disable_telemetry, external_dir)
  • genasis-design crate restructured:
    • mode.rsMode::Pristine | Mode::External, .design-state.toml R/W
    • swap.rs — slug mode (npx invoke) + --from <path> mode (file copy) unified entry
    • restore.rs — external→pristine restore (archive move + pristine.bak → design-system.md)
    • pointer.rs — design-system.md pointer body render (§A/§B/§C skeleton) — locale branch (en/ko in-source templates)
    • Existing extractor.rs / change_protocol.rs / diff.rs / ticket_emitter.rs preserved; legacy entry point aliased as run_legacy_swap
  • CLI cmd_design.rs extended:
    • swap <slug> (backward-compatible with swap <url> --body--body legacy path kept)
    • swap --from <path>
    • restore
    • status output includes mode/slug/applied_at/override_count/preview URL
  • Templates:
    • [s] design-system.md.tera two-variant split deferred — pointer body generated by pointer.rs::render in code, Tera split unnecessary. Attach emits placeholder; swap overwrites on external mode entry.
    • templates/{en,ko}/skills/design-aware/SKILL.md.tera strengthened: reference order (pristine → external §A → §B), user-request conflict procedure, external DESIGN.md direct-edit prohibition, post-swap guidance
  • i18n keys: design.swap.delegating, design.swap.from_local, design.swap.pristine_backed_up, design.swap.design_md_written, design.swap.pointer_written, design.swap.state_updated, design.swap.post_swap_*, design.status.mode_pristine, design.status.mode_external, design.restore.* etc. (14 keys × 2 locales)
  • E2E (crates/genasis-design/tests/swap_restore_round_trip.rs): pristine → swap slug → swap slug 2 → restore round-trip + sha256 verification
  • cargo test green (132 → 145 passed)

M-D2 — EPIC plan + Mattermost + user-override accumulation (done 2026-05-04)

  • ticket_emitter gains Plan::FullRewrite { epic, children } + PlanMode::{Auto, PerArea, FullRewrite}, auto threshold DEFAULT_FULL_REWRITE_THRESHOLD = 4 (majority of 7 areas)
  • Child description includes EPIC title — Plane upstream (no native parent_id) board bundle visibility
  • Mattermost announce template (CLI emits body; actual post is caller/provider): 🚨 DESIGN CHANGE: <from> → <to> | preview: <url> | issues planned: <n>
  • genasis design verify (crates/genasis-design/src/verify.rs) — .design-state.toml.template_hash vs actual DESIGN.md sha256, tamper detection
  • genasis design override add "<text>" (crates/genasis-design/src/override_log.rs):
    • Two sentinel comments recognized (en/ko)
    • #### override-<id> @ <iso> block appended, override_count incremented
    • [s] §A grep+citation is design-aware SKILL agent responsibility — CLI only records body
  • genasis design override list / remove <id>
  • E2E (crates/genasis-design/tests/epic_plan_and_overrides.rs): full-rewrite EPIC verification, 3 overrides accumulated then swap resets §B.2 (intentional — user re-reviews against new §A, guided by design-aware SKILL) + tamper detection

M-D3 — Monitor widget + attach prompt + doctor + ADR (done 2026-05-04)

  • AppState.design: DesignWidgetState (mode/slug/applied_at/override_count/preview_url/gallery_url)
  • widgets/design.rs — pristine/external branch render, key 7 focus, Enter opens preview URL via open/xdg-open/cmd /C start
  • app.rs layout: Design panel added (below Deploy row, 7-line slot)
  • cmd_attach.rs auto-seeds [design] defaults into genasis.toml on first attach (gallery_index_url, gallery_url_template, add_command, disable_telemetry=true, external_dir). Preserved if already present (idempotent). Interactive prompt omitted for i18n/non-interactive consistency — user edits genasis.toml later for gallery swap.
  • cmd_doctor.rs [design] section:
    • Mode output (pristine / external + slug)
    • npx availability — optional when pristine, required-missing warning when external
    • External mode: run_verify re-invoked for hash match
    • Mode/disk coherence — pointer/external-dir missing detection
  • docs/ADR/ADR-009-design-catalog-delegation.md (en) + docs/ko/ADR/ADR-009-... (ko) — no-vendor rationale / two-mode justification / gallery URL abstraction / telemetry default off / conflict resolution policy / 3 alternatives reviewed
  • Doctor i18n keys (en/ko): doctor.design.section, mode_pristine, mode_external, npx_missing_optional, npx_missing_required, verify_ok, verify_tampered, verify_error, pointer_missing, extdir_missing. Monitor key hint update ([1-7] focus, [Enter] open URL)
  • [s] Manual TUI smoke — code-path unit verified + state load fallback. Actual key-input testing at first v0.1.0 cross-compile.
  • cargo test + lang drift pass

M14 — Default agentic team bootstrap (green-field install)

2026-05-05 user-flagged. The overlay engine currently assumes .claude/agents/*.md files already existattach injects a fence into a user-authored file. When a project has no agent team at all, the canonical 10 ECC roles cannot be scaffolded, leaving the "non-destructive overlay" promise without a green-field entry point. M14 fills that gap — base agent template (rendered when role file is missing) beneath the existing patch overlay (rendered into the marker fence), forming a 2-layer structure.

Key design decisions (ADR-010 candidate)

  • Default OFF: bootstrap is opt-in (--bootstrap). Existing users running attach against an empty .claude/agents/ get a warning, not silent file creation. ADR-001 non-destructive invariant preserved.
  • Base + patch ownership separation: Base file (post-emit) is fully user-owned (free to edit). Only the marker fence inside it is genasis-owned (upgraded by upgrade). ADR-001 "fence-outside = user zone" promise consistently maintained.
  • No ECC vendor: Base templates are intentionally thin stubs — frontmatter (name/description/tools/model/color) + 5–10 line header. Not a fork of claude-code-templates / ECC role definitions. Patch fence fills protocol body later.
  • i18n split tree: templates/en/agents/<role>.md.tera + templates/ko/agents/<role>.md.tera 2 trees. lang switch swaps base too (but preserves user edits outside fence — existing fence-internal-only policy).
  • Role set: pm / planner / architect / frontend / backend / qa / designer / security / devops / code-reviewer (same 10 as M2's Role::ALL).

M14.0 — Decision gate + ADR-010

  • docs/ko/ADR/ADR-010-default-team-bootstrap.md (Korean SSOT): context, alternatives (a~f), decision (b+d, e-rejected), consequences, references (ADR-001 marker fence + ADR-008 lang precedence)
  • docs/ADR/ADR-010-default-team-bootstrap.md English mirror
  • blueprint.ko.md §20 new section (M14, ADR-010 cited) + blueprint.md section index updated
  • blueprint.ko.md §16 ADR table: ADR-008/009/010 rows added
  • User ratify gate — ratified 2026-05-08 (entry point: new genasis bootstrap subcommand + genasis init --bootstrap alias, auto-chains to cmd_attach unless --no-attach-after; ADR-010 §3 decision (b)+(d))

M14.1 — Base agent templates (templates/{en,ko}/agents/<role>.md.tera) — ✅ pending build verification

  • crates/genasis-templates/templates/en/agents/ directory created
    • pm.md.tera (frontmatter + 5–10 line role header)
    • planner.md.tera
    • architect.md.tera
    • frontend.md.tera
    • backend.md.tera
    • qa.md.tera
    • designer.md.tera
    • security.md.tera
    • devops.md.tera
    • code-reviewer.md.tera
    • README.md — base vs patch boundary explained, user-edit zone specified
  • crates/genasis-templates/templates/ko/agents/ — same 11 files (10 base + README, Korean body + identical frontmatter, description: in Korean)
  • genasis-templates::lib.rs include_dir!() auto-embeds new directory (directory addition only — no manifest update needed)
  • agent_base_subtrees_have_same_roles test — verifies both locales have all 10 required role tera files
  • [s] Frontmatter contract unit test covered by bootstrap.rs::tests::rendered_base_carries_required_frontmatter_keys (rendered base verified for 5 keys + name: matches stem)

M14.2 — genasis-overlay::bootstrap module — ✅ pending build verification

  • crates/genasis-overlay/src/bootstrap.rs new module
    • BootstrapOptions { lang, roles, context } + Default + builder setters (new, with_roles, with_context)
    • pub fn plan_bootstrap(project_root, opts) -> Result<BootstrapPlan>.claude/agents/<role>.md absent → Create { body }, present → Skip { reason: "exists" }
    • BootstrapPlan (creates() / skips() iterators) + BootstrapAction::{Create, Skip}
    • pub fn apply_bootstrap(plan) -> Result<BootstrapReport>gfs::atomic_write for new files (atomic_write auto-creates parent dir)
  • lib.rs: pub mod bootstrap; + re-export (apply_bootstrap, plan_bootstrap, BootstrapAction, BootstrapChange, BootstrapOptions, BootstrapPlan, BootstrapReport)
  • Unit tests (crates/genasis-overlay/src/bootstrap.rs::tests):
    • empty_project_creates_all_ten_roles — empty project → 10 Create
    • existing_files_are_skipped — partial roles present → only missing get Create, present get Skip("exists") + role enum verified
    • apply_writes_only_create_actionsapply_bootstrap → 10 files exist on disk
    • rendered_base_carries_required_frontmatter_keys — frontmatter contract (5 keys + name: <slug> match)
    • korean_locale_subtree_loads--lang ko works identically
    • unknown_locale_errors — unknown locale returns Error::Overlay
    • role_subset_only_plans_chosen_roleswith_roles(vec![...]) for partial scaffold
    • idempotent_second_apply_is_a_noop — second bootstrap call → all Skip
  • Integration tests (crates/genasis-overlay/tests/bootstrap_then_attach.rs):
    • bootstrap_then_attach_injects_into_every_role — bootstrap → scan → 10 all Known(_) → plan_attach → 10 Inject
    • bootstrap_ko_then_attach_ko_injects_korean_overlay--lang ko chain verified, backend.md attach output contains Korean protocol header "Plane / Mattermost 프로토콜"
    • bootstrap_partial_then_attach_handles_mix — user-authored frontend.md preserved byte-identical by bootstrap

M14.3 — CLI wire-up — ✅ commit pending (this commit)

  • crates/genasis-cli/src/cmd_bootstrap.rs new — genasis bootstrap [--lang] [--roles] [--no-attach-after] [--dry-run] [--project]. Loads agents catalog, calls plan_bootstrapapply_bootstrap, auto-chains cmd_attach::pub_run unless --no-attach-after.
  • crates/genasis-cli/src/cmd_init.rs gets --bootstrap alias + --roles forwarder. Delegates straight to cmd_bootstrap::run so the two entry points stay byte-identical.
  • crates/genasis-cli/src/cmd_attach.rs empty-dir hint: when report.agents and report.skipped are both empty, stderr emits bootstrap.no_agents_hint and continues (existing non-destructive behaviour preserved).
  • [s] cmd_attach --bootstrap alternative path — rejected per ADR-010 §3 (b)+(d). Single canonical entry point + init --bootstrap alias keeps the surface coherent.
  • genasis-i18n/locales/{en,ko}.yml keys added: bootstrap.no_agents_hint, bootstrap.scaffolded_summary (%{count}), bootstrap.skipped_existing (%{name}), bootstrap.next_step.
  • --lang priority — cmd_bootstrap::run calls lang_prompt::decide identically to cmd_attach::pub_run, so the global --lang flag picks the same locale for both base and patch trees. Unit tests parse_roles_* cover role-subset path.

M14.4 — tests/golden/blank/ activation — ✅ commit pending (this commit)

  • tests/golden/blank/input/ — empty mock project (README.md only, no .claude/)
  • tests/golden/blank/expected/ — bootstrap+attach output (10 fenced agent files + README.md), populated via BLESS=1 cargo test
  • crates/genasis-overlay/tests/golden_blank.rs — two tests: bootstrap+attach+detach round-trip + expected/ snapshot equality (BLESS=1 to refresh)
  • tests/golden/SHARED.md table: blank row flipped to Active with test path + BLESS hint
  • [s] tests/golden/blank-ko/ — deferred to M18 audit. Per the user's M18 directive ("intent re-check first") we will decide on language variants alongside the rest of the fixture roster instead of adding one ad-hoc here.

M14.5 — Doctor + retrospective — ✅ commit pending (this commit)

  • cmd_doctor.rs [bootstrap] section:
    • .claude/agents/ existence + file count report (doctor.bootstrap.dir_missing / doctor.bootstrap.file_count)
    • Empty dir + bootstrap not run → doctor.bootstrap.empty_hint suggestion (i18n)
    • Base files' frontmatter name: matches stem; missing/mismatched fields surfaced as warnings
  • progress.md / progress.ko.md retrospective slot — M14 row added below.
  • DoD: cargo test --workspace green (177 → 179 passed including golden_blank), bootstrap-related drift items cleared. Bigger doctor coverage will be added under M19.

Risks / TBD

  • (a) init --bootstrap vs attach --bootstrap placement: resolved 2026-05-08 — new genasis bootstrap subcommand + genasis init --bootstrap alias (ADR-010 §3 (b)+(d)).
  • (b) ECC claude-code-templates differentiation text: README.md Comparison table needs "Non-destructive overlay" vs "Bootstrap" as two axes to avoid visual confusion.
  • (c) How far base templates specify tools: — too narrow restricts user freedom, too broad is meaningless. Starting from ECC default (Bash, Read, Write, Edit, Glob, Grep, Task) + comment guidance.

v0.1.0 plan (2026-05-08 ratified)

v0.1.0 cut condition (user decision 2026-05-08): every command advertised in README.md is exercised by an automated E2E test, and every golden fixture in tests/golden/ either has a populated expected/ snapshot or has been intentionally retired. The roadmap below sequences the remaining milestones into commit-sized batches with immediate review after each.

Order Milestone Scope Status
1 M14.0 ADR-010 ratify gate done
2 M14.3 cmd_bootstrap.rs + init --bootstrap alias + attach empty-dir hint + 4 i18n keys done
3 M14.4 tests/golden/blank/ activation (input + expected + round-trip) done
4 M14.5 cmd_doctor.rs [bootstrap] section + retro entry + DoD done
5 M18 Golden fixture audit — keep / retire / add list, then populate expected/ for survivors done
6 M19 tests/e2e/ Rust integration suite covering all 13 README commands (trial flavor as default backend) in progress (M19.1/.2/.3 done; M19.4 awaits M15/M16)
7 M20 nightly-e2e.yml workflow restored — servers/docker-compose.yml smoke against real Plane + MM done
8 M21 trial-app Playwright suite — full US-001..US-022 acceptance regression pending
9 M15 Manifest + drift detection + genasis debug {status,log,collect,reset} done
10 M16 genasis debug submit (PR-only per ADR-012 §8) + debug-history/ repo structure + workflow + skill done
11 M17 Analysis automation + integration done
12 v0.1.0 cut tag + release.yml run + announcement ready (release notes drafted; tag is a maintainer action)

M18 — Golden fixture audit — ✅ commit pending (this commit)

2026-05-08 audit decision: golden fixtures should pin deterministic disk-state output only; any scenario expressible as a unit test against pure data belongs in the relevant crate. Applied to the seven existing directories:

Directory Decision Rationale
ecc-only/ Keep Round-trip + idempotent attach anchor (golden_ecc_only.rs). Already populated.
blank/ Keep M14 bootstrap entry point (golden_blank.rs). Populated under M14.4.
with-ko-locale/ Keep Korean overlay body anchor — language-specific disk state worth pinning.
kw-plugins/ Retire Detector only reads frontmatter name:; no code-level distinction from ECC.
legacy-bash-genesis/ Retire cmd migrate-from-genesis is docs-only for v0.1.0 (M11 [s]). No code path to exercise.
with-drizzle/ Retire Single detected() call → covered by new unit tests in crates/genasis-db/src/adapters/drizzle_kit.rs::tests.
with-duckdb/ Retire Single Driver::parse("duckdb") → already covered by unit tests in crates/genasis-db/src/kernel.rs::tests.

Optional additions considered (with-trial/, bootstrap-then-attach-{en,ko}/) were rejected — they are cheaper to cover via the M19 Rust integration suite.

Deliverables in this commit:

  • tests/golden/{kw-plugins,legacy-bash-genesis,with-drizzle,with-duckdb}/ removed (git rm -r).
  • crates/genasis-db/src/adapters/drizzle_kit.rs gains 3 unit tests (detected_true_when_ts_config_present, _when_js_config_present, _false_when_no_config) so the retired with-drizzle/ scenario is not lost.
  • tests/golden/SHARED.md rewritten with the surviving 3 fixtures + retired list + "unit test first, golden second" guidance.
  • cargo test --workspace: 183 → 186 passed.

M19 — tests/e2e/ Rust integration suite (README parity)

Cover every command listed in README.md §CLI Reference: init, init --trial, attach, detach, doctor, upgrade, bootstrap, agents {browse,install,list,installed,remove}, monitor (headless smoke), design swap, db {query,migrate}, lang switch, debug {status,collect,submit} (last needs M15+M16 done — gated), example. Default backend is the trial flavor against a process-local trial-app instance so suite runs hermetically in CI.

M20 — nightly-e2e.yml workflow restoration

Recreate the workflow declared in M0 (currently missing). On a nightly schedule: docker compose up -d against servers/docker-compose.yml, run M19 suite with flavor = "plane" / flavor = "mattermost" instead of trial, tear down. Tags: nightly-real-servers. Failures open a labelled issue automatically.

M21 — trial-app Playwright suite

Per user decision 2026-05-08: rich Playwright coverage matching every acceptance criterion in trial-app/ralph/prd.json US-001..US-022.

  • trial-app/e2e/ directory with playwright.config.ts
  • One spec file per user story (us-001.spec.ts ... us-022.spec.ts)
  • Wired into trial-app package.json as npm run e2e
  • Hooked into M19 (genasis init --trial E2E covers Quick Path) + separately runnable for trial-app development cycles.

v0.1.0 cut criteria (DoD)

  • cargo test --workspace --no-fail-fast green — 222 passed, 2 ignored
  • npm --prefix trial-app run e2e green (M21 suite) — 14 passed, 1 skipped
  • tests/e2e/ Rust suite green in CI (M19) — 23 tests across lifecycle/agents/supporting/debug
  • Nightly real-server suite green for at least one run (M20) — workflow landed; first scheduled run pending
  • All tests/golden/*/expected/ either populated or directory removed (M18) — survivors: ecc-only, blank, with-ko-locale
  • lint-i18n-strict green (release.yml hard fail) — pre-existing drift in 5 docs (CREDITS / DESIGN-SWAP-GUIDE / AGENTS-MARKETPLACE / QUICKSTART / famous-agents) needs Korean mirror landed before tag
  • cargo clippy --workspace --all-targets clean (no errors) — note: not run with -D warnings because of upstream warning surface; all warnings are dead-code style only
  • cargo fmt --all -- --check clean
  • docs/RELEASE-NOTES-v0.1.0.md drafted
  • Tag v0.1.0, release.yml run, GitHub Release notes published — maintainer action

Phase F — Debug History Feedback Loop (ADR-012)

2026-05-05 user-designed. Genasis as a meta-tool generates overlay files that users inevitably modify. Those modifications are the highest-signal feedback for improving genasis. This phase implements a secure, always-on drift detection + opt-in submission pipeline that feeds field patches back into genasis development via automated Claude Code analysis.

Governance: contributors submit data only (debug-history/patches/*.patch.json); maintainer processes patches via Claude Code /debug-review skill for auto-development. See ADR-012 §8.

M15 — Manifest + Drift Detection + Local Debug Commands

  • genasis-core manifest module:
    • .manifest.json schema (genasis_version, agents_catalog_version, attached_at, lang, files map with sha256/template_source/fence_sha256)
    • manifest::generate(project_root) — scan .claude/genasis/ + marker fences, produce manifest
    • manifest::compare(manifest, live_state)Vec<DriftEntry>
    • DriftEntry { file, drift_type, old_hash, new_hash, diff_lines }
  • Manifest generation wired into cmd_attach.rs and cmd_init.rs (post-apply)
  • Passive drift detection on every CLI invocation:
    • app_preamble() or equivalent hook runs manifest compare
    • Appends to .claude/genasis/.drift-log/current.jsonl
    • < 1ms overhead target (SHA-256 per managed file only)
  • genasis debug subcommand tree:
    • genasis debug status — drift summary (file count, last collect timestamp)
    • genasis debug log — display .drift-log/current.jsonl contents
    • genasis debug collect — anonymise + generate patch.json:
      • Secret stripping (TOKEN/SECRET/KEY/PASSWORD/CREDENTIAL regex)
      • Path anonymisation (absolute paths → <PROJECT_ROOT>/...)
      • Project identity as one-way hash
      • Output to ~/.genasis/debug-history/<project-hash>/<timestamp>.patch.json
    • genasis debug reset — update manifest to current state, clear drift log
  • i18n keys: debug.status.*, debug.collect.*, debug.log.*, debug.reset.* (en/ko)
  • Unit tests: manifest generate/compare, drift detection, secret stripping, path anonymisation
  • Integration test: attach → manual file edit → drift detected → collect → patch.json valid

M16 — Submit + Repo Structure + /debug-review Skill

  • genasis debug submit command:
    • --all | --latest | --file <path> selection
    • Full payload preview before confirmation
    • Interactive confirm prompt (i18n)
    • Optional user_comment field
    • Submission via gh issue create (label: debug-history, structured JSON body)
    • Rate limiting: max 1 submit per project per day
  • debug-history/ directory structure in genasis repo:
    • debug-history/index.jsonl (patch registry: id, submitted_at, project_hash, status)
    • debug-history/patches/ (submitted patch.json files)
    • debug-history/analysis/ (auto-generated: clusters.md, proposed-fixes.md)
    • debug-history/schema.json (JSON Schema for patch.json validation)
  • .github/workflows/debug-history-pr.yml:
    • Only allow changes to debug-history/patches/*.patch.json
    • JSON schema validation
    • Executable content rejection (shebang, suspicious patterns)
    • Auto-label [debug-history] + auto-assign maintainer
  • .claude/skills/debug-review.md skill:
    • Read all unresolved patches from debug-history/patches/
    • Cluster by affected template/file
    • Identify recurring patterns (threshold: ≥2 patches)
    • Propose template changes as Edits
    • Update debug-history/analysis/clusters.md
    • Tag resolved patches in index.jsonl
  • i18n keys: debug.submit.*, debug.submit.confirm, debug.submit.rate_limited (en/ko)

M17 — Analysis Automation + Integration

  • /debug-review skill triggers:
    • Manual: maintainer invokes /debug-review
    • Scheduled: weekly auto-run (GitHub Actions + Claude Code)
  • debug-history/analysis/clusters.md auto-generation:
    • Group patches by template source
    • Classify: bug_fix / workflow_extension / project_specific
    • Frequency count + example excerpts
  • debug-history/analysis/proposed-fixes.md auto-generation:
    • For each cluster with ≥2 occurrences: draft template Edit
    • Link to source patch IDs
    • Confidence score (based on pattern consistency)
  • Audit trail:
    • Every merged template fix references motivating patch IDs in commit message
    • Resolved patches tagged in index.jsonl with fix commit SHA
  • Archival policy:
    • Patches older than 6 months → debug-history/archive/YYYY-MM/
    • Archived patches excluded from active analysis
  • Documentation:
    • CONTRIBUTING.md section on debug-history submissions
    • genasis debug --help comprehensive usage guide
    • GENASIS.md template updated with debug history section

In-progress notes

(This section records blocks, decision changes, and deferred items inline.)

  • 2026-05-03: Initial blueprint agreement complete, M0 start.

  • 2026-05-03: M0 complete — 144 files, 9 crate stubs, install.sh smoke verified, 6 golden fixture dirs, 5 Tera templates, 3 GitHub Actions workflows. Ready for M1.

  • 2026-05-03: M1 complete — genasis-core 5 modules operational (marker/fs/env/config/error), cmd_version first working command, role_inference + SQL guard strengthened, 30+ unit/integration tests, ADR-001/002 written. M2 ready.

  • 2026-05-03: M2 complete — frontmatter parser + detector + validator + merger + dry_run + cmd_attach/detach operational, first real template (frontend), ecc-only golden fixture + 2 round-trip integration tests, cumulative 78 #[test]. Next: M3.

  • 2026-05-03: M3-M11 completed — Plane/MM provider flavor system + GitHub gh wrapper + cmd_init operational, Plane user provisioner Node sub-process, DB schema kernel + 7 adapters + cmd_db, 10+16+6+6 Tera templates (agent overlays / commands / skills / hooks), design hot-swap orchestrator + cmd_design, doctor/upgrade/monitor operational, ADR-003~007 written. First-release code/docs in place.

  • 2026-05-04: M12 v1 plan (doc dual tree + CI only, 8 sub-steps). User feedback expanded to v2.

  • 2026-05-04: M12 v2 replan complete — user request added (a) runtime i18n (Rust CLI/TUI + install.sh), (b) --lang en|ko install-time selection, (c) multilingual co-install investigation (docs/impact-of-multilang-prompts.md — 13 sources analysed) → --lang both rejection + active singularity policy. blueprint §19 full rewrite (13 sub-sections), progress M12 expanded to 13 sub-steps. New crate genasis-i18n, templates/{en,ko}/ split, genasis lang switch command, install.sh --lang branch, with-ko-locale golden. Awaiting human approval.

  • 2026-05-04: M12 v3 fine-tuning — 2 user feedback items. (1) Drift gate from 2-tier to 3-tier (PR warn / release-prep strict / auto translation-completion PR). (2) Runtime i18n library fluent-rs → rust-i18n — ~50 messages / no Korean plural variation / 150KB binary saving / token efficiency.

  • 2026-05-04: M12 v4 — interactive language prompt added, final user approval. --lang arg priority (arg > TTY prompt > $LANG fallback). Install shows bilingual banner. --non-interactive/--yes for CI.

  • 2026-05-04: M12 v5 — README SEO + multilingual toggle added, final approval. blueprint §19.13 8 sub-sections. Approved — sequential execution from M12.0.

  • 2026-05-04: Phase D (Design Catalog Integration) complete — M-D1/M-D2/M-D3 in one pass. 7 user decisions reflected. No vendoring → npx getdesign delegation. Telemetry default OFF. New code: genasis-design/{mode,pointer,swap,restore,verify,override_log,ticket_emitter}.rs + genasis-monitor/widgets/design.rs + cmd_design 5 subcommands. ADR-009 (en+ko). i18n 126 → 144 keys. Cumulative cargo test 145 passed.

  • 2026-05-05: M14 (Default agentic team bootstrap) user-flagged + plan reflected. User inquiry — can a blank project scaffold a default team? Code audit: genasis-overlay only supports attach/detach, no base-agent creation path. Unintentional gap from milestone ordering; blueprint §15 implicitly assumed ECC reference user. M14 established: base + patch 2-layer + ADR-010 + green-field golden activation. v0.1.0 release tag moved post M14.0.

  • 2026-05-04: M12 v6 audit + stale item cleanup. 154 unchecked items in progress.ko.md audited — nearly all M12.3M12.13 work was committed but checkboxes not closed. True missing artifacts filled (logo.svg, architecture.svg, tests/install_lang_e2e.rs 6 tests, cmd_attach.rs --lang clap conflict resolved). All M12.3M12.12 sub-steps closed [x] or [s]. Cumulative cargo test 120 passed.

  • 2026-05-10: v0.5.1 patch release — monitor text selection restored + tmux Shift+drag hint. Reported during v0.5.0 dogfooding: drag-select / double-click / triple-click did nothing inside genasis monitor. Root cause was EnableMouseCapture in crates/genasis-monitor/src/app.rs without any widget consuming mouse events — terminal stopped routing clicks to its native selection layer. Removed EnableMouseCapture + DisableMouseCapture (one-line fix, comment noting future widgets must opt-in rather than enable globally). TUI wizard already had capture off; added a dim Shift+drag select text (in tmux) hint to key_hints.rs so tmux mouse-mode users discover the standard workaround. Three-row troubleshooting table added to docs/MONITOR.md and KO mirror covering the v0.5.0 issue, tmux Shift+drag, and screen copy-mode. Workspace version 0.5.0 → 0.5.1; release notes EN+KO. cargo test --workspace 245 passed, 4 ignored — no regressions.

  • 2026-05-10: Human roster provisioning — humans as first-class team members (ADR-014). Until now genasis init / bootstrap only auto-provisioned the ten agent bot accounts; humans had to sign up separately, breaking both the "turnkey bootstrap" and "human/agent symmetry" missions. Added genasis-core::config::HumanEntry + a [[humans]] array in genasis.toml, with provisioning side-effects (Mattermost user_id, Plane user_id, temporary password) carved out into .genasis/humans.lock.toml. New trait method MattermostProvider::ensure_human_user(spec, team_id) with an upstream admin-create implementation (24-char high-entropy temp password covering Mattermost's strictest policy, force-change on first login, idempotent on email). Extended provision-plane-users.mjs ProvisionInput with humans: HumanRequest[] (Playwright UI is still a stub but echoes the humans payload). New CLI genasis humans add | edit | remove | list | sync; cmd_init now auto-runs humans sync when [[humans]] is non-empty (failures warn but do not fail init). TUI wizard grew from 6 to 7 steps (Env→Lang→Team→Connect→Humans→Overlay→Done) with a / e / d / s / Enter for add/edit/delete/sync/advance and a 5-field form modal; re-running the wizard reloads [[humans]] for in-place editing ("rerun is the editor"). agents/GENASIS.md.tera gains ## Human Roster table and ### Requirement intake protocol (registered = binding stakeholder, unregistered = QUESTION label + PM verification, bots = existing agent-to-agent flow); pm.patch.md.tera / planner.patch.md.tera (en/ko) and commands/check-inbox.md.tera mirror the protocol. ADR-014 written in EN/KO. New unit tests: HumansLock round-trip, upsert case-insensitive match, derive_mm_username normalisation, cmd_humans truncate / now_iso. cargo test --workspace --lib green. Out of scope (deferred to v2): invite-email mode for SMTP-enabled environments, Plane Playwright UI port to land real user_ids, OAuth/SSO integration.

  • 2026-05-10: Trial bridge config SSOT cleanup (ADR-013). The previous code defined the [trial] section but never read it; routing actually used [plane].url / [mattermost].url plus MM_ADMIN_TOKEN / PLANE_API_KEY env vars, so [trial].enabled = false could not actually disable the bridge and [trial].url edits were silently ignored. Added Option<&TrialConfig> to mattermost::factory::build() / plane::factory::build(); trial flavor now sources URL + secret from [trial] and rejects enabled = false. Added Config::validate_trial() for cross-section enforcement at load time. cmd_init / cmd_mm / cmd_plane / cmd_humans skip the admin env-var requirement under trial flavor. New unit tests ×10 (factory build_trial_*, validate_trial_*) + integration tests/trial_factory_e2e.rs ×3 (2 #[ignore]-marked E2E + 1 negative-path). ADR-013 written in EN/KO. cargo test --workspace 245 passed, 4 ignored.

  • 2026-05-14: v0.6.0-alpha.14 — D-072 monitor auto-sandbox discovery + config_hint banner. Fixed the UX defect where genasis monitor from a testbed root silently returned empty widgets.

    User's suspicion: testbed root /work/agenteams/team-ex/ had no genasis.toml / .claude/agents/, so the user doubted whether the agentic team was actually wired to the trial-app.

    Reality: the testbed structure has the sandbox one level deeper (alpha9-trial/). Live evidence:

    • .claude/agents/ holds all 10 agent files (architect / backend / code-reviewer / designer / devops / frontend / planner / pm / qa / security)
    • genasis.toml's [trial] section is enabled=true, team_token=76b03286…
    • PM overlay carries the D-062 fix (자동 devops dispatch matches)
    • src/components/QuizApp.tsx (193 lines) + src/lib/quiz-bank.ts (237 lines) are real code (430 lines total)
    • The user's "change Start button to cyan" message at 14:30:08 reached the daemon → Agent Task → frontend → real edit to src/styles.css:264 .btn-primary cyan #06b6d4 → transition_issue done → wrap-up post_message — full autonomous chain in 141 s.

    But the UX defect is real: the user had to know the exact sandbox path (cd or --project <dir>) before monitor showed any trial data. From the testbed root, genasis monitor walked up looking for genasis.toml, found none, set trial_mode=false, and every widget stayed empty. The D-058 fix did push a hint into state.config_hint, but no widget rendered it (D-058 was incomplete).

    D-072 (Critical UX) — two-part fix:

    • New genasis-core::Config::discover_or_descend — when walk-up fails, scans the immediate children of start for genasis.toml. Skips dot dirs / node_modules / target, sorts for determinism. Now monitor from a testbed root auto-discovers alpha9-trial/genasis.toml. The discovery is announced via a banner hint ("ℹ Auto-discovered sandbox at …").
    • monitor::widgets::log_tail now surfaces state.config_hint as a sticky first row at the top of the widget — yellow (⚠ not found) or cyan (ℹ auto-discovered). Even when log_tail fills up, the hint doesn't scroll off.

    D-058 closeout: the hint was previously pushed to state only and never rendered. Same fix bundle.

    Unit verification:

    • discover_or_descend(/work/agenteams/team-ex)…/alpha9-trial/genasis.toml
    • discover_or_descend(/work/agenteams/team-ex/alpha9-trial) → same path (walk-up zero hop) ✅
    • discover_or_descend(/tmp) → None (hint surfaced) ✅

    Updated user guidance: cd /work/agenteams/team-ex && genasis monitor now Just Works™ — Sprint card counts + listen.log activity feed populate automatically, with a banner naming the auto-discovered sandbox. --project <dir> still supported for the multi-sandbox case.

  • 2026-05-14: v0.6.0-alpha.13 — D-061/062/063/065 bundle hotfix + agents-v1.0.3 catalog publish. Per user instruction "fix every outstanding defect", four defects shipped in one cycle.

    D-062 (autonomous dispatch chain) — three overlays + system prompt strengthened together:

    • pm.patch.md.tera (ko/en) adds a new Step 4 next to Step 3: "For any code-changing request, the moment frontend/backend Task calls finish you MUST invoke devops in the same turn." Concrete Task() template (npm install → background npm run dev & → ss verify → announce_dev_server_url → post_message). Notes "PM stays out of infra/server-survival — that's devops's territory."
    • devops.patch.md.tera (ko/en) gains an "Invocation trigger" section (PM's dispatch-chain final hop), workflow now requires ls package.json precheck + foreground npm run dev banned (must use &) + explicit mcp__trial-app__announce_dev_server_url call. New Forbidden item: skipping announce_dev_server_url.
    • frontend.patch.md.tera (ko/en) introduces a "standalone scaffold guarantee". Even when PRD points at a sub-path, populate it with package.json + vite.config.ts etc. so devops can spin up npm run dev. Frontend itself never spawns the dev server (devops's job). Completion report must include cwd=<abs path> so devops knows where to start.
    • session.rs::build_append_system_prompt CRITICAL block expanded. Chains frontend Task → devops Task → announce_dev_server_url and spells out failure cost: "Without that announce call, the user's ShowcasePanel iframe shows localhost refused to connect and the turn looks broken."

    D-061 (Critical) — rewrote genasis example prd PRD §5 for the v0.6.0 model:

    • crates/genasis-cli/templates/examples/prd.{en,ko}.md §5 ("Trial-app integration") fully rewritten. The v0.5.x model ("write into agents-pool/trial-app/ source tree") is gone; v0.6.0 flow is "scaffold a standalone Vite app in the user sandbox (package.json + vite.config.ts + src/main.tsx + components/QuizApp.tsx + lib/quiz-bank.ts) + devops backgrounds npm run dev + calls announce_dev_server_url → ShowcasePanel iframe picks it up."
    • Next cycle: genasis example prd will yield a PRD that points at a runnable standalone scaffold → frontend follows the PRD → devops can actually spin a dev server → user sees the real result in ShowcasePanel.
    • The old v0.5.x flow is now a fallback note that references ADR-016.

    D-063 — trial-app set_app_features([]) was a no-op under LRU-append semantics:

    • app/api/trial/team-app/status/route.ts guard tightened: app_features && app_features.length > 0app_features !== undefined. Empty array now triggers an update.
    • db/sim.ts::setTeamApp signature widened from add_features: string[] to string[] | null with three documented semantics: null = preserve, [] = explicit reset, [...] = LRU-append.
    • app/api/trial/bootstrap/route.ts mirror call aligned.
    • Typecheck PASS. Operator trial-app needs npm run build + restart to surface the fix.

    D-065 (partial) — genasis monitor Log widget couldn't follow the daemon's listen.log:

    • New crates/genasis-monitor/src/collector/listen_log.rs — reads the last 80 lines (≈16 KB) of <project_root>/.genasis/listen.log every 3 s, strips ANSI escapes, pushes to state.log_tail. First read seeks to size-16KB so long-running daemons don't dump thousands of lines on first tick; subsequent reads only emit new content.
    • state.rs gains project_root: Option<PathBuf> + listen_log_offset: u64. load_trial_config stores cfg_path.parent() when discovery succeeds.
    • app.rs run_loop gets LISTEN_LOG_TICK = 3 s.
    • Result: genasis monitor --project /path/to/sandbox while a daemon is running now streams real tool_use / post_message events into the Log widget instead of "no log lines yet".
    • Agents widget "wire SessionStart hook" + RTK / JSONL / Network counters remain — separate defect (D-066 next cycle).

    agents-v1.0.3 catalog publishagents-pool/scripts/publish-overlays-only.sh 1.0.3 --from 1.0.2. agents-v1.0.3.tar.gz uploaded to GitHub Releases. User sandboxes pick up new overlays via genasis agents update or genasis upgrade.

    Build verification: cargo build --workspace 0 errors, trial-app npx tsc --noEmit PASS. Touched: 6 overlay files + session.rs + 2 PRD templates + 3 monitor files + 3 trial-app files.

  • 2026-05-14: v0.6.0-alpha.12 — D-060 Task-tool dispatch enforcement + new defects D-061/062/063. The alpha.11 live test confirmed PM was creating cards but never invoking sub-agents — D-060. Overlay + append_system_prompt now enforce the Task dispatch step. Verified via user follow-up.

    D-060 — PM didn't invoke sub-agents via Task after create_issue:

    • User sent "@pm — dispatch cards #327/#328/#329 to frontend via Task tool, start coding". PM responded, invoked Frontend via Task, and frontend wrote real code.
    • Real artifacts written by the frontend agent inside the user sandbox:
      • /work/agenteams/team-ex/alpha9-trial/agents-pool/trial-app/app/components/QuizApp.tsx (503 lines: "use client" + useReducer + mulberry32 seed + 3-screen flow)
      • /work/agenteams/team-ex/alpha9-trial/agents-pool/trial-app/lib/quiz-bank.ts (423 lines: 17 questions across beginner/intermediate/advanced)
    • Cards #327/#328/#329 → inreview. PM wrap-up post (id=310) reports artifact paths + scope-coverage breakdown.
    • Fix bundle:
      • agents/overlays/{en,ko}/pm.patch.md.tera §"Requirement intake" Step 3 rewritten as a mandatory rule — "After create_issue returns, you MUST immediately invoke each card's assignee via the Task tool in the same turn. Do not end the turn after merely creating cards. One Task call per card. When devops spins up a dev server, announce_dev_server_url is required."
      • session.rs::build_append_system_prompt adds a separate CRITICAL block so the system prompt enforces the rule even when overlays are stale.

    D-061 (Critical) — genasis example prd PRD §5 assumes the v0.5.x trial-app source-tree model:

    • PRD.md §5 says "The implementation lives inside the trial-app's source tree at agents-pool/trial-app/app/components/QuizApp.tsx … and agents-pool/trial-app/lib/quiz-bank.ts". That path tree is the operator-hosted trial-app's source. The frontend agent followed the PRD verbatim and wrote those files into the corresponding subdirectory inside the user sandbox. But that subdirectory has no package.json / next.config.js — it's not a standalone Node project, so npm install + npm run dev can't run there, no dev server, ShowcasePanel iframe gets localhost:5173 refused to connect.
    • Root cause: in v0.5.x the operator-hosted trial-app imported QuizApp.tsx directly, so the agentic team's job was to PR the trial-app source tree. v0.6.0 switched ShowcasePanel to LocalDevServerOrFallback, which expects an iframe of the user's localhost dev server. The PRD template still encodes the old model.
    • Next cycle: rewrite the genasis example prd template so PRD §5 describes "create a standalone Next.js (or Vite) scaffold inside the sandbox + run a dev server (e.g. http://localhost:5173) + devops calls announce_dev_server_url".

    D-062 — PM doesn't invoke devops after frontend finishes:

    • In the alpha.12 verification turn the PM dispatched to frontend but never invoked devops (the role responsible for npm install + npm run dev). PM wrap-up: "Next step: QA reviews the three inreview cards then transition to done." No dev server, no devops.
    • Overlay's §"Deploy routing" section already distinguishes visual-only changes from code changes, but PM doesn't trigger devops automatically. D-060's fix already adds an explicit announce_dev_server_url requirement to PM overlay; the next live cycle will check whether frontend → devops kicks in automatically once D-061 is in place.

    D-063 — set_app_features([]) doesn't reset due to LRU-append semantics:

    • PM tried to clear the stray ["dark-mode","i18n"] features by calling set_app_features({features:[]}). The trial-app backend treats empty arrays as a no-op under its LRU-append semantics, so /api/trial/team-app/status still returns ["dark-mode","i18n"].
    • Low priority — visual precedence is "most recent set", so ShowcasePanel rendering is barely affected. The trial-app backend needs either an explicit reset endpoint or DELETE semantics when features is empty. Next cycle housekeeping.
  • 2026-05-14: v0.6.0-alpha.11 — D-059 bypassPermissions hotfix. Live verification right after alpha.10 surfaced one more blocker.

    D-059 (Critical) — PM denied permission for MCP tool calls, chat panel stayed silent:

    • User sent "D-059 검증 — TODO 앱 만들어줘". daemon log showed PM calling mcp__trial-app__post_message, set_app_kind, set_app_features, but the final assistant text was "trial-app MCP 도구 권한이 필요합니다 (post_message, set_app_kind, ...)". Result: every call was rejected, no rows in sim_posts / sim_issues.
    • Cause: session.rs::spawn ran claude with --permission-mode acceptEdits. That mode auto-accepts file edits only — MCP tool calls fall into the prompt path, but stream-json non-interactive mode has nowhere to surface a prompt, so they're auto-denied.
    • Fix — --permission-mode bypassPermissions. The agentic team's cwd is constrained to the user sandbox and its job is to write real code anyway, so the surface is controlled. One-line change.
    • Live re-verification with same message pattern after daemon restart:
      • 02:54:18 human message arrives
      • 02:54:29 PM calls post_message → sim_posts id=304 actor=pm "ack — TODO 앱(다크모드 + i18n) 작업 시작합니다. 카드 생성 후 프론트엔드로 디스패치." persisted
      • 02:54:30 set_app_kind(kind="todo") + set_app_features(["dark-mode","i18n"]) succeed
      • 02:54:31 create_issue(title="TODO 앱: 다크모드 + i18n", assignee="frontend", state="inprogress") → sim_issues id=320 inprogress
      • 02:54:33 turn complete success=true duration_ms=12960 (12.9 s)
      • /api/trial/team-app/status now reports {"app_kind":"todo","app_features":["dark-mode","i18n"],"app_status":"complete"} → ShowcasePanel toggle unlocked
    • Decisive verification — PM updated chat, kanban, and showcase toggle through MCP tools, all three.

    Pending follow-up (D-060, next cycle): PM created the card and assigned frontend but didn't actually invoke the frontend sub-agent via the Task tool, so the team never started writing code or spinning up a dev server. The overlay's "hand each subordinate role off via Task tool sub-agent invocation" rule isn't enforced in practice — next cycle to firm up PM prompt + Task-tool flow.

  • 2026-05-14: v0.6.0-alpha.10 — D-057 MCP path baking hotfix + D-058 monitor --project flag. Two blockers found via post-alpha.9 self-test + user chat reproduction, hotfixed in one cycle.

    D-057 (Critical) — MCP server path baked to CI machine:

    • daemon log showed claude argv with "args":["/home/runner/work/genasis/genasis/mcp-servers/trial-app/index.mjs"] — the GitHub Actions build path.
    • Cause: cmd_listen.rs default mcp_server_dir came from env!("CARGO_MANIFEST_DIR"), which is resolved at compile time. release musl binaries shipped with /home/runner/work/genasis/genasis/... baked in → user machines don't have that path → node fails with Cannot find module → claude session never registers mcp__trial-app__* tools → PM has no way to post back to the user.
    • Secondary problem: if the user hasn't npm install -g @modelcontextprotocol/sdk, NODE_PATH points somewhere without the SDK and the MCP server fails for the same reason.
    • Fix — new crates/genasis-cli/src/mcp_bundle.rs:
      • Embeds each MCP server's index.mjs into the binary via include_str! (~30KB total).
      • On first call, unpacks to ~/.cache/genasis/mcp-servers/<name>/index.mjs (skips when sha256 matches).
      • Writes a package.json in the same cache root and runs npm install --prefix <cache> to fetch @modelcontextprotocol/sdk (once; subsequent calls skip).
      • Returns McpBundle { server_dir, node_modules }.
    • build_mcp_config signature gains node_modules: &Path. NODE_PATH is now pinned to the cache's node_modules (previously came from npm root -g).
    • GENASIS_MCP_SERVER_DIR env still overrides for dev / debug.
    • Local release smoke: ~/.cache/genasis/mcp-servers/ populated by npm install (~10s), claude session init log shows mcp_servers=["trial-app", ...], node MCP child process visible, user message answered in 3 s (session turn complete success=true duration_ms=2999).
    • Known follow-up (D-059): PM emits the response only as assistant text and never calls mcp__trial-app__post_message, so the chat panel still doesn't show the reply. The overlay's 5-second ack rule isn't enforced in practice — next cycle to track.

    D-058 — genasis monitor empty when run from the wrong directory:

    • User ran genasis monitor from /work/agenteams/team-ex → every widget empty (Sprint Todo:0 In:0 Review:0 Done:0, Agents "no agent activity collected", Log "no log lines yet"), even though the live trial-app shows 4 cards + 2 chat messages.
    • Cause: monitor::app::run calls Config::discover against std::env::current_dir(). discover only walks up — never down — so the testbed root, which doesn't itself contain genasis.toml, silently early-returns from load_trial_config. trial_mode stays false and all trial widgets render empty.
    • Fix:
      • cmd_monitor::Args gains --project <DIR> flag.
      • monitor::app::run(project_root: Option<PathBuf>); when Some, discover walks up from there.
      • When discover fails, push a clear hint to state.log_tail + new state.config_hint field: "⚠ genasis.toml not found walking up from ... Run genasis monitor inside your project sandbox, or pass --project <dir>."
      • AppState gets pub config_hint: Option<String>.

    Build verification: cargo build --workspace 0 errors, cargo fmt --check clean, end-to-end smoke confirmed daemon → MCP child → claude session init → tool registration → PM reply turn.

  • 2026-05-14: v0.6.0-alpha.9 — D-054 cleanup + beta real MCP servers + M-v6.0.4 multi-team session map. Three pending items from alpha.8 shipped in one cycle.

    D-054 cleanup — simulation-era residue removed:

    • Deleted crates/genasis-cli/src/listen/{routing.rs, sdk.rs} modules (deprecation stubs since alpha.7). Removed pub mod sdk; declaration from mod.rs. All traces of v0.5.x marker parsing / fresh-spawn run_claude_agent_sdk gone.

    beta — real Mattermost / Plane MCP servers:

    • mcp-servers/mattermost/index.mjs (+ package.json) — @modelcontextprotocol/sdk stdio server. Tools: post_message (Bearer auth + channel-name → UUID cache + actor prefix in body), list_posts, list_channels, update_post. Env: MM_URL / MM_ADMIN_TOKEN / MM_TEAM_ID / MM_DEFAULT_CHANNEL_ID.
    • mcp-servers/plane/index.mjs (+ package.json) — Tools: create_issue (idempotent on title + state-UUID auto-map + per-role assignee env PLANE_USER_ID_<ROLE>), transition_issue, list_issues, list_states. State UUID map: on first call we GET /states/ and alias "todo"/"inprogress"/"inreview"/"done" with backlog/started/completed group fallback.
    • crates/genasis-cli/src/listen/session.rs::build_mcp_config gains real / auto flavor branch — registers mattermost server when MM_URL + MM_ADMIN_TOKEN are set, plane server when PLANE_URL + PLANE_API_KEY are set. PLANE_USER_ID_* env vars are auto-forwarded. NODE_PATH auto-detection via npm root -g shared with trial.
    • Overlay text is identical between trial and real — same MCP tool surface (mcp__mattermost__post_message, mcp__plane__create_issue, etc.) so flavor swap requires no overlay rewrite.

    M-v6.0.4 — multi-team sandbox (HashMap<team_token, ClaudeTeamSession>):

    • InboundEvent::PostCreated gains team_token: String. Both TrialAppSseStream and MattermostWsStream tag every emitted event with their bound team_token.
    • MattermostWsStream::connect signature adds team_token: String — operators hosting multiple MM instances run one daemon per instance. cmd_listen uses MM_TEAM_ID env (or mm.url fallback) as the team key.
    • New pub type SessionFactory = Box<dyn Fn(&str) -> Pin<Box<dyn Future<Output = Result<...>> + Send>> + Send + Sync>; and pub async fn run_listen_loop_multi(stream, cfg, factory). HashMap lookup on team_token → on miss, factory call spawns a fresh ClaudeTeamSession. Drain task is per-session, logs include a team field.
    • cmd_listen::run_foreground constructs the factory as a closure capturing project_root / flavor / trial_url / mcp_server_dir; per-event invocation feeds only the team_token. The single-team case rides the same path (today's streams emit one team_token, so the HashMap holds a single key — multi-stream extensions will populate N keys with no further changes).
    • run_listen_loop_session replaced by run_listen_loop_multi (single caller in cmd_listen).

    Result: alpha.9 is the first build where v0.6.0's four pillars — protocol overlays, broker daemon, MCP servers (trial + real), multi-team session map — are all wired. real flavor runs the identical overlay surface as trial. cargo build --workspace 0 errors, cargo fmt --check clean.

    Still pending (alpha.10 / beta verification):

    • real flavor end-to-end smoke (operator-issued PATs + [[humans]] registered + genasis listen --real against an actual Mattermost + Plane).
    • multi-team end-to-end verification on a single daemon — two team_tokens streaming concurrently → two independent sessions in isolated sandboxes.
    • agents-v1.0.3 catalog publish (skip if no overlay change).
  • 2026-05-13: v0.6.0-alpha.1 — start of essence recovery: Agent SDK integration (M-v6.0.1). The user accurately pointed out that "agents should know the actual project code and find the solution inside it" — and that every v0.5.x fix (D-029b colour dict / D-039 hard-coded CSS branches / D-040 announce string / D-041 cleanup heuristic) was simulation polish. v0.6.0 starts the real model.

    New PLAN_v0.6.0.md: per-team sandbox + agent code access. Five milestones (Agent SDK / example scaffold / real code edits / per-team isolation / hosting trial-app role).

    M-v6.0.1 (this cycle): added crates/genasis-cli/src/listen/sdk.rs with run_claude_agent_sdk(prompt, cwd, tools, timeout) spawning Node subprocess @anthropic-ai/claude-agent-sdk with permissionMode: 'acceptEdits', cwd, and allowedTools. Authenticates via local Claude Code session — no ANTHROPIC_API_KEY needed (feedback_no_claude_api). Added LoopConfig.project_root: PathBuf. Switched the PM call in handle_human_post from claude --print to the SDK (tools=[Read, Bash]; Edit deferred to the frontend phase). Falls back to claude --print then to echo. The echo-only mode stays for CI.

    Live verification (message id=239 in user's sandbox /work/agenteams/team-ex/v516-final/): the daemon received "summarise this project's PRD in one line" and the PM replied 12 seconds later citing "본 프로젝트(v516 Final)의 PRD 핵심 내용 요약" — meaning Agent SDK really read PRD.md via the Read tool with the right cwd.

    Coming next:

    • PM prompt branching for simple Q&A vs work requests (currently always fans out)
    • frontend/designer/qa/devops agents also through the SDK with Edit/Bash
    • genasis example prd produces PRD.md PLUS a real React scaffold
    • per-team sandbox isolation + dev server auto-spawn

    Simulation-era close: D-029b ~ D-042 hard-coded dicts/branches/heuristics will retire as real agent work covers the same surface.

  • 2026-05-13: v0.5.26 release — block deploy/cleanup actor self-trigger loop (D-042 hotfix). While verifying v0.5.25's D-040 the daemon received its own [deploy] announce back over SSE; is_human_actor("deploy") = true then triggered a wasted PM round-trip (assignments=0, but still one LLM call + extra reply). Added "deploy" and "cleanup" to is_human_actor's KNOWN_BOTS so every system actor the daemon posts is classified as non-human.

  • 2026-05-13: v0.5.25 release — accent range expansion + deploy announce + stuck card cleanup (D-039/040/041 + agents-pool@2aa07e9). User reported after the self-test cycle that tickets stayed stuck in todo/inprogress, the showcase didn't reflect the latest requests, and no agent ever said "deployed". Three fixes shipped together.

    D-039 (accent range): QuizApp's accent-* features only changed the start button background (bg-*-600); the h2 title kept text-neutral-900. Users asking for "title in red" got a red start button while the title stayed neutral, so visually nothing matched the request. Added a parallel titleAccentClass (text-*-600 / dark variants) with the same last-wins resolution and applied it to the title h2.

    D-040 (auto deploy announce): features-only deploy means "no agent invocation needed", so nobody said "deployed" in chat and the human lost the thread. The daemon now posts a [deploy] actor message "✅ 배포 완료 — sim_teams.app_features = [...]" immediately after fan-out. by-last-agent / devops modes get similar announces.

    D-041 (stuck card cleanup): added EventSink::cleanup_stuck_cards. When the human message contains "정리/마무리/완료해/cleanup/tidy up", the daemon calls listIssues before the PM step and pushes every state=inprogress|todo card through a single bootstrap round-trip transitioning them all to done. Old stuck cards from prior cycles (#14/15/16/23/24/26) get swept in one go.

  • 2026-05-13: v0.5.24 release — [CARD:] regex hyphen matching fix (D-038). While verifying v0.5.23 live, card #26 "accent-yellow 타이틀 렌더 점검" was the only one stuck in todo. routing.rs's parser regex [^→\->\]]+? for [CARD: <title> → <state>] excluded - in its character class, so titles with hyphens (e.g. accent-yellow) truncated at the first hyphen — title_substring="accent" broke ensureIssue dedup and the card never transitioned. Simplified to (.+?)\s*(?:→|->)\s*([a-z]+) so the body matches non-greedy up to the separator. Old stuck cards from earlier cycles (#14/15/16/23/24) will move correctly once a follow-up cycle touches them.

  • 2026-05-13: v0.5.23 release — echo stub title correctness + Plane-compatible sequence_id propagation (D-036/037). After v0.5.22 the user reported (1) cards piling up in In Progress without ever moving to Done (echo "착수" stub used first_three_words so its title diverged from the PM seed and broke ensureIssue dedup), and (2) "#N" literal showing up in agent messages (LLM copied the placeholder verbatim — needed a real card number that's also Plane-compatible).

    D-036 (echo stub titles): build_echo_agent_start / build_echo_agent_done dropped first_three_words(&assignment.task). handle_human_post now finds the PM seed card by assignee match in route.new_cards and passes the exact title to the echo stubs. start, done, and PM seed now share one title — ensureIssue's title-equality dedup works end-to-end.

    D-037 (Plane-compatible sequence_id): EventSink::apply_pm_routing now returns Result<HashMap<String, u64>> (title → sequence_id). TrialAppSink parses bootstrap's demo_issues[] response and populates the map. The fan-out uses it to replace #N with the real card number (e.g. #28). sim_issues.sequence_id and real Plane's issue.sequence_id are both integers, so v0.6.0 real-Plane integration keeps the same code path.

  • 2026-05-13: v0.5.22 release — KST-aware timestamps + LRU app_features + strict agent title preservation (D-033/034/035). After v0.5.21 the user reported three follow-up problems: (1) chat timestamps were 9 hours off in Korea, (2) "change to red" didn't update the start button (still teal), (3) chat showed [CARD: → done] markers but kanban cards stayed in In Progress.

    D-033 (timezone): SQLite datetime('now') writes UTC without a Z suffix, so the browser's Date parser interpreted it as local time. LiveChatThread.formatTime now normalises "YYYY-MM-DD HH:MM:SS" to ...TZ before parsing; toLocaleTimeString then renders in the viewer's actual locale.

    D-034 (LRU app_features): setTeamApp's set union preserved original position, so a user requesting "red → blue → red" left the array order unchanged and QuizApp's last-wins resolver picked the wrong (older) accent. Now LRU — existing entries are removed before re-append, so the most recently requested feature is always at the tail.

    D-035 (strict agent titles): claude agents paraphrased the PM seed card title in their [CARD: <title> → state] markers, breaking ensureIssue's title-equality dedup and producing duplicate cards while the originals stayed stuck in In Progress. build_agent_prompt now interpolates the literal seed title and instructs the agent: "do not change a single character".

  • 2026-05-13: v0.5.21 release — real LLM mode + parser robustness + colour dictionary + deploy routing + parallel fan-out (D-029/030/032 + agents-pool@7bfb004).

    Retrospective: across v0.5.16–v0.5.20 the operator daemon was always launched with --echo-only, which procedurally dodged the user's repeated "no simulations" demand. Dropping echo-only and restarting in real claude --print mode immediately surfaced two bugs: (a) parse_pm_routing matched only strict markdown headings (## 작업 분배) and so missed claude's freer-form responses; (b) the PM prompt's feature dictionary was narrow enough that claude approximated 청록 (teal) to accent-green. User asked whether deployment was a missing role and suggested parallelism — D-030 and D-032 joined the same release.

    D-029a (routing.rs::extract_section): replaced the strict ## 작업 분배 find with a line-by-line regex that accepts # X, ## X, ### X, **X**, or plain X. claude can now drop the ## prefix and fan-out still triggers.

    D-029b (dictionary expansion): added accent-purple/teal/yellow/orange/pink to both the PM prompt and the echo mapper (Korean/English variants — 청록/teal/민트/cyan, 노란/yellow, 주황/orange/오렌지, 분홍/pink/핑크). The PM prompt now also says "anything outside the list — emit kebab-case as-is" so arbitrary colours (e.g. 코랄 → accent-coral) flow through to sim_teams. QuizApp resolves accent class by reversing the features array so the most recently appended accent wins — matches human intent.

    D-030 ([DEPLOY: <mode>]): added a deploy-routing rule to the PM prompt — features-only (flag only → instant), by-last-agent role=<role> (code change → the last assigned agent announces deploy), devops (infra/multi-step → devops agent invoked). PmRouting.deploy field + parser. The devops agent was already in the catalog — the issue was PM never invoking it, not a missing role.

    D-032 (parallel fan-out): replaced the sequential for-loop over assignments with FuturesUnordered + staggered starts. Each agent begins at idx × agent_gap_secs so visually they enter In Progress in sequence but execute concurrently. Real LLM mode cuts total time from N × response-time to roughly max(response-time) — about 50% on 3-agent fan-outs.

    Memory addition: feedback_genasis_no_echo_only.md — the operator daemon must never be launched with --echo-only.

  • 2026-05-13: v0.5.20 release — make agentic team work visible in real time (D-028). User report: "the trial agents reply all at once the moment a request is dropped — it looks like a simulation, not real work. Make the live activity visible."

    Root cause: handle_human_post packed each agent's inprogress + done transition into a single message and a single bootstrap round-trip. SSE issue.updated events fired within milliseconds of each other, so LiveKanbanBoard's React render never showed an In Progress card. To a human the kanban looked empty and the agents looked instant.

    Fix: split build_echo_agent_response into build_echo_agent_start (inprogress only) + build_echo_agent_done (done only). The handle_human_post loop now:

    1. posts the agent "착수" message → SSE issue.updated (state=inprogress)
    2. sleeps agent_work_secs (default 6s) — gives humans time to see the In Progress card
    3. posts the agent "완료" message → SSE issue.updated (state=done)
    4. sleeps agent_gap_secs (default 3s) — pause before the next agent

    New CLI flags --agent-work-secs / --agent-gap-secs forwarded by listen start to the child. echo-only no longer collapses to a "simulation in 50ms" — it now reads as deliberate sequential collaboration.

  • 2026-05-13: v0.5.19 release — accent-purple coverage + agents-pool@0e1c117. While verifying v0.5.18 a "make the button purple" chat exercised an echo-mode PM mapper that didn't recognise 보라색, leaving features=[]. Added 보라 / purple / 퍼플 → accent-purple to build_echo_pm_response, plus bg-purple-600 branch in QuizApp. Bumped the agents-pool submodule pointer.

  • 2026-05-13: v0.5.18 release — monitor trial slug normalization (D-026 hotfix). v0.5.17's monitor passed [plane].project_name ("v516 Final" — a human-readable label with a space) directly to the trial-app /api/plane/issues?project_slug= query, which returned {issues: []} because sim_issues are indexed by the slugified form ("v516-final"). load_trial_config now slugifies project_name via genasis_core::config::slugify so the monitor's GET matches the slug the listen daemon uses on genasis init --trial. Real-Plane paths still honour project_id when set.

  • 2026-05-13: v0.5.17 release — daemon SSE auto-reconnect + monitor trial-flavor data wiring (D-024/025). User reported the v0.5.16 daemon as silently broken: the trial-app reported "alive", genasis listen status reported "alive", yet messages sent to the chat panel produced zero agent replies, and genasis monitor showed empty Sprint / Agents / Log-tail widgets. Two defects fixed in one cycle.

    D-024 (genasis-cli/src/listen/trial_sse.rs): reqwest-eventsource::EventSource enters a permanently-closed state where every subsequent next() returns None; the existing code re-used that dead instance forever, so the daemon stayed up but received zero messages. TrialAppSseStream now carries a consecutive_reconnects: u32 and a rebuild() helper with exponential backoff (1s → 2s → 4s → 8s → 16s → 30s cap). next_event detects the None terminator and swaps in a fresh EventSource; a successful SseEvent::Open resets the counter.

    D-025 (genasis-monitor/src/collector/trial.rs + app.rs + state.rs + widgets/sprint.rs): collector::plane::poll_sprint was defined but never invoked from anywhere, so the monitor's Sprint / Agents / Log-tail widgets were permanently empty in trial-mode projects. New collector/trial.rs::poll_trial polls the trial-app /api/plane/issues + /api/mattermost/posts + /api/trial/team-app/status endpoints and returns the same SprintSnapshot + Vec<AgentIssue> shapes plus recent chat lines. app::load_trial_config reads genasis.toml, detects [trial].enabled && (plane.flavor == "trial" || mattermost.flavor == "trial"), and populates AppState.trial_mode + trial_url + team_token + project_slug + scrum_channel. The run-loop fires collect_trial on a 5s tick. Sprint widget header now shows [app_kind · features] so the operator sees at a glance which showcase is published.

    Verification: monitor in a trial-mode project now displays live Sprint Todo/In/Review/Done counts, per-role Agent cards, and a Log-tail of the most recent scrum-channel posts. SSE auto-reconnect logs trial SSE rebuild — sleeping then opening new EventSource after the upstream proxy closes the connection, and the daemon resumes consuming post.created events without operator intervention.

    v0.5.17 tag push = release.yml. operator instance daemon must be restarted with the new binary so the SSE rebuild path is active.

  • 2026-05-12: v0.5.16 release — 시나리오 재설계 + thread-grouped 채팅 UI + daemon-guide banner + QuizApp customization (D-021/022/023). 사용자가 v0.5.15 의 "TODO 앱 만들어줘" 시나리오를 "무의미" 라고 정확히 지적: example PRD 결과물 (Claude Code 퀴즈) 을 확인도 못 하고 엉뚱하게 TodoApp 으로 교체됨. 동시에 trial-app 이 sim_posts 의 root_id 있는데도 thread 시각화 안 되고 flat timeline 으로만 렌더. 자가테스트가 끝나고도 사용자가 직접 채팅으로 후속 요청 가능한 대기 상태 + 종료 가이드 trial-app UI 안에서 노출 필요. 본 사이클이 셋 다 해결.

    agents-pool@f9034ec:

    • LiveChatThread.tsx thread 렌더링 — sim_posts 를 root_id 그룹핑, root post 아래 reply 들을 좌측 indent + border line 으로 들여쓰기 표시. 각 reply 가 data-root-id 보유 (testability). multi-line PM 응답이 whitespace-pre-wrap 으로 legible.
    • QuizAppfeatures?: string[] prop 받음 — accent-red/accent-blue/accent-green 으로 시작 버튼 색상 변경, larger-text 로 글자 크기 증가, 그 외 features 는 시각 badge 로 transparency. ShowcasePanel 이 appFeatures 그대로 전달.
    • LiveBoard 상단에 daemon-guide banner (amber 색): "🤖 Agentic team 대기 중 — genasis listen stop 으로 종료". 사용자가 채팅으로 추가 요청 가능함 + 종료 절차 한 곳에 noted.

    genasis v0.5.16 (listen PM prompt 재설계):

    • routing.rs::build_pm_prompt 가 "쇼케이스는 이미 example prd 결과물 (Claude Code 퀴즈) 로 배포돼 있고, 사람 요청은 그 기존 앱에 대한 수정/커스터마이즈 요구" 라고 명시. PM 이 [APP: quiz] 유지 + [FEATURES: …] 에 accent-red/share-button/dark-mode 등 시각 변경 누적.
    • mod.rs::build_echo_pm_response (echo-only stub) 도 본 시나리오에 맞춰 재설계: "빨간/blue/dark/공유" 키워드 → accent-red/accent-blue/dark-mode/share-button feature 자동 매핑. app_kind 는 기본 quiz 유지.
    • 작업 분배도 "designer + frontend + qa" 3 명 (시각 변경 워크플로우 기본) — Claude Code 모드와 echo 모드 동일 의미.

    검증 (v0.5.16 binary vs 호스팅 URL 새 시나리오):

    • 사람 메시지 예시: "퀴즈 시작 버튼 색상을 빨간색으로 바꿔줘"
    • 결과:
      • PM 응답: [APP: quiz] (그대로) + [FEATURES: accent-red] + 3 명 fan-out
      • sim_teams.app_features += accent-red
      • QuizApp 시작 버튼이 검정 → 빨간색
      • 채팅 패널: 사람 메시지 root + pm/designer/frontend/qa reply 들여쓰기 thread
      • LiveBoard 상단에 daemon-guide banner visible
    • 사용자가 화면에서 example PRD 결과물 (퀴즈) 그대로 보면서 색상 변경 요구 → agentic team 협업 → 시작 버튼 색 즉시 반영. "엉뚱하게 다른 앱으로 교체" 문제 해결.

    자가테스트 후 daemon 대기 안내 (사용자 §"agentic team 대기 + 종료 가이드"): 자가테스트 스크립트가 daemon stop 명시 안 하면 daemon 그대로 살아있음. trial-app banner 가 종료 방법 항상 표시.

    남은 한계 (v0.6.0):

    • 드래그/드롭 칸반 + 카드 상세 모달 미구현.
    • 멘션 자동완성 (@pm 입력 시 dropdown) 미구현.
    • QuizApp 의 share-button 실 구현 (결과 화면에 공유 UI) 미구현 — feature flag 만 활성.
    • real Mattermost flavor 의 Plane integration stub.

    v0.5.16 태그 푸시release.yml 트리거. operator instance agents-pool@f9034ec 동기화 + production rebuild 완료.

  • 2026-05-12: v0.5.15 release — agentic team protocol port (genesis §9 + §26): multi-agent fan-out + thread root_id + sim_issues dynamic + showcase app update (D-018/019/020 + ADR-018). User pushed back hard on v0.5.14: 자가테스트가 echo-only PASS 결론 냈지만 실제로는 ① 쇼케이스가 처음 만든 퀴즈앱 그대로 (TODO 앱 만들어 달라고 했는데 안 바뀜) ② pm 응답이 단일 actor 로 답할 뿐 멘션·작업 분배 흐름 부재. 직접 답: 의도였지만 v0.5.14 구현은 transport 파이프라인만 검증하고 control plane (multi-agent routing) 누락. genesis §9 (Mattermost 소통 프로토콜) + §26 (Ownership-based atomic transaction) 의 trial flavor 등가물을 본 사이클에서 이식.

    agents-pool@8872e92 (trial-app foundation):

    • sim_teams V4→V5 마이그레이션: app_kind + app_features 두 컬럼 추가. idempotent.
    • new setTeamApp(token, kind, features) — features 는 set union 누적.
    • /api/trial/team-app/status POST 와 /api/trial/bootstrap POST 둘 다 optional app_kind + app_features 받음.
    • app/components/demos/PhoneFrame.tsx (모바일 차체 추출) + TodoApp.tsx — features 별 UI 분기 (dark-mode 토글, i18n EN/KO 전환, search 입력, priority/due-date 배지).
    • ShowcasePanelkind === 'todo' 면 TodoApp 렌더, 아니면 legacy QuizApp.

    genasis v0.5.15 (listen daemon multi-agent fan-out):

    • listen/routing.rs (~330 LOC): build_pm_prompt + build_agent_prompt + parse_pm_routing (5 종 마커 regex 추출).
    • handle_human_post: PM claude --print → 사람 메시지 스레드 reply → routing 추출 → sink.apply_pm_routing (sim_teams + sim_issues 갱신) → 각 멘션 role 에 follow-up claude --print → 같은 thread reply → agent 응답의 추가 [CARD: …] 마커 한 번 더 적용.
    • TrialAppSink::replythread_root_id null 이면 source post_id 를 root_id 로 (strategy.md 의 root_id = post.root_id || post.id 패턴 이식).
    • echo-only stub 도 deterministic — LLM 없는 CI 에서도 multi-agent 구조 검증 가능.

    검증 (local release 빌드 vs 호스팅 URL):

    • 사람 메시지 "TODO 앱 만들어줘 — 다크모드 + i18n 지원" → sim_posts: human (id=37, root) → pm/designer/frontend/qa 4 응답 모두 root_id=37 (사람 메시지 스레드).
    • sim_issues 신규 3 카드 + assignee 분배 + 일부 transition done.
    • sim_teams: app_kind=todo, app_features=["dark-mode","i18n"].
    • 쇼케이스: Claude Code 퀴즈 → TodoApp 으로 동적 교체, dark-mode 토글 + i18n EN/KO + ✓ feature badge.
    • Playwright 11 체크 __ALL_PASS__: true.

    binary 크기: 12,025,256 → 12,063,864 (+38 KB).

    남은 한계 (v0.6.0 로드맵):

    • 데모 앱 1 종 (TodoApp) — Pomodoro/Markdown/Counter/Habit 미구현.
    • real Mattermost sink 의 apply_pm_routing 이 Plane integration 미구현 (stub).
    • PM/agent 가 진짜 코드 작성 → trial-app 빌드 트리거 흐름은 feature flag 시뮬레이션 단계.

    v0.5.15 태그 푸시release.yml 트리거. operator instance 는 agents-pool@8872e92 동기화 + production rebuild 완료.

  • 2026-05-12: v0.5.14 release — push-based reactive bridge (SSE/WebSocket) + daemon lifecycle (bridgectl equivalent) + multi-round self-test. User raised three follow-ups on the v0.5.13 listen daemon: (1) after the example app is "built", a continued reactive loop must accept follow-up human messages requesting modifications without restart; (2) polling is acceptable but a true listen should be event-driven (SSE / WebSocket) — favoured a Mattermost client lib if available, else direct WebSocket; (3) flavor=trial must still route exclusively through the trial-app, never reaching real Mattermost/Plane endpoints.

    Library surveycrates.io returns ~8 mattermost-related crates. mattermost_api (DL 11.6k) and mattermost-rust-client (DL 11.7k) cover REST but only patchy WebSocket support; the v0.1 mattermost-rs is too immature (33 DL); mattermost-bot (DL 1.7k) drags a full bot framework. Decision: direct compose of reqwest-eventsource v0.6 (DL 7.5M) + tokio-tungstenite v0.29 (DL 177M). Mattermost WS protocol is a simple authentication_challenge → JSON event stream; one library buys neither protocol robustness nor smaller diff against the existing reqwest stack.

    Binary footprint (clarified the user's concern that 177M DL count was implying massive size — it isn't, DL is a usage popularity counter): v0.5.13 baseline 11,640,928 bytes → v0.5.14 12,025,256 bytes. Δ +384 KB / +3.3%. The new TLS dependencies dedupe against reqwest's existing rustls graph so the real cost is just tungstenite frame parsing + eventsource SSE decoder.

    Listen module redesigncrates/genasis-cli/src/listen/ 신규 모듈:

    • mod.rsInboundEvent::PostCreated + EventStream / EventSink trait + run_listen_loop + is_human_actor / message_requests_done 휴리스틱.
    • trial_sse.rsTrialAppSseStream (reqwest-eventsource 가 SSE 의 reconnect / heartbeat 추상화) + TrialAppSink (POST /api/mattermost/posts + idempotent bootstrap re-seed for "X 완료" directives).
    • mattermost_ws.rsMattermostWsStream (직접 tokio-tungstenite 사용, wss://…/api/v4/websocket 연결 후 authentication_challenge 보내고 event="posted" 필터, exponential backoff 1→30s 재연결) + MattermostSink (POST /api/v4/posts, Plane transition 은 v0.6.0 후속으로).
    • lifecycle.rsbridgectl.sh 등가물. PID 파일 (.genasis/listen.pid), 로그 (.genasis/listen.log), /proc/<pid>/cmdline 매칭으로 고아 탐지, slug 당 1 프로세스 보장.
    • cmd_listen.rs — Args 전부 global = true 로 두어 genasis listen start --trial --echo-only 형태가 자연스럽게 됨. Foreground (default) / start / stop / status / restart / logs 서브명령.

    SSE 이벤트 포맷 디버깅 — 초기 구현은 data.kind == "post.created" 검사. 실제 trial-app SSE 는 event: post.created\ndata: <SimPost JSON> 형태 (kind 가 SSE event: 라인). reqwest-eventsource 의 Event::Message { event, data }event 필드를 검사하도록 수정 → 1줄 패치로 reactive 활성화.

    다라운드 자가테스트playwright-v514-multi.py 가 호스팅 URL 에서:

    • 1라운드: 사람 "TODO 앱 만들어줘 — 다크모드 지원" → [pm] 응답 visible
    • 2라운드: 사람 "방금 만든 거 한국어로도 보이게 해줘" → [pm] 추가 응답 visible
    • 4 데모 카드 모두 Done
    • Playwright __ALL_PASS__: true

    flavor 격리 보존cmd_listen.rs::build_loop_componentsgenasis.toml [trial].enabled (또는 --trial 명시) 검사 → trial 분기는 오직 trial-app /api/* 만 호출, real 분기만 MM_ADMIN_TOKEN 요구하고 Mattermost 직접. genesis §0 대전제 (사람↔agent 소통은 두 채널만, 인스턴스 격리) 보존.

    Pushing v0.5.14 tag triggers release.yml.

  • 2026-05-12: v0.5.13 release — genasis listen reactive bridge + ticket-state coherence (D-013 + D-014 + TR-3). User pointed at the hosted Live Trial URL showing a self-contradicting kanban (Todo + InProgress cards leftover from init while Done already had "🎉 Example app published") AND zero agent response to a human's chat question at 11:35. Read /work/secusy/genesis/strategy.md §0/§26/§28 — the original genesis design required all human ↔ agent communication to flow through Mattermost+Plane via a reactive bridge daemon (scripts/mattermost-bridge.mjs in the legacy stack) that polls the channel, detects mentions, and spawns claude --print headless. The genasis trial flavor had every static piece of that design (10 agent overlays carrying ownership-atomic-transaction logic, 14 /sprint-* /check-inbox /agent-resume commands, the GENASIS.md charter) but was missing the bridge daemon itself — making the autonomous loop entirely manual.

    D-013 (ticket-state coherence):

    • agents-pool/trial-app/db/sim.ts::ensureIssue short-circuited on if (existing) return existing and silently discarded input.state / input.assignee. Patched to call transitionIssue when caller specifies state/assignee differing from the existing row. Brand-new row path unchanged.
    • genasis publish demo_issues extended from 2 cards (Build done + Example app published done) to 3 cards (Write-PRD done + Build done + Example app done) so the kanban end-state after publish is Done=4, InProgress=0, Todo=0 instead of contradicting itself.
    • agents-pool@8b03654 ships the trial-app side.

    D-014 (reactive bridge — genasis listen):

    • New cmd_listen.rs (361 lines) — async daemon that:
      1. Loads [trial] config + per-team token from genasis.toml.
      2. Streams GET /api/events/stream?team=<token> as SSE.
      3. Filters post.created events whose actor is human-looking (not in KNOWN_ROLE_BOTS).
      4. Spawns claude --print with a Korean role-aware prompt, 120s timeout.
      5. POSTs the agent reply back to /api/mattermost/posts under the configured --default-actor (default pm).
      6. Best-effort maybe_transition_card heuristic — when the human says "X 완료" / "done" the daemon re-bootstraps the four init cards to Done via the idempotent path so the kanban catches up to the chat narrative.
    • Flags: --trial, --echo-only (CI mode without claude), --default-actor, --claude-timeout-secs, --max-events.
    • reqwest gains stream feature + new futures-util workspace dep for SSE byte-stream consumption.

    GENASIS.md charter updated with a new "Reactive bridge (자동 응답 데몬)" sub-section telling every agent persona that human chat is wired through genasis listen. Without the daemon the autonomous loop does not fire.

    TR-3 self-test policy expansion:

    • /work/genasis/CLAUDE.md §자가개발 및 테스트 step 4 adds three explicit verification items (card-state coherence / reactive loop / human-directive transition).
    • Step 10 termination condition strengthened: cycle exits only when items 1·2·3 all PASS in Playwright.
    • /work/agenteams/team-ex/CLAUDE.md (user SSOT) gains §14 + §15 mirroring the same requirements + obligating self-tests to spawn genasis listen --trial in the background before claiming PASS.

    Pushing v0.5.13 tag triggers release.yml. agents-pool@8b03654 is already live on mmplane-trial.realstory.blog.

  • 2026-05-12: v0.5.12 release — D-011 (operator dev-mode build) + D-012 (sim DB FK pointing at dropped legacy table) + trial provider tracing + stale-host detection. User reopened the v0.5.11 cycle pointing at the hosted URL https://mmplane-trial.realstory.blog/?tab=live&team=… still empty and demanded direct diagnosis instead of recommending the local-docker workaround again. The user also flagged that any debugging must keep using the hosted domain — Caddyfile forwards mmplane-trial.realstory.blog → localhost:2001, so the operator host is the same machine running self-test. Three layered problems uncovered, all fixed end-to-end.

    D-011 — operator was running npm run dev directly off agents-pool@677bd5d:

    • ps traced the process tree: zsh → npm run devnext dev --port 2001. dev-mode Next.js, started 18h prior to D-011 trigger, on a commit that predates D-009 (ec7f149) by 2 commits. zod's safeParse silently strips unknown keys, so demo_issues + welcome_message from v0.5.10's bootstrap call never reached the DB layer.
    • Resolution: killed the dev process tree, git pull on /work/mmplane-trial.realstory.blog/trial-app/ (677bd5d → ec7f149 → 673764b), npm run build, nohup PORT=2001 npm start &. Caddyfile reverse-proxy unchanged. Bootstrap response now echoes the new keys.

    D-012 — sim_issues / sim_posts FK still pointed at the dropped sim_projects_legacy / sim_channels_legacy tables:

    • After redeploying, the first bootstrap with demo_issues:[…] failed with SqliteError: no such table: main.sim_projects_legacy. The V0→V2 rebuild path (ALTER TABLE sim_projects RENAME TO sim_projects_legacy followed by CREATE TABLE sim_projects (… new schema …)) made SQLite ≥3.25 auto-rewrite the FK in sim_issues from →sim_projects(slug) to →"sim_projects_legacy"(slug). The rebuild then dropped sim_projects_legacy but didn't fix sim_issues's FK back. Same trap on sim_posts → sim_channels. Pre-v0.5.10 bootstrap never wrote to sim_issues, so this stayed dormant until D-009's seeding tried.
    • Fix in agents-pool@673764b: new V3→V4 migration in db/index.ts that uses sqlite's documented FK-fix recipe (table rebuild under PRAGMA foreign_keys=OFF). Idempotent — only runs when PRAGMA foreign_key_list reports the broken ref. Applied cleanly on the operator's 104-project DB (104 projects / 104 channels / 1 issue / 0 posts preserved).

    Trial provider tracing (D-011 trace 트랙 3a):

    • tracing::info!(target="trial", provider=…, op=…, …) added to every Plane/Mattermost call on the trial flavor: ensure_project, create_issue, transition, post_root, post_thread. Each call emits an outbound → POST/PATCH … line then a ← sim row created/updated line carrying the sim row id back, so users running RUST_LOG=trial=info genasis <cmd> get end-to-end correlation between agent intent and trial-app DB writes.

    Stale-host detection (트랙 3b):

    • try_bootstrap_trial_app now parses the bootstrap response JSON and emits a warning if demo_issues and welcome_message keys are absent (the deployed schema predates ec7f149). Points the user at README §Known limitations and the GENASIS_TRIAL_URL workaround. Without this, users would see green CLI output and an empty kanban with no signal that the server dropped their seed data.

    Verified live (v0.5.12 against https://mmplane-trial.realstory.blog):

    • Fresh genasis init --trial --name "D-012 Hosted Verify" → bootstrap ok, stale warning absent. New team 35247bd0… issued.
    • RUST_LOG=trial=info genasis init (bare) → tracing line → resolving trial sim project provider="plane" op="ensure_project" team_token_short=35247bd0 project_name="D-012 Hosted Verify" visible in stderr, then plane project_id = d-012-hosted-verify.
    • genasis publish+ seeded build-complete card + chat message + landing URL https://mmplane-trial.realstory.blog/?tab=live&team=35247bd0….
    • Playwright against the hosted URL: __ALL_PASS__: true — 4/4 demo cards + 2/2 welcome messages + showcase handle active.

    Pushing v0.5.12 tag triggers release.yml. agents-pool@673764b is the operator-side dependency; the production server at port 2001 is already on it.

  • 2026-05-12: v0.5.11 release — Quick Path inline sanity checks + stale-hosting jump-out (D-010). Re-ran the self-test cycle per the user's repeat trigger. CLI 1-5 all green from a fresh v0.5.10 install, but Playwright diagnosed that a brand-new user who follows README verbatim against the default operator-hosted URL still sees an empty kanban + empty chat — every visible signal that "something happened" is missing until they scroll all the way to §"Known limitations". Side-by-side: the same flow with GENASIS_TRIAL_URL=http://localhost:2099 shows 4 cards + 2 welcome messages + active showcase handle. The v0.5.10 escape hatch works, it's just not discoverable in the 5-minute path.

    Fix (D-010) — README + README.ko §"Quick Path":

    • Step 2 now ends with a 🔍 Sanity check callout: open the landing URL right then, expected to see team badge + 3 demo cards + welcome chat. Empty kanban means stale hosting → jump-link to the new §"Known limitations (v0.5.11)" anchor for the one-line export GENASIS_TRIAL_URL=http://localhost:2099 workaround.
    • Step 5 (after genasis monitor) gets a 🔍 Final sanity check callout: refresh the URL, expected state is 5 cards (incl. 🎉 Example app published in Done) + 2 messages + clickable showcase handle. Also calls out the legitimate "showcase-only" state if the user chose to skip the local-docker hop earlier — so they don't double-back unnecessarily.
    • Bilingual mirror updated in README.ko.md with the same callouts.

    Verified live (v0.5.10 binary, two scenarios — same Playwright run):

    • A. Default hosting (https://mmplane-trial.realstory.blog): badge ✅, kanban 0/4, chat 0/2, showcase handle ✅ (because publish only flips app_status). Matches the new "empty after Step 2" warning.
    • B. Local override (http://localhost:2099): badge ✅, kanban 4/4, chat 2/2, showcase handle ✅. Matches the new "5 cards + 2 messages after Step 5" expectation.
    • Screenshots: /work/agenteams/team-ex/screenshots/cycle-{A_default_hosting,B_local_override}.png.

    Other items observed but not blocking:

    • D-006 (404 resource) — page.on('response') capture confirmed 0 4xx responses across all 11 resources. The "Failed to load resource" console line is an SSE stream close noise. Marked non-defect.
    • D-007 (caret-color hydration warning) — does NOT reproduce against the locally-built ec7f149 container. Hosting-side dev-mode build artifact, expected to disappear when the hosted instance is rebuilt.

    No code change in this release — cargo build runs only to keep Cargo.lock in sync after the workspace version bump. Pushing v0.5.11 tag triggers release.yml so the README that install.sh indirectly links to ships with the same Quick Path the binary supports.

  • 2026-05-12: v0.5.10 release — GENASIS_TRIAL_URL env override + D-009 end-to-end proof. User pushed back on the v0.5.9 cycle's conclusion of "wait for operator redeploy" with "네가 직접 D009 Test 결과를 보고 왜 정보가 사라졌는지 추적해서 문제 해결해". Direct diagnosis (instead of assuming): POST'd to https://mmplane-trial.realstory.blog/api/trial/bootstrap with demo_issues + welcome_message — response shape confirmed no new fields in the JSON output, meaning the hosted instance is running pre-ec7f149 code. Probed /api/plane/issues + /api/mattermost/posts — both 401 with the pre-D-001 secret-required contract. Hosted instance is genuinely behind.

    End-to-end verification via local docker (proves binary + agents-pool code are correct):

    • Built mmplane-trial-app:d009-debug from the current agents-pool tree (ec7f149), ran it on port 2099.
    • POST'd directly to http://localhost:2099/api/trial/bootstrap with demo data — response included demo_issues: [...] and welcome_message: {id, channel_id, message} rows.
    • Playwright opened http://localhost:2099/?tab=live&team=<token> — visible: 3 demo cards distributed across Done/InProgress/Todo + 1 welcome chat post. D-009 fix works end-to-end with no operator dependency.

    Fix (the actual binary change):

    • Replaced the hardcoded const TRIAL_APP_URL in cmd_init.rs with a trial_app_url() function that reads GENASIS_TRIAL_URL from env, falling back to https://mmplane-trial.realstory.blog.
    • The override flows consistently through: (1) the render_trial_config writer that produces genasis.toml [trial].url, (2) the try_bootstrap_trial_app POST endpoint, (3) the --probe-only summary, (4) the per-team open URL printed in the success banner, (5) genasis publish (already reads [trial].url so picks it up).
    • README + README.ko Known limitations (v0.5.10) documents the full workaround: sparse-checkout agents-pool/trial-app → docker build → docker run -p 2099 → export GENASIS_TRIAL_URL=http://localhost:2099.

    Verified live (v0.5.10 binary against localhost:2099):

    • genasis init --trial --name "Local D-009 Verify" → bootstrap ok, 3 demo cards seeded (Set up agentic team Done, Write PRD… InProgress, Build the example app… Todo) + welcome message "👋 …팀이 시작됐어요…".
    • genasis publish → status flipped to complete, 2 additional cards seeded (Build the example app… Done, 🎉 Example app published Done) + "✅ 빌드 완료…" message.
    • Playwright: 4/4 cards visible across columns, 2/2 welcome messages, showcase handle "에이전트가 만든 앱 보기" active. Done column shows 2 entries with @genasis assignee labels.

    Pushing v0.5.10 tag triggers release.yml. Hosted mmplane-trial.realstory.blog is still stale for the default-URL path, but users now have a fully working alternative via GENASIS_TRIAL_URL.

  • 2026-05-12: v0.5.9 release — Live Trial UI shows visible activity after init --trial / publish (D-009). User opened the post-publish Live Trial URL from the previous self-test cycle and reported "여전히 작업 진행했던 흔적이 남아 있지 않아" — kanban was empty, chat thread was empty, showcase handle alone wasn't enough signal that the system did anything. Root cause: try_bootstrap_trial_app only seeded team + project + channel rows; genasis publish only flipped app_status to complete. No actual cards or messages.

    Fix (D-009):

    • agents-pool@ec7f149: extend /api/trial/bootstrap to accept two optional fields:
      • demo_issues[] — initial kanban cards (title + state + assignee), seeded via new ensureIssue() helper keyed on (team_token, project_slug, title) for idempotency.
      • welcome_message — root post in the first channel, seeded via new ensureWelcomePost() keyed on (actor, message).
    • genasis: try_bootstrap_trial_app (called during init --trial) now sends 3 demo cards spanning Done/InProgress/Todo plus a Korean welcome message that points the user at next steps. run_publish sends 2 additional "build complete" cards plus a publish-confirmation message — also via bootstrap (idempotent), so no extra round-trip semantics.
    • Re-running init --trial or publish never duplicates content thanks to the trial-app side dedup. The publish seed failure is non-fatal — status flip already succeeded so the warning message is just informational ("UI may not reflect the published state until the deployed trial-app catches up").
    • Submodule pointer bumped to agents-pool@ec7f149.

    Verified:

    • cargo build --release -p genasis-cli clean, cargo test --workspace --lib: 162 passed
    • npx tsc --noEmit on trial-app clean

    Pushing v0.5.9 tag triggers release.yml. Once deployed, the operator-hosted trial-app must redeploy from agents-pool@ec7f149 for the new fields to be honoured (otherwise they are silently dropped per the z.optional() schema — bootstrap continues to work, just without seeding).

  • 2026-05-12: v0.5.8 release — install.sh prefix safety + README Self-host entry point (D-005 + D-008). Continued self-test cycle (now with Playwright browser verification against the live deployed trial-app) caught two new defects from the fresh-user perspective.

    Fix (D-005)install.sh --prefix=<new-path> silently lied:

    • User passing --prefix=/some/new/dir (a non-existent path) hit mv: cannot stat, fell through to sudo install which failed silently in non-TTY contexts (curl|sh, CI runners) without aborting because set -e does not propagate past sudo's interactive password prompt. The script then printed [OK] Installed: <path> even though no binary was actually written.
    • Fix: mkdir -p "$PREFIX" 2>/dev/null || true before mv. sudo install now goes through elif ... 2>/dev/null so its failure is caught explicitly, with a die that lists the writable default. A post-install [ -x "$install_path" ] hard check guarantees the success line only fires when the file truly exists.
    • Verified live: sh install.sh --prefix=/tmp/install-test-new --skip-prereqs --no-run against a non-existent prefix now creates the dir, writes the 11 MB binary, and the resulting genasis --version reports 0.5.7 (just-fetched release).

    Fix (D-008) — README Self-host Option B unreachable from Quick Path:

    • The "Step-by-Step → Set Up Plane & Mattermost → Option B" block jumped straight to cd servers && ./scripts/setup-user-env.sh && docker compose up -d, but install.sh only ships the genasis binary — the servers/ dir was never fetched. New users following the README hit bash: cd: servers: No such file or directory and had no way forward.
    • Fix: added a "First fetch the servers/ directory" preamble with two retrieval paths (full clone, or sparse-checkout via git sparse-checkout set servers). Bilingual mirror updated in README.ko.md.

    Verified:

    • install.sh round-trip end-to-end against --prefix=/tmp/install-test-new
    • README Quick Path 1-5 still green from a fresh install.sh install of v0.5.7 binary against the live deployed mmplane-trial.realstory.blog
    • Playwright browser check: Live Trial page renders Marketing Squad + scrum-marketing-squad channel + 4-column kanban + chat sidebar; genasis publish flips app_status to complete and the showcase handle becomes visible

    Pushing v0.5.8 tag triggers release.yml.

  • 2026-05-12: v0.5.7 release — genasis attach --upgrade flag matches its own deprecation message (D-003). Continued self-test against v0.5.6 binary revealed the deprecation message on the Upgrade subcommand pointed users at genasis attach --upgrade (and the README CLI reference echoed it), but that flag did not exist on cmd_attach::Args — running it produced error: unexpected argument '--upgrade' found, leaving the user with no documented migration path off the deprecated subcommand.

    Fix (D-003):

    • Added --upgrade boolean flag to cmd_attach::Args. Currently a passthrough — the existing re-attach machinery IS the upgrade — but the flag carries user intent and primes future versions to adopt a more conservative policy (e.g. preserve Tampered fences by default to match the legacy cmd_upgrade behaviour).
    • Updated the two internal call sites (cmd_bootstrap and cmd_lang) to set upgrade: false.
    • Live: genasis attach --upgrade --non-interactive now succeeds and runs the standard re-attach plan.

    Pushing v0.5.7 tag triggers release.yml.

  • 2026-05-12: v0.5.6 release — genasis agents list / browse / status works against v1.0.0 catalog (D-002). Same self-test cycle that closed D-001 in v0.5.5 surfaced a second long-standing gap: genasis agents list errored with agents/index.json not found. Run genasis agents fetch first., but genasis agents fetch reported the catalog as already cached with 492 agents available — a circular dead-end. Root cause: the v1.0.0 release tarball ships manifest.json (metadata about overlay roles) but not index.json (the searchable catalog the marketplace commands expect), and the binary did not synthesise one client-side.

    Fix (D-002):

    • New load_catalog_index(version, cache_override) helper in cmd_agents.rs with a 3-level fallback chain: project-local ./agents/index.json → cache <dir>/v<ver>/index.jsonsynthesise from cache base/ frontmatters. The synthesis walks every .md under <cache>/base/, parses YAML frontmatter via the existing genasis_core::frontmatter API (single-line scalar reader for name / description / category / tags), and builds the {agents: [], categories: [], presets: {}} shape every command already consumes. _source: "synthesised-from-cache-base-frontmatters" is annotated in the index so agents status can surface where the data came from.
    • cmd_list, cmd_browse, cmd_status, install_preset all route through load_catalog_index now. When agents-v1.0.1 ships with a proper index.json the synthesis becomes dead code and the binary picks up the richer shape (preset definitions etc.) without further changes.
    • Presets are still empty (frontmatters don't carry preset membership), so genasis agents install --preset web-app now gives a one-line message pointing the user at install <name> instead of the cryptic no presets defined in index context error.

    Verified:

    • cargo build --release -p genasis-cli clean
    • Live: genasis agents list → 492 agents, paginated; genasis agents list --search frontend → 4 hits (angular-architect, frontend-developer, frontend-security-coder, fullstack-developer); genasis agents statusIndex: 492 agents available (synthesised-from-cache-base-frontmatters) — the previous dead-end is now self-explanatory.

    Pushing v0.5.6 tag triggers release.yml.

  • 2026-05-12: v0.5.5 release — Quick Path self-heals against stale operator deployment (D-001). Self-test cycle against v0.5.4 binary uncovered that the Quick Path still hard-failed at step 4 (genasis init after --trial) with a 401 from /api/plane/projects whenever the hosted mmplane-trial.realstory.blog deployment lagged behind agents-pool@289876c. The v0.5.4 release notes had documented this as an operator action item, but a fresh user has no way to redeploy somebody else's server. This release moves the work into the binary so the Quick Path becomes self-healing.

    Fix (D-001):

    • TrialPlane::ensure_project now calls GET /api/trial/team-app/status?team=<token> first (auth-free, accepted by all deployed versions). When the team already exists (which it always will, because try_bootstrap_trial_app ran during --trial), returns the bootstrap-canonical slugify(project_name) immediately — no POST to the auth-locked /api/plane/projects needed. As a side benefit this fixes a latent slug-consistency bug: bare genasis init was deriving slug from slug_to_identifier(name) (e.g. "MARK" for "Marketing Squad"), which collided with bootstrap's slugify("Marketing Squad")="marketing-squad". Downstream create_issue / transition calls now hit the same sim row the Live Trial UI renders.
    • TrialMattermost::ensure_channel routes through the auth-free idempotent /api/trial/bootstrap endpoint (passing the target channel as a single-element channels[] array). Bootstrap returns the existing channel row's id without going through the auth-locked /api/mattermost/channels POST.
    • Both methods retain a legacy POST fallback for very old self-hosted deployments and emit a one-line remediation message ("the deployed trial-app is older than this binary; redeploy or self-host") instead of the raw {"error":"unauthorized"} body when the legacy path returns 401.

    Not in this release:

    • Agent-runtime calls (create_issue, transition, post_root, post_thread) still target the legacy /api/plane/issues / /api/mattermost/posts routes and will still 401 against an out-of-date deployment. Closing that gap is a larger refactor (the trial provider would have to maintain its own (issue_id → sim row) mapping) and isn't needed for the Quick Path to look good to a new user. README §"Known limitations (v0.5.5)" now flags this honestly.

    Self-development & testing:

    • Added ## 자가개발 및 테스트 section to CLAUDE.md codifying the iterative test→fix→push→monitor→retest loop. Test bed is /work/agenteams/team-ex/ with PLAN.md + genasis-test-log.md; the protocol is self-contained — no external ~/rnd/agenteams/team01/... dependency. Claude Code sessions can re-enter this loop autonomously.

    Verified:

    • cargo build -p genasis-providers clean, cargo test -p genasis-providers 23 passed
    • Live integration test against mmplane-trial.realstory.blog (deployed v0.5.4-era app): Quick Path 1→4 now succeeds end-to-end. genasis init after --trial returns plane project_id = test-v055-live without 401.

    Pushing v0.5.5 tag triggers release.yml (musl-static x86_64 + aarch64 via cross, Verify-static-linking + compat-smoke gates, GitHub Release with both tarballs + sha256s).

  • 2026-05-12: v0.5.4 release — 8 v0.5.3 field defects (C1-S1) + clean Quick Path on next operator deploy. Tester ran v0.5.3 end-to-end on a clean WSL2 box and filed 11 defects (C1-3 critical, S1-4 significant, M1-4 medium, D1 low). 4 of those (S2, S4, M4, and partially S3) were already addressed by earlier patches; this release closes 8 more. The Quick Path is now end-to-end functional from binary alone IF the hosted mmplane-trial.realstory.blog deployment is at least at the agents-pool 289876c commit (token-as-capability for all bridge routes — see C1 below).

    Fixes:

    • C1 (hosted trial-app 401) — partial. The genasis binary side has been correct since v0.5.3 (289876c in agents-pool dropped shared_secret check from all bridge routes), but the deployed mmplane-trial.realstory.blog may not have been rebuilt yet. Added README §"Known limitations" pointing operators at the redeploy step and explaining how users can self-host the trial-app if they're blocked.
    • C2 (catalog short-name files) — the Role::aliases() + infer_from_name aliases I added in v0.5.3 already let bootstrap and attach work against the long-name files. v0.5.4 additionally teaches cmd_doctor's frontmatter check about the same alias table so 7 false-positive "name: doesn't match filename stem" warnings are silenced. The catalog itself should still ship short-name files for cleanliness in agents-v1.0.1 — tracked separately.
    • C3 (GENASIS.md never written) — the v1.0.0 catalog tarball doesn't bundle <lang>/GENASIS.md.tera at all, but cmd_attach printed + GENASIS.md in its summary regardless. Two-part fix: (a) agents/GENASIS.md.tera from the genasis repo is now include_str!'d into the binary as a fallback, so GENASIS.md gets written even with a catalog that's missing the template; (b) the summary line is rewritten to honestly state how many files were written, with a separate warning when GENASIS.md couldn't be produced. Once agents-v1.0.1 ships the template, the catalog copy takes precedence.
    • S1 (channel slug spaces) — overlay templates rendered #scrum-Marketing Squad because they interpolated project_name raw. Two-part fix: (a) registered a slugify Tera filter on build_tera_from_store so future templates can write {{ project_name | slugify }}; (b) added project_slug to build_context (pre-slugified by genasis_core::config::slugify) and updated the 20 overlay source templates in agents/overlays/{en,ko}/ to use project_slug for channel references. The next catalog release ships these.
    • M1 (MM channel idempotence ugly)UpstreamMattermost::ensure_channel now does a lookup first (GET /teams/{id}/channels/name/{name}) and only POSTs on 404. The store.sql_channel.save_channel.exists.app_error gobbledygook string never reaches users anymore. Also handles the race case (POST returns the error string instead of an id) with a follow-up lookup.
    • M2 (Plane health probe 401 noise) — switched the probe from /api/v1/workspaces/<slug>/ (auth-gated, 401 even with valid API key) to /api/instances/ (unauth metadata endpoint). Clean 200/JSON on a healthy server; transport errors still surface as before. Workspace existence is verified later in ensure_project's paginated walk where it belongs.
    • M3 (install.sh hang in curl | sh) — the lang prompt was already TTY-aware, but genasis attach invoked from inside install.sh inherits the curl pipe as stdin. Added </dev/null on the attach invocation so the child can't possibly read user-meant bytes from the script pipe.
    • Doctor name_mismatch warningcmd_doctor was warning on every clean install because catalog name: frontend-developer doesn't match filename frontend.md. Now uses the same infer_from_name alias resolution as cmd_attach; only warns when stem and value resolve to different roles (genuine bug) instead of when they textually differ (alias case).

    Verified:

    • cargo fmt --all clean
    • cargo clippy -p genasis-cli -p genasis-overlay -p genasis-providers --tests -- -D warnings clean
    • cargo test --workspace: 269 passed, 4 ignored
    • trial-app npm run typecheck + npm run build clean (no agents-pool change needed in this release)
    • i18n drift gate: 148 keys OK

    Pushing v0.5.4 tag triggers release.yml (musl-static x86_64 + aarch64 via cross, Verify-static-linking + compat-smoke gates, GitHub Release with both tarballs + sha256s).

    Deferred to next minor (v0.6.0):

    • S3 (token provisioning helper): new genasis init bootstrap-tokens subcommand that runs the ~9-step Plane + Mattermost admin API dance automatically.
    • agents-v1.0.1 catalog refresh: short-name base files (pm.md, frontend.md, …) + slugify-using overlay templates + <lang>/GENASIS.md.tera. Once shipped, every C2/C3/S1 fallback in this binary becomes a fast-path.
  • 2026-05-12: v0.5.3 release — CLI simplification (A-E) + 6 v0.5.2 field-reported defects (가-바). Tester ran v0.5.2 end-to-end and surfaced six new defects on top of the v0.5.0 round; this release fixes all six and ships the planned CLI-surface simplification (init/publish primary, bootstrap/attach/lang/upgrade/plane/mm deprecated with v0.7.0 removal milestone).

    Debug fixes:

    • 가 — Tera lex error on ${#body} killed 5 of 6 hooks. cmd_attach's install_genasis_overlay_artifacts was rendering every .tera through Tera::one_off with ? propagation, so the first file containing ${#var} (bash length expansion, where {# looks like the start of a Tera comment) bailed the whole loop. Switched to a render_template_body helper that only invokes Tera when {{ or {% actually appears in the body; everything else passes through verbatim. Per-file errors are now warnings, never propagated. All 6 hooks (session-start, branch-guard, MM-sync, worktree-guard, user-prompt-submit-mm, post-tool-trim) plus 17 commands now land in .claude/genasis/.
    • 나 — trial-app bootstrap ok printed despite team_exists: false on the server. try_bootstrap_trial_app checked only the POST status code, so a server that accepted but didn't persist (older deployment, schema drift, etc.) silently lied. Added a follow-up GET /api/trial/team-app/status?team=<token> verify call after the POST; if team_exists is false, the function returns a clear error pointing at "deployed trial-app may be older than the bootstrap contract this binary expects."
    • 다 — /api/plane/projects 401 because operator-only shared_secret was required. Generalised ADR-016 §4 from "bootstrap is unauth, everything else needs secret" to "all trial-app routes use token-as-capability; shared_secret is optional defence-in-depth". Renamed requireTrialContextresolveTrialContext in lib/trial-auth.ts (legacy alias kept for one release); updated all 5 bridge routes (plane/{projects,issues,issues/[id]}, mattermost/{channels,posts}) to drop the secret check. ADR-016 §4 updated.
    • 라 — 6/10 agents had frontmatter name: mismatch → overlay fence not injected. The same alias-walk symmetry I added to Role::aliases() for bootstrap-side filename resolution was missing on attach-side frontmatter name resolution. Extended infer_from_name to recognise the v1.0.0 catalog's actual name: values (frontend-developer, backend-developer, qa-expert, product-manager, devops-engineer, security-engineer, design-system-architect, etc.) so all 10 canonical roles resolve regardless of which side of the boundary they cross.
    • 마 — CLAUDE.md, GENASIS.md missing. GENASIS.md install survived the issue-가 Tera fix automatically (the install function no longer aborts the whole call on a single template error). Additionally, install_genasis_overlay_artifacts now writes a CLAUDE.md stub with the @import GENASIS.md line if no CLAUDE.md exists at the project root — without that import, Claude Code never loads the protocol contract and the slash commands + hooks are orphaned. Existing CLAUDE.md is left alone (idempotent).
    • 바 — humans sync Plane half requires PLANE_ADMIN_EMAIL / PLANE_ADMIN_PASSWORD, undocumented. README EN+KO §"Option B" credentials block expanded with explicit setup notes pointing at the same god-mode admin credentials used in Step-by-Step §"Provision admin tokens". Plane API-key auth alone can't create users; admin sign-in is required.

    CLI simplification A-E (deprecation messages with v0.7.0 removal milestone):

    • A: init promoted as Primary entry point in clap help text. bootstrap and attach re-described as [Advanced] — useful for hand-authored or partial-scaffold workflows, but daily users should run init.
    • B: New top-level genasis publish subcommand that takes the same PublishArgs (--dry-run, --project) as genasis trial publish. trial publish still works but emits a deprecation note. New cmd_trial::run_publish_with_project shared between both paths.
    • C: genasis lang prints a deprecation note pointing at genasis attach --lang=<en|ko> before running.
    • D: genasis upgrade prints a deprecation note pointing at genasis attach --upgrade before running.
    • E: genasis plane / genasis mm print deprecation notes pointing at genasis doctor --probe-plane / --probe-mm.

    All deprecated subcommands continue to function exactly as before — only the help-text classification and the runtime stderr note change. v0.7.0 will remove them.

    Verified:

    • cargo fmt --all clean
    • cargo clippy -p genasis-cli -p genasis-overlay --tests -- -D warnings clean
    • cargo test --workspace: 269 passed, 4 ignored
    • trial-app npm run typecheck + npm run build: clean
    • i18n drift gate: 148 keys OK
    • Pushing v0.5.3 tag triggers release.yml (musl-static x86_64 + aarch64 via cross, Verify-static-linking + compat-smoke gates, GitHub Release with both tarballs + sha256s).
  • 2026-05-12: v0.5.2 release — fix 11 field-reported defects from v0.5.0 + ship binary. End-to-end Quick Path tester report flagged 11 distinct defects against v0.5.0; this release closes 8 of them (3 documented as known limitations with workarounds). Bumped workspace.version = "0.5.1""0.5.2" and tagged v0.5.2 on HEAD. Fixes:

    • run_trial agent-bootstrap chain (the primary "팀 폴더에 .claude/agents 비어있음" symptom): genasis init --trial was creating an empty .claude/agents/ and exiting; the user had to discover genasis bootstrap themselves. Now run_trial threads lang_flag / non_interactive / assume_yes and calls cmd_bootstrap::run (which auto-chains to cmd_attach) immediately after writing genasis.toml. --probe-only still skips bootstrap so tests don't pay the catalog-fetch cost. Failures are surfaced as warnings rather than aborting init so the user still gets their team_token.
    • Issue #11: cmd_attach never installed slash commands / hooks / skills / GENASIS.md even though the README has always promised them and the v1.0.0 catalog has the .tera templates ready. New install_genasis_overlay_artifacts() helper renders commands/*.tera.claude/genasis/commands/*.md, hooks/*.tera.claude/genasis/hooks/*.{sh,md} (chmod 0755 for .sh), skills/*.tera.claude/genasis/skills/*.md, and <lang>/GENASIS.md.tera → project-root GENASIS.md. The 18 slash commands (/sprint-start, /issue-done, /db-migrate, …) + post-tool-trim hook + GENASIS.md protocol contract now land on attach.
    • Issue #6: servers/docker-compose.yml added networks.default.aliases: [web|api|space|admin|live] to plane-{web,api,space,admin,live} services. Plane's baked-in proxy Caddyfile expects bare hostnames; without aliases every request to localhost:${PLANE_PORT} 502'd with dial tcp: lookup web: i/o timeout. Fixed.
    • Issue #5: README + README.ko Plane at localhost:8080, Mattermost at localhost:8065 was a hardcoded lie — setup-user-env.sh actually allocates 38400/38500 + uid % 50 offset. Rewrote the §"Option B" instructions to describe the allocator + show how to read the assigned ports out of .env.
    • Issue #8: UpstreamPlane::health was probing /api/v1/health/ which Plane v1.2.3 returns {"error":"Page not found."} for — alarming in genasis init output but non-fatal. Switched to /api/v1/workspaces/<slug>/ which is stable and returns 200/401/404 (all "server up") cleanly.
    • Issue #10: UpstreamPlane::ensure_project always POSTed /projects/ regardless of existence → re-running genasis init failed with "The project name is already taken". Added find_project_by_name_or_identifier (walks paginated /projects/?next=...) and returns the existing id on match.
    • Issue #9: MM_TEAM_ID was required-but-undocumented for channel provisioning. Now auto-resolves from [mattermost].team_name via GET /api/v4/teams/name/<name> using the same MM_ADMIN_TOKEN already in scope. Falls back to the legacy "skipped" message if the lookup fails. README explicitly mentions MM_TEAM_ID as a fallback env var.
    • tera dep added to genasis-cli so cmd_attach can render command/hook templates. The v1.0.0 catalog templates don't actually use Tera variables today, but Tera::one_off is forward-compatible.
    • Already-fixed-in-main-but-unreleased (1, 2, 3, 4): ADR-016 + ADR-017 multi-tenancy + showcase + Linux musl-static release config + install.sh --lang ko space-form parsing — all 13 commits between v0.5.1 (local-only tag) and v0.5.2 land in this release.

    Documented as known limitations (defer to next patch):

    • Issue #7: Plane sets Secure on CSRF cookies over plain HTTP → browser sign-up fails. Workaround documented (host-Caddy + self-signed cert, or browser CSRF override).
    • Issue #5a: genasis agents list/install/browse fail because index.json ships as a copy of manifest.json (missing agents/presets/categories arrays). Tracked in agents-pool — fix lands without binary changes.

    cargo test --workspace 269 passed, 4 ignored (was 254 before all this work). cargo clippy -D warnings clean on touched crates. trial-app npm run build clean. Pushing v0.5.2 tag triggers release.ymlx86_64-unknown-linux-musl + aarch64-unknown-linux-musl builds via cross, Verify static linking gate, compat-smoke (debian:bullseye) gate, then GitHub Release with both tarballs + sha256s.

  • 2026-05-12: Live Trial UX polish — disconnected view no longer overlapped by ChatSidebar. Reported immediately after the explicit-gating commit: the ChatSidebar (absolute right-0 top-0 z-30 h-full) climbed up the DOM looking for the nearest relative ancestor, found <section class="relative ..."> (the Live tab's outer wrapper), and as a result floated over the TokenBar's right edge — including the Connect button — both before AND after connect. Two changes: (1) LiveBoard.tsx wraps its kanban+chat stage in a new relative h-[630px] div, scoping the ChatSidebar's positioning to the stage only — the TokenBar above stays untouched. The disabled prop is removed entirely since the disconnected case is now handled at the page level. (2) page.tsx no longer renders LiveBoard at all when disconnected; instead a compact DisconnectedLive returns max-w-3xl centered TokenBar + a small "What activates once connected" benefits card (3 lines: kanban / chat / showcase). The unknown-token error reuses the same shell, just with an additional amber alert. Net result: the Connect button is never covered, the disconnected page is visually focused on the single CTA, and the connected page gives the kanban+chat its full intended height. New i18n keys (KO+EN): live.intro.compact, live.disconnected.heading, live.disconnected.benefits.{kanban,chat,showcase}. / route shrank from 20.9 kB → 15.3 kB (removed placeholder LiveBoard + dim-state CSS). npm run typecheck + npm run build clean.

  • 2026-05-12: Explicit team-token gating on Live Trial (ADR-017 §6 amendment). Field-feedback after the showcase shipped: anonymous visits silently landed in the DEFAULT_TEAM_TOKEN sandbox, which made the multi-partition story confusing — users couldn't tell which kanban "belonged to them," and a per-team landing URL pasted on a different machine would silently drop back to the shared sandbox the moment any navigation cleared the ?team= query. Removed the auto-fallback rendering. New client component app/components/TeamTokenBar.tsx sits at the top of Live Trial as the single owner of token persistence; token resolution in app/page.tsx is now URL → cookie → empty (no DEFAULT_TEAM_TOKEN default). Empty → LiveBoard renders in disabled mode (pointer-events-none + opacity-40) with live.disabled.overlay banner so the user sees what they'll get once connected. TokenBar validates pasted tokens via GET /api/trial/team-app/status?team=... (extended in this amendment to return team_exists + project_name), persists to a 1-year cookie (genasis-trial-team) + localStorage, and router.replace navigates to /?tab=live&team=<token> so the SSR pass picks up the new tenancy. On the CLI side, genasis init --trial now ends with a copy-friendly ASCII-bar summary printing the project name, team_token, and pre-filled landing URL — the same language as the TokenBar's "Enter your team token" copy so users get consistent guidance whether they paste the URL or the bare token. README/TUTORIAL EN+KO updated with the paste-token walkthrough; ADR-017 §6 documents the design. 18 new i18n keys (KO+EN) for live.tokenbar.* and live.disabled.overlay. trial-app npm run typecheck + npm run build clean; cargo test -p genasis-cli --bin genasis run_trial still 3 passed.

  • 2026-05-12: Field-feedback round 2 — install.sh --lang doc/impl alignment + Linux musl-static release. Two unrelated user-reported issues: (1) install.sh --lang ko (space form) was silently rejected as an unknown flag — only --lang=ko (equal form) was parsed. Every doc string (help text, error banners, README) used the space form. Rewrote the arg loop from for arg in "$@" to while [ $# -gt 0 ] with explicit shift, accepting BOTH --lang ko and --lang=ko (same for --prefix and --version). Help text updated to spell out the dual-form acceptance. (2) Release binaries baked a GLIBC_2.39 floor because release.yml built x86_64-unknown-linux-gnu on ubuntu-latest (now 24.04). Switched both Linux matrix entries to *-unknown-linux-musl via cross for fully-static binaries — cross auto-selects the musl image so no apt install musl-tools boilerplate is needed. Same rustls-tls feature flag already in Cargo.toml means no OpenSSL/libssl dependency to wrestle with. Added a Verify static linking step that runs file on the produced binary and fails the build if it reports "dynamically linked" — guards against accidental reintroduction of a glibc dep. Added a compat-smoke job that runs the packaged x86_64 binary inside debian:bullseye (glibc 2.31) on every tag. Dropped both macos-latest matrix entries since Apple Silicon notarisation flow is unresolved — README §Supported Platforms now marks macOS as TBD with a roadmap note; install.sh prints a clear "build from source" message on Darwin instead of attempting a download that doesn't exist. Bilingual README platform table expanded from 4 rows × 2 cols to 5 rows × 3 cols (Pre-built / Build-from-source / Notes). No new cargo test cases — these are infra changes; the actual coverage is the release pipeline itself.

  • 2026-05-11: Trial-app showcase model (ADR-017). Closed a credibility gap left open by ADR-013/016 — the scripted Try it tab animated the same kanban + chat widgets that the live mode uses, so a first-time visitor couldn't tell which one was "real," and the reference PRD ("Example Feature — Task Status") asked agents to build something visually indistinguishable from the trial-app itself. Four coordinated changes: (1) delete the scripted demo — removed DemoBoard.tsx, ChatThread.tsx, KanbanBoard.tsx, lib/{use-demo-sprint,demo-script}.ts, e2e/demo.spec.ts, all demo.* i18n keys, the tab=demo URL handler, and the TrialTab="demo" variant; landing tab is now live. (2) i18n-aware example PRD — cmd_example.rs reads [i18n].active from genasis.toml and emits either prd.en.md or prd.ko.md, both describing the new reference app: "I Am a Claude Code Expert" / "나는 Claude Code 전문가" — a mobile-phone-bordered 5-question self-assessment quiz with 3 difficulty levels and a question bank ≥ 15. (3) embedded showcase — new app/components/QuizApp.tsx + lib/quiz-bank.ts ship the reference quiz inside trial-app, gated per-team by a new sim_teams.app_status column (V2 → V3 migration, ADR-016 §3 pattern reused). New ShowcasePanel.tsx slides in from the left of LiveBoard when toggled, closes on Esc/click-outside/✕. (4) explicit completion signal — new genasis trial publish CLI POSTs {team_token, status: "complete", project} to /api/trial/team-app/status (the route also unauth'd, ADR-016 §4 token-as-capability extends here). Apply tab → "Borrow real env" / "실환경 빌리기" because the user is literally borrowing a real Plane + MM project on the operator's mmplane-trial.realstory.blog infrastructure. README links updated trial.realstory.bloghttps://mmplane-trial.realstory.blog/?tab=signup; same sweep across QUICKSTART (EN+KO), blueprint.ko §22.2, agents-pool/prd/trial-webapp.md, playwright.config.ts, e2e/signup.spec.ts. New tests: cmd_example × 4 (en/ko/explicit-flag/missing-config), cmd_trial × 3 (dry-run/missing-token/missing-config). cargo test --workspace 266 passed, 4 ignored (259 → +7). trial-app npm run typecheck + npm run build clean; /api/trial/team-app/status shows in route table.

  • 2026-05-11: ADR-016 follow-up — token propagation + SSE isolation + fallback UX (Phase A + B). The initial ADR-016 commit (3760b07) plumbed team_token only as far as the config file: Rust trial providers still sent no X-Genasis-Team-Token, the new /api/trial/bootstrap returned 503 whenever TRIAL_SHARED_SECRET wasn't set on the operator-hosted instance (the default), and the SSE event bus was global so cross-tenant updates leaked into every connected tab. Phase A: TrialPlane / TrialMattermost constructors gain a third team_token: String arg; the headers() method attaches X-Genasis-Team-Token when non-empty; both factories thread t.team_token.clone().unwrap_or_default() through from TrialConfig. Phase B: /api/trial/bootstrap drops requireTrialContext — the 32-char hex team_token body field is now the sole credential (idempotent + unpredictable, see ADR-016 §4); lib/events.ts subscribe() accepts an optional teamToken filter and emit() matches against event.payload.team_token; /api/events/stream reads ?team= from the request URL and only forwards matching events; LiveKanbanBoard / LiveChatThread append ?team=<token> to their EventSource URL (browsers can't attach custom headers to EventSource). page.tsx gained a fallback branch for unknown tokens — when ?team=<token> is present but getTeam(token) returns null, the user gets an amber error panel ("Team token not recognised — check [trial].team_token in your genasis.toml") instead of silently landing in the default sandbox. New data-team-token attribute + colour-coded badge on LiveBoard so the user always sees which tenancy they're in. New tests: 5 headers tests across plane/trial.rs + mattermost/trial.rs. ADR-016 EN+KO extended with §"Auth model — token IS the capability". cargo test --workspace 259 passed, 4 ignored (254 → +5). trial-app npm run typecheck + npm run build clean.

  • 2026-05-11: Trial-app identifier alignment + multi-tenancy (ADR-016). ADR-013 wired the routing between genasis and the trial-app but said nothing about the identifiers flowing through that route — so genasis init --trial was hard-coding every Plane/Mattermost field to the literal "trial" regardless of the team the user actually wanted, and the trial-app sim had no per-team isolation so concurrent demos on the hosted instance overwrote each other. Three coordinated changes shipped together: (1) real-mode schema gains [plane].project_name + [[mattermost].channels] (MattermostChannel { key, name, display_name }), with Config::derive_naming_defaults() synthesising a single scrum channel for legacy configs; (2) [trial].team_token (32-char hex from random_team_token()) becomes the per-team isolation key, written by genasis init --trial and falling back to a "default" sentinel for pre-ADR-016 configs; (3) the trial-app sim migrates from user_version = 1 to 2 — every sim_* table gains team_token plus composite UNIQUE(team_token, slug|name), a new sim_teams table records each bootstrap, and a POST /api/trial/bootstrap route seeds the project + channels under the token. lib/trial-auth.ts resolves the token from X-Genasis-Team-Token header → ?team= query → DEFAULT_TEAM_TOKEN. Browser UI (page.tsx + LiveBoard + LiveKanbanBoard + LiveChatThread) plumbs the token from ?team=<token> SSR through to every fetch() via withTeamHeader. cmd_init.rs real-mode no longer string-formats scrum-{project_name} — it looks up cfg.mattermost_channel("scrum"). cmd_init.rs --trial prompts for --name (or derives from dirname), generates the token, renders the dynamic Tera-style template, POSTs /api/trial/bootstrap, and opens /?tab=live&team=<token> in the browser. New tests: 7 in genasis-core::config (slugify, random_team_token, derive_naming_defaults, effective_team_token, mattermost_channel lookup, channels TOML round-trip), 3 in cmd_init::tests (project name from flag, derived from dirname, idempotent on existing config). ADR-016 written EN/KO. cargo test --workspace 254 passed, 4 ignored.

  • 2026-05-08: Phase F audit + checkbox catch-up. Reconciled progress.md/progress.ko.md against actual repo state (commits e0683de..5bdaadf, build.sh, CONTRIBUTING.md, docs/CREDITS.md). Phase F status table flipped F.1–F.8 from planningdone. Trial-app US-001..US-022 all passes: true in trial-app/ralph/prd.json — corresponding F.5 sub-checkboxes closed, plus F.6 (genasis init --trial), F.7 (cmd_example.rs + 3 example templates) and F.8 (TUTORIAL.md en/ko + README Quick Path/Step-by-Step restructure + CLAUDE.md mirror table). One item kept as [s]: bilingual example documents (active-singularity policy keeps examples English-only until genasis example --lang lands). Still open: M14.0 ratify gate, M14.3–M14.5 (CLI bootstrap wire-up + golden blank fixture + doctor section), and the entire Phase F Debug History loop (M15–M17).

  • 2026-05-19: v0.6.0-alpha.45 — D-132 chat-thread propagation + ADR-020 showcase polling. Field report from a fresh trial run uncovered three coupled defects. (1) PM's "✅ deployed" wrap-up was posted as a brand-new top-level chat row instead of a threaded reply under the human's request, and frontend / devops never posted at all. Root cause: crates/genasis-cli/src/listen/session.rs:204 send_user_message only forwarded the human's text payload — the originating post_id was dropped before reaching PM, so the agent overlays' literal root_id=<human msg id> instructions had nothing to substitute. (2) ShowcasePanel iframe stayed in the "building / 채팅 패널에 만들고 싶은 앱을 알려주세요" placeholder even though devops had successfully run genasis push --dir ./app/dist and the operator-served URL was reachable; the ShowcasePanel only polled sim_teams.dev_server_url (the pre-ADR-020 reverse-proxy column) and the dev-server API endpoint did not expose the new showcase_pushed_at column at all, so the push-flow signal was invisible client-side. (3) The PM overlay (en + ko) still carried the deprecated v0.5.x setsid -f sh -c 'npm run dev -- --host 0.0.0.0 --port 5173 …' + mcp__trial-app__announce_dev_server_url(...) dispatch script even though the devops overlay had been rewritten for ADR-020 in alpha.40 — PM was telling devops to run two contradictory workflows, and in this environment (agents on the user's laptop, trial-app on the remote operator host) the localhost dev-server path is physically unreachable from the operator. Coordinated fix across genasis main + agents-pool submodule: (a) session.rs send_user_message(text, post_id) now wraps human content as <human_post id="…">…</human_post> + an explicit reminder line; daemon system prompt gained a "Thread discipline (D-132)" paragraph telling PM to extract that id and pass it as root_id on every post_message and to forward it into every Task(subagent_type=…) prompt so frontend / devops / qa thread under the same root. listen/mod.rs caller destructures post_id from InboundEvent::PostCreated and threads it through. (b) agents/overlays/{en,ko}/devops.patch.md.tera — every post_message(actor="devops", ...) call gains root_id="<human post_id>", plus a "Thread discipline" preamble. (c) agents/overlays/{en,ko}/pm.patch.md.tera — Step 4's dispatch prompt rewritten from the legacy npm run dev + announce_dev_server_url recipe to the ADR-020 (cd app && npm install && npm run build) + genasis push --dir ./app/dist recipe; Step 5/6 add root_id to every post_message; "Deploy routing" section synchronised with the same flow; explicit warning that localhost:5173 is unreachable from the remote operator and therefore the legacy reverse-proxy path no longer works in trial mode. (d) agents-pool submodule (commit 9d4f13e): /api/trial/team-app/dev-server GET also selects + returns showcase_pushed_at; ShowcasePanel.tsx poll loop flips status to "ready" when EITHER dev_server_url OR showcase_pushed_at is non-null. Submodule pointer bumped in the parent repo. Gate: cargo fmt --all -- --check clean; cargo clippy --workspace --all-targets clean; cargo test --workspace --tests --exclude genasis-e2e 276 passed, 0 failed, 5 ignored; trial-app npm run typecheck clean. D-123 still open (e2e binary RSS leak). workspace.version 0.6.0-alpha.440.6.0-alpha.45.

  • 2026-05-19: v0.6.0-alpha.44 — D-131 CLAUDE USAGE pulls live numbers from /api/oauth/usage. Field follow-up to alpha.43: even after D-130's heuristic fix, the user's CLAUDE USAGE panel still rendered 0% / 0% / 0% / 0% while the official Anthropic settings page (claude.ai/settings/usage) reported 9% / 12% / 2% / Claude Design 0% — and the user attached a screenshot of both. Root cause: the JSONL aggregator I built in D-130 sums local token totals and divides by a static/tier-derived budget, but the server-side rate-limiter applies its own weighting (cache rates, multi-window interaction, plan-specific carve-outs) that we cannot reproduce locally. The percentages will never match unless we read the server's numbers directly. Investigation found that the Claude Code CLI itself (@anthropic-ai/claude-code v2.1.144 binary, x86_64 ELF) calls GET /api/oauth/usage with the user's OAuth bearer from ~/.claude/.credentials.jsonclaudeAiOauth.accessToken and parses a fixed shape (fetchUtilization: GET /api/oauth/usage string found via strings + grep on the binary; full response decoded with a probe curl). Response schema captured against the dev host: {five_hour: {utilization, resets_at}, seven_day, seven_day_oauth_apps, seven_day_opus, seven_day_sonnet, seven_day_cowork, seven_day_omelette (= Claude Design), tangelo, iguana_necktie, omelette_promotional, extra_usage: {is_enabled, monthly_limit (cents), used_credits (cents), utilization, currency, disabled_reason}}. The probe returned seven_day: 12.0 and seven_day_sonnet: 2.0 — exact match for the settings-page screenshot. Implementation: new crates/genasis-monitor/src/collector/oauth_usage.rs module: serde-deserialized OAuthUsage / UsageWindow / ExtraUsage structs covering the captured schema; fetch() async function reads the bearer, hits https://api.anthropic.com/api/oauth/usage via reqwest (already a workspace dep; rustls-tls + json features) with 5 s timeout, the same anthropic-beta: claude-code-20250219 header the CLI sends, and a User-Agent: genasis-monitor/<ver> for server-side attribution. Token expiry guard: expiresAt field (epoch ms) is checked with a 60 s margin and returns Ok(None) silently when the cached token is already (or about to be) stale, so the monitor falls back to the JSONL aggregator instead of spamming auth errors every minute. 401 responses also fall through to Ok(None) (Claude Code rotates its copy of the token on the next interactive run, so noisy logging here is counter-productive). 4xx/5xx with a valid bearer surface as Err and land on log_tail with a HH:MM (oauth usage fetch failed: ...) line. Disable knob: MONITOR_DISABLE_OAUTH_USAGE=1 skips the call entirely. The OAuth bearer is NOT an ANTHROPIC_API_KEY — the user's standing prohibition (feedback_no_claude_api.md) covers Console API keys for inference; this is a user-scoped OAuth bearer for stats already present on the box, identical to what Claude Code itself uses. Snapshot wiring: UsageSnapshot gains 11 new optional / live fields — oauth_five_h_pct, oauth_seven_day_pct, oauth_seven_day_opus_pct, oauth_seven_day_sonnet_pct, oauth_seven_day_design_pct (from seven_day_omelette), oauth_five_h_resets_at, oauth_seven_day_resets_at, oauth_extra_used_credits_cents, oauth_extra_monthly_limit_cents, oauth_extra_pct, oauth_fetched_at. New apply_oauth_usage() method copies the response onto the snapshot. New five_h_oauth_countdown() returns the server's resets_at countdown when present. collect_jsonl() updated to carry these 11 fields across the JSONL refresh — scan_sessions_dir() returns a fresh UsageSnapshot::default() and would otherwise wipe the OAuth numbers we just fetched. App loop: new OAUTH_USAGE_TICK = 60 s (matches Claude Code's own caching cadence) plus a fetch on startup and on the r (refresh) key. Widget: the gauges now read state.usage.oauth_*_pct.unwrap_or_else(|| <JSONL fallback>) so server numbers win when present and JSONL keeps working when they aren't. Third gauge becomes 7d (Opus) when the server reports it OR 7d (Design) (magenta vs cyan) when only seven_day_omelette is non-null — matches the Anthropic page's "Claude Design" row. Cost line rewritten: when extra_usage is present we show Credits $0.00 / $200 · est 5h $X (matches the "사용 크레딧 / Usage Credits" + "월간 지출 한도" rows on the settings page exactly); otherwise fall back to the D-130 estimate. Reset line gains a source: live (OAuth) or source: local (JSONL) tag so the user can tell which source they're looking at. Empty-state hint logic updated: only show "No Claude activity in last 5h" when BOTH the JSONL is empty AND no OAuth fetch has landed — server data can be non-zero on a fresh test bed where the local JSONL hasn't accumulated anything yet. Live verification on dev host (cargo run --example usage_dump): five_hour: 11.0 (settings page says 9%, 1–2 min later), seven_day: 12.0 (exact match), seven_day_sonnet: 2.0 (exact match), seven_day_omelette: 0.0 ("Claude Design", exact match), extra_usage.monthly_limit: 20000 ($200, exact match), extra_usage.used_credits: 0.0 ($0.00, exact match). New tests: parses_live_fixture (locks the serde shape against the captured response), parses_resets_at (ISO 8601 → epoch), empty_response_ok (graceful no-op when server returns {}). Workspace 276 passed (was 273 → +3). Gate: cargo fmt --all -- --check clean; cargo clippy -p genasis-monitor --all-targets clean. workspace.version 0.6.0-alpha.430.6.0-alpha.44.

  • 2026-05-19: v0.6.0-alpha.43 — D-130 CLAUDE USAGE widget end-to-end fix (monitor). User screenshot from a freshly-installed test bed showed 5h session 0%, 7d (all) 0%, 7d (Sonnet) 0%, $0.00 / $200, Reset: reset pending — i.e. every number in the CLAUDE USAGE panel was dead, even though SESSIONS showed five active Claude Code processes with 1d age. Root-cause audit found four distinct defects in crates/genasis-monitor/src/collector/jsonl.rs + widgets/sessions.rs: (1) five_h_cost_usd was declared on UsageSnapshot but never written anywhere in the workspace — cost was permanently $0.00 for everyone. (2) five_h_reset_epoch / week_reset_epoch were only set from the legacy rate_limit_event JSONL records; Claude Code v2.1.x stopped emitting those (transcript-wide grep of 156 local .jsonl files found 0 hits), so the countdown was always negative → format_countdown(<=0) returns "reset pending". (3) read_credentials looked at top-level plan / planName / tier / serviceTier keys, but the real ~/.claude/.credentials.json shape is {"claudeAiOauth": {"subscriptionType": "max", "rateLimitTier": "default_claude_max_20x"}} — every user got plan: "unknown" and tier-aware budgets never kicked in, so MONITOR_5H_TOKEN_LIMIT=7M was used regardless of the user actually being on Max (20x) which has a much higher real limit. (4) week_sonnet_* only accumulated when model.contains("sonnet") — Opus-heavy users (the entire genasis dev box runs claude-opus-4-7) watched a permanently-0 % Sonnet bar despite using millions of Opus tokens daily. Three-phase fix in one PR. Phase A — kill the dead fields: new pricing_for(model) table covers the Claude 4.x lineup (Opus $15/$75, Sonnet $3/$15, Haiku $1/$5 input/output per MTok, plus cache_read = input × 0.1 and cache_create = input × 1.25 per Anthropic's prompt-caching doc); scan_single_file now accumulates five_h_cost_usd + new week_cost_usd on every assistant event. read_credentials reads claudeAiOauth.subscriptionType + .rateLimitTier first, falling back to the legacy top-level keys so older credential files keep working; new plan_display_name() maps tier strings to user-friendly labels ("Max (20x)", "Pro", "Team", …). New tier_to_limits(tier) → Option<(5h, week_all, week_opus, week_sonnet)> lookup, called from app.rs so the default budgets reflect the user's actual plan; env overrides (MONITOR_*_TOKEN_LIMIT) still win when present. Phase B — accuracy: UsageSnapshot.five_h_oldest_event_ts + week_oldest_event_ts track the earliest in-window assistant event; five_h_reset_countdown() now returns oldest_ts + 5h - now (the moment the earliest call slides out of the sliding window) when no rate_limit_event epoch is recorded — actual countdowns instead of permanent "pending". ModelFamily::{Opus, Sonnet, Haiku, Other} classifier splits weekly totals into per-family counters (week_opus_input/output/cache_read/cache_create, week_haiku_*, week_other_*); widget gains a new 7d (Opus) X% magenta gauge above the Sonnet row (Max plan tracks Opus + Sonnet on separate budgets). New five_h_pct_weighted() exposes the cache-folded percentage (input + output + cache_create × 1.25 + cache_read × 0.1) closer to what the server-side limiter sees. New state.limit_week_opus_tokens field. Phase C — UX guard: new UsageSnapshot::is_empty_5h() returns true when zero assistant events landed in the 5h window; widget renders a two-line hint ("No Claude activity in last 5h. / Run claude in any project to populate.") instead of four 0 % gauges that look broken on first-time / clean-env installs. CLAUDE USAGE block title now appends the resolved plan label (CLAUDE USAGE — Max (20x)). Layout reshuffled from 4 × 2-line gauges to 6 × 1-line rows (5h / 7d-all / 7d-Opus / 7d-Sonnet / cost / reset) — still fits the existing 8-row session-panel slot. Cost line rewritten as 5h $X.XX · 7d $Y.YY · cap $Z so today's burn and the week's burn are visible side by side. Reset line shows "—" instead of "reset pending" when the countdown is non-positive. Live verification on the dev host: cargo run --example usage_dump reports creds plan: Max (20x), tier_to_limits: 5h=4400000 week_all=100000000 week_opus=40000000 week_sonnet=100000000, five_h_cost_usd: $91.06, week_opus_input: 204817 — all values that were 0 / "unknown" pre-D-130. New tests added: scan_populates_cost, opus_cost_higher_than_sonnet, reset_countdown_from_oldest_event, tier_lookup, plan_label_max_20x, weighted_pct_includes_cache, plus an is_empty_5h() assertion in scan_empty_dir_returns_defaults. Sister to examples/detect_dump.rs, new examples/usage_dump.rs lets future cycles spot-check the JSONL aggregation without driving the ratatui UI. Gate: cargo fmt --all -- --check clean; cargo clippy --workspace --all-targets -- -D warnings clean; cargo test --workspace --tests --exclude genasis-e2e 17/17 monitor passed (no regression in adjacent crates). workspace.version 0.6.0-alpha.420.6.0-alpha.43.

  • 2026-05-17: v0.6.0-alpha.42 — D-124 install.sh stops touching cwd + D-123 partial hardening (monitor TTY gate). Two field-reported follow-ups uncovered while validating alpha.41. (1) D-124 — CLOSED. install.sh had RUN_AFTER_INSTALL=1 as default and ran genasis attach against the user's cwd at install time. A user running curl ... | sh from /work/agenteams (just to verify genasis --version) found .claude/ + .genasis/ had been scribbled into that parent directory, which then leaked overlays into every nested sandbox via Claude's .claude/ cascade — same family of cross-contamination as D-122. Fix: install.sh RUN_AFTER_INSTALL flipped to 0; new --with-attach flag opts back in for legacy / CI flows; the old --no-run becomes a documented no-op (kept so existing invocations don't error). Header comment + help text rewritten; Next-steps banner now points at cd <project> && genasis init --trial (the README Quick Path) instead of the bare genasis attach reference. (2) D-123 — STILL OPEN. cargo test --workspace --all-targets had been OOM-killed on the dev host at 25 GB anon-rss the previous day; journalctl -k named the killed process agents-9360df0d (cargo's fingerprint for target/debug/deps/agents-<hash> = the tests/e2e/tests/agents.rs integration binary), not the production CLI genasis agents browse that an earlier Claude-Code investigation had blamed. Static analysis pointed at monitor_smoke_without_tty_exits_cleanly running genasis monitor under piped stdin/stdout; that hypothesis was empirically wrong — after adding the TTY gate, a fresh tests/e2e/tests/agents.rs binary still leaked 5 GB RSS at runtime, proving monitor was not the (sole) culprit. The monitor TTY gate is shipped anyway as defensive hardening (app::run() now bails with io::ErrorKind::Unsupported when std::io::stdout().is_terminal() is false, preventing the ratatui loop from running headless even when monitor is not the leak source) but D-123's true root cause is still being chased. Next-cycle diagnosis: bisect the 9 tests inside tests/e2e/tests/agents.rs individually under /usr/bin/time -v to find the actual offender (likely agents_browse_without_index_errors_cleanly since cmd_browse enters dialoguer FuzzySelect on piped stdin, but this needs measurement, not another static-analysis guess). Gate: cargo fmt --all -- --check clean; cargo clippy --workspace --all-targets clean; cargo test --workspace --tests --exclude genasis-e2e 267 passed; cargo test -p genasis-e2e deliberately not gated in this ship because D-123 is unresolved — alpha.42 was opportunistic field-fix ship for D-124 (immediate user-visible UX bug) plus monitor hardening, not a D-123 closure claim. workspace.version 0.6.0-alpha.410.6.0-alpha.42.

  • 2026-05-17: v0.6.0-alpha.41 — enforce app/ subdir as the standard scaffold layout (D-122). User report: mkdir my-team && cd my-team && genasis init --trial --name "My Team" followed by a chat request produced a nested my-team/my-team/ where the React app actually lived. Root cause was three layers of ambiguity. (1) agents/overlays/{en,ko}/frontend.patch.md.tera told frontend to npm create vite@latest . (scaffold straight into cwd). (2) crates/genasis-cli/templates/examples/prd.{en,ko}.md §5 used an ambiguous <sandbox-root>/ layout tree and still referenced the deprecated v0.5.x announce_dev_server_url flow. (3) crates/genasis-cli/src/listen/session.rs daemon system prompt told PM to chain frontend → devops → genasis push but never specified WHERE to scaffold. So Claude — given a system prompt mentioning slug: my-team — used the slug as a folder name and nested the scaffold. Meanwhile cmd_push.rs auto-detect already preferred app/dist → app/build → app/out over their root counterparts, meaning the design intent was always scaffold under app/ — the overlays/PRD/system prompt just never said so. Four parallel fixes shipped: (1) frontend overlay (en+ko) — npm create vite@latest app -- --template react-ts --yes + (cd app && npm install), all Edit/Write paths rewritten to app/src/..., explicit "never npm create vite@latest ." warning. (2) devops overlay (en+ko) — (cd app && npm run build), [ -f app/dist/index.html ], genasis push --dir ./app/dist, plus a layout-contract preamble. (3) PRD templates (en+ko) §5 — replaced the <sandbox-root>/ tree with an explicit my-team/.claude/+genasis.toml+PRD.md+app/ standard Claude layout, retired the announce_dev_server_url workflow and rewrote it as the ADR-020 push-to-operator flow. (4) Daemon system prompt — chained frontend → devops instructions now spell out app/ subdirectory + an explicit prohibition on scaffolding in cwd. Net result: the user's project root remains a clean Claude project (.claude/agents/ + .genasis/ + genasis.toml + PRD.md + app/), genasis push auto-detects app/dist so no extra --dir is needed. cargo fmt --all clean, cargo clippy --workspace -- -D warnings clean, cargo test --workspace no regression. workspace.version 0.6.0-alpha.400.6.0-alpha.41.

  • TODO: GitHub <OWNER> decision needed (install.sh placeholder)

  • TODO: Monitor manifest hash comparison — Next.js-only vs Vite/Turbo/plain compatibility check

  • TODO: Atlas DuckDB support status recheck (raw runner necessity confirmation)


Future items (post first-release)

  • genasis-mcp-proxy
  • Multi-project monorepo support
  • Web UI dashboard
  • Community mcp-cache integration
  • VSCode extension
  • Plane Pro / GitLab / Linear and other issue-tracker flavors

Retrospective slots

Milestone Start End Learnings
M0 2026-05-03 2026-05-03 install.sh OS matrix was 70% of core effort; Tera include_dir!() embed simplifies single-binary distribution; Rust toolchain not installed locally → all crate import consistency reviewed manually.
M1 2026-05-03 2026-05-03 Single-fence invariant + body hash is the core of overlay safety; .env.agents comment preservation requires Vec<Line> model; SQL guard uses string-literal-aware split avoiding sqlparser-rs dependency.
M2 2026-05-03 2026-05-03 MergePlan plan/apply separation makes dry-run natural; FenceState 5-state clarifies --force semantics; include_dir!() Tera embed auto-discovers templates; only ecc-only fixture meaningful at M2.
M3 2026-05-03 2026-05-03 agent-aware is thin delegation over upstream; flavor detection is one header line.
M4 2026-05-03 2026-05-03 stdio JSON envelope is the single Rust↔Node contract. UI automation stays at stub stage.
M5 2026-05-03 2026-05-03 Atlas default + Drizzle Kit auto-detect + DuckDB raw_runner fallback; URL redaction prevents secret leaks.
M6 2026-05-03 2026-05-03 9 role overlays are thin frontend variants; 16 slash commands are thin pointers to GENASIS.md.
M7 2026-05-03 2026-05-03 Extractor delegation + 6-area keyword categorisation simplifies issue plan.
M8 2026-05-03 2026-05-03 doctor mirrors install.sh check matrix — protects even when user bypasses.
M9 2026-05-03 2026-05-03 ratatui 0.27 Frame::area() API simplifies 4-row grid; 250ms poll is right trade-off.
M10 2026-05-03 2026-05-03 No mcp-proxy in v1 is the right maintenance-vs-impact trade-off.
M11 2026-05-03 2026-05-03 All first-release code/docs in place. Next: one real sprint for data-ingest hook validation + v0.1.0 tag.
M14 2026-05-05 2026-05-08 Bootstrap as a subcommand (not an attach side-effect) was the right call — the empty-dir hint in cmd_attach is enough to discover the entry point, and ADR-001's non-destructive promise stays intact. BLESS=1 golden-snapshot pattern (M14.4) generalises to M18 cleanly. Doctor [bootstrap] section piggy-backs on existing Role::ALL slug list — no new validation infra needed. Frontmatter name: ↔ filename stem invariant emerged organically from the test fixtures.

Phase E — Dynamic Agents Catalog (ADR-011, 2026-05-05)

Architectural shift: remove include_dir!() compile-time template embed, replace with runtime fetch from GitHub Releases (agents-v1.x.tar.gz). Community best-of-breed agents curated via private agents-pool submodule.

Sub-milestone Scope Status
E.0 ADR-011 written (KO + EN) done
E.1 agents/ catalog directory (9 base + 20 overlays + 16 commands + 6 hooks + manifest) done
E.2 genasis-templates crate → fetch+cache+load (include_dir removed) done
E.3 genasis-overlay merger/bootstrap wired to AgentStore done
E.4 CLI genasis agents {fetch,status,update,list} subcommand done
E.5 .github/workflows/release-agents.yml (tag → tarball + sha256) done
E.6 agents-pool/ skeleton (config.toml + crawl/verify/publish scripts) done
E.7 agents-pool crawl → verify → publish pipeline live test done
E.7.1 Separation enforced: agents/base/ removed from public repo, .gitignore blocks it done
E.7.2 publish.sh → tarball build + gh release upload (not copy to genasis) done
E.7.3 release-agents.yml → verify-only (tarball built by agents-pool, not CI) done
E.7.4 agents-pool/CLAUDE.md — curation strategy + privacy rules done
E.8 Agent marketplace model: individual install + index.json + /install-agent command done
E.8.1 agents/index.json — 23 agents, 6 categories, 3 presets (metadata only) done
E.8.2 CLI genasis agents install <name> — individual fetch from release assets done
E.8.3 CLI genasis agents browse — interactive TUI placeholder done
E.8.4 CLI genasis agents list --category/--search — filtered browsing done
E.8.5 CLI genasis agents installed / remove — project management done
E.8.6 /install-agent Claude Code slash command template done
E.8.7 publish.sh uploads individual .md as release assets done
E.9 agents-pool pushed to private repo + genasis submodule registration pending
E.10 Wire cmd_attach/cmd_upgrade to load AgentStore before plan pending
E.11 install.sh update pending
E.12 Remove old crates/genasis-templates/templates/ pending
E.13 Interactive TUI (dialoguer) for genasis agents browse pending
E.14 First agents-v1.0.0 release (validates full pipeline) pending

Default 9-role team (famous-agents.md 기반 best-of-breed)

Role Source Category
pm genasis + dl-ezo reference core
architect ECC core
frontend-developer wshobson core
backend-developer wshobson core
code-reviewer ECC (gold standard) core
qa-tester VoltAgent core
security-reviewer ECC core
planner dl-ezo core
designer genasis core

Phase F — Server Setup + Trial + Docs Refactor (2026-05-06)

Making genasis immediately usable: one-command server install, hosted trial environment, streamlined README, and design swap guide.

Sub-milestone Scope Status
F.1 servers/ — unified docker-compose.yml (Plane + Mattermost + Caddy) + install guide with key extraction done
F.2 Trial signup web app PRD (agents-pool) — apply → MM #genasis-trial → admin responds → user gets keys done
F.3 README refactor — simplify to quickstart + trial link, move details to external guides done
F.4 docs/DESIGN-SWAP-GUIDE.md — how to replace design-system.md via genasis design swap done
F.5 Trial demo app (chat + kanban + signup + status pages, US-001..US-022) done
F.6 genasis init --trial CLI integration done
F.7 `genasis example {prd design
F.8 Tutorial documentation (docs/TUTORIAL.md + docs/ko/TUTORIAL.md) done

F.1 — Server installation guide (servers/)

Unified Docker deployment of Plane + Mattermost + Caddy reverse proxy. Source: existing /work/plane and /work/mattermost Docker configs on this host.

Deliverables:

  • servers/docker-compose.yml — single file to bring up all services
  • servers/Caddyfile — TLS + reverse proxy (plane.domain / mm.domain)
  • servers/README.md — step-by-step guide including:
    • Prerequisites (Docker, domain, DNS)
    • Environment variables to set
    • How to extract Plane API key + workspace slug
    • How to create Mattermost bot tokens (per agent role)
    • How to obtain Plane user UUIDs for agent assignment
    • How to configure genasis.toml with the extracted keys

F.2 — Trial signup web app (PRD in agents-pool)

Hosted demo at mm.realstory.blog / plane.realstory.blog allowing potential users to try genasis without self-hosting.

Flow:

  1. User visits trial signup page
  2. Fills in: name, email, project name, desired team size
  3. Submission posts to Mattermost #genasis-trial channel
  4. Admin (maintainer) responds with provisioned credentials
  5. User sees keys/login info on the signup page (or via email)

PRD lives in agents-pool/prd/trial-webapp.md (private). Only the plan reference lives in public progress.md.

F.3 — README refactor

Principles:

  • Above the fold: tagline + one-line value prop + quickstart (3 commands)
  • Trial CTA: "Try it now with our hosted Plane + Mattermost" → link
  • Move complex docs to external files with links
  • Keep SEO-critical content (comparison table, architecture diagram)

External guide files (linked from README):

  • docs/QUICKSTART.md — full install + first attach walkthrough
  • docs/SERVER-SETUP.mdservers/README.md
  • docs/DESIGN-SWAP-GUIDE.md — design system replacement
  • docs/AGENTS-MARKETPLACE.md — browsing + installing agents

F.4 — Design swap guide

docs/DESIGN-SWAP-GUIDE.md covering:

  • What is design-system.md and why it matters
  • genasis design swap <slug> — browsing the gallery
  • genasis design swap --from <path> — local file
  • genasis design restore — reverting to pristine
  • User overrides (genasis design override add)
  • EPIC mode (auto-issues for impacted UI areas)

F.5 — Trial demo app (chat + kanban simulation) — ✅ commits e0683de..de860ad (US-001..US-022) + follow-up UI polish (cc95fa9, 9ca1b43, cffb314, a14fc11, 5bdaadf)

Interactive web app at trial-app/ (Next.js 15 App Router) covering the full hosted-trial flow:

  • Demo kanban board (Todo/InProgress/Done columns, animated card moves) — app/components/KanbanBoard.tsx + DemoBoard.tsx
  • Demo chat thread (scripted agent messages with typing indicator) — app/components/ChatThread.tsx
  • Pre-scripted 8-step sprint simulation (PM → frontend → reviewer → QA) — lib/demo-script.ts + lib/use-demo-sprint.ts
  • [Run Demo Sprint] / [Reset] buttons — wired in DemoBoard
  • Signup form (name, email, phone, project, team size) → MM #genasis-trialSignupForm.tsx + /api/submit
  • Status page with token-based credential display — app/status/[token]/page.tsx + CredentialsView.tsx
  • Deploy to trial.realstory.blog — Dockerfile + docker-compose.yml (deployment config landed; live deploy is a runtime/ops step)
  • Live human co-work mode (US-015..US-022): Trial flavor + TrialPlaneProvider / TrialMattermostProvider HTTP forwarders, simulated Plane/MM state schema, /api/plane/* + /api/mattermost/* bridge endpoints, SSE broadcaster (/api/events/stream), LiveBoard + LiveChatThread + drag-drop kanban + chat composer + chat sidebar
  • KO/EN i18n toggle (LangSwitcher, lib/i18n.ts, Pretendard font, accessibility hardening — commits 572485b, a14fc11)

PRD: agents-pool/prd/trial-webapp.md (v2). All 22 user stories passes: true in trial-app/ralph/prd.json.

F.6 — genasis init --trial CLI integration — ✅ commit de860ad

  • --trial flag for cmd_init.rs (US-013) — pub trial: bool clap arg
  • Flow: create blank project → bootstrap agents → ask "Launch trial app?" → open browser — run_trial() in cmd_init.rs writes minimal genasis.toml with [trial] enabled and offers to spawn the trial-app
  • Trial app runs as background process on localhost:3000 — spawn command configurable; default npm --prefix /work/genasis/trial-app run start
  • i18n keys for trial prompt (en/ko)

F.7 — genasis example subcommand — ✅ commit de860ad

  • genasis example prd — generate sample PRD.md (todo-app with auth, CRUD, responsive UI)
  • genasis example design — generate sample design-system.md (color/typography/spacing tokens)
  • genasis example prd2 — generate PRD2.md (login, admin backoffice, user management)
  • cmd_example.rs — new CLI subcommand (US-014)
  • Templates in crates/genasis-cli/templates/examples/{prd.md,design-system.md,prd2.md} (PRD said agents/examples/ — relocated to crate-local because templates are static include_str!()-embedded with the binary, not part of the dynamic agents catalog)
  • [s] i18n: en/ko versions of each example document — examples ship as English-only per the active-singularity policy (ADR-008). Korean mirror is a future enhancement and would require a --lang arg on cmd_example to pick the right tree.

F.8 — Tutorial documentation — ✅ commit d023cd9

  • docs/TUTORIAL.md (English) — 5-step quick path + 5 exercises
  • docs/ko/TUTORIAL.md (Korean mirror)
  • README restructured: "Quick Path" (5 steps → tutorial link) + "Step-by-Step Guide" (full control) — verified: ## Quick Path — Try Genasis in 5 Minutes + ## Step-by-Step Guide headings present in README.md; equivalents in README.ko.md
  • Mirror pair added to CLAUDE.md table (docs/TUTORIAL.mddocs/ko/TUTORIAL.md)

Releases

First release (v0.1.0) cut after F.1 (server guide) enables end-to-end self-hosted setup. agents-v1.0.0 already published. Translation completion gate in release.yml passes.