Files
firat.sertgoz ab38a0b234 feat(bridge): workspace-backed project registration + adapter improvements (#2533)
* feat(projects): workspace-backed project registration; migrate commitments into projects/commitments/

[cherry-pick-target: feat/projects-workspace-backed]

Replace the parallel `.system/engine/projects/*.json` schema with
workspace-backed project registration. Writing any file under
`projects/<slug>/` is now the declaration that the project exists —
the engine auto-registers it on `memory_write`, and `mission_create`
can reference it by slug. The model reasons about projects through
normal workspace APIs instead of a hidden sidecar schema.

Engine + bridge

- `ProjectId::from_slug(user_id, slug)` derives a stable v5 UUID;
  `Project::new` routes through it so constructing the same project
  twice returns the same ID (no duplicates).
- `slugify_simple` in `ironclaw_engine::types` — pure slug, no UUID
  suffix, reverses cleanly from a `projects/<slug>/` directory name.
- Project metadata moves from `.system/engine/projects/{slug}--{id8}/
  project.json` to user-facing `projects/<slug>/.project.json`.
  One-shot startup migration copies legacy files over, idempotent.
- `HybridStore::load_projects_from_workspace` scans `projects/*/` and
  synthesizes a stub `Project` for bare directories, so a write under
  `projects/foo/` surfaces immediately on restart.
- `EffectBridgeAdapter::ensure_project_for_memory_write` hook runs
  after a successful `memory_write`: if the target is under
  `projects/<slug>/...`, finds-or-creates the project and splices
  `project_id` into the tool output (enables
  `{{call-N.project_id}}` template refs).
- Extract `resolve_project_ref` helper from the inline block in
  `handle_mission_call` — now used by both `mission_create`'s
  `project_id` param and future project-aware tools.

Skills (13 files)

- Mechanical `commitments/` → `projects/commitments/` across the nine
  commitment-domain skills (commitment-setup, -triage, -digest,
  decision-capture, delegation-tracker, idea-parking,
  tech-debt-tracker, product-prioritization, security-review).
- Four persona setup skills (ceo-setup, developer-setup,
  trader-setup, content-creator-setup) gain an explicit "declare the
  project" step (write `projects/commitments/AGENTS.md` with
  persona-specific operating principles) and pass
  `project_id: "commitments"` on every `mission_create`. Setup
  markers move to `projects/commitments/.<persona>-setup-complete`.
- `ceo-setup` gets a v0.4.0 rewrite that also installs two dashboard
  widgets under `projects/commitments/.system/widgets/`:
  `commitments-this-week` (overdue / due / completed counts) and
  `delegations-waiting` (delegation list with stale-at-2-days flag).
  Both poll `projects/commitments/widgets/state.json`, refreshed by
  the triage mission each run.

Tests

- Three new unit tests in `bridge::effect_adapter::tests`:
  `extract_project_slug_recognizes_project_paths`,
  `extract_project_slug_rejects_degenerate_targets`,
  `project_new_is_deterministic_from_user_and_slug`.
- Update `tests/e2e_live_personas.rs` path assertions
  (`workspace_paths`, `read_under`, `verify_setup_landed`,
  `DEV_SETUP_CHECKS` needles, two workflow turn messages) to the new
  `projects/commitments/` prefix.
- Add a diagnostic dump in `run_turn` when a persona workflow turn
  times out with no response, so live-test hangs surface the
  captured status events instead of an opaque panic.

No backcompat for the old flat `commitments/` layout — pre-production
deployment, nothing in the wild depends on it.

* fix: adapt cherry-picked project registration to staging API surface

Add missing struct fields (engine_store, skill_registry) and setter
methods to EffectBridgeAdapter, expose MissionManager::store() accessor,
add sync_v1_skill_to_store to skill_migration, and remove references
to fields/methods not yet on staging (Project::goals/metrics,
LiveTestHarnessBuilder::with_skills_dir, V2SkillMetadata::bundle_path).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(bridge): address review — drop slug-prefix fallback, harden tests (#2533)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(bridge): address PR #2533 review — slug-consistency, migration hardening, caller-level tests

- synth_bare_project now normalizes the raw dir name via slugify_simple
  before ProjectId::from_slug, matching Project::new. Returns Option so
  unsluggable dirs (`---`, `!!!`) don't produce phantom projects.
- migrate_legacy_project_jsons upgraded to warn! and moves unparseable
  legacy project.json aside as project.broken.json so the user can
  recover instead of the engine masking the loss on every boot.
- Document project_slug's engine-internal (mission-path, UUID-suffixed)
  scope vs project_dir's user-facing (no-UUID) scope so the two slug
  schemes aren't conflated in future edits.
- Drop unused ProjectId param from project_dir / project_path.
- Trim Project::new docstring per CLAUDE.md style.

Tests added (19):
- types::project: slug variant collapse, unicode, empty-slug stability,
  run/edge normalization
- store_adapter unit: project_slug_for_name contract, project_dir/path,
  synth_bare_project↔Project::new ID equivalence across 12 weird names,
  unsluggable-dir rejection, cross-user isolation
- store_adapter migration_tests (libsql): bare-dir load, metadata over
  synth, non-canonical skip, weird-slug collapse, user-edit preservation,
  broken-JSON move-aside
- effect_adapter caller-level: drives execute_action("memory_write")
  for canonical / idempotent / non-projects / nested / weird-slug /
  cross-user / pathological targets per .claude/rules/testing.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Illia Polosukhin <ilblackdragon@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 23:23:15 +09:00
..