Commit Graph
21 Commits
Author SHA1 Message Date
fez5587andClaude Fable 5 027e7458f4 Manager status updates + workspace demo links
- While work is in flight, the manager posts a 2-4 sentence shareholder
  status update (what's moving, risks, next step) digested from real
  events via one pool call — at most one per 2h per company, skipped
  when a milestone update already covered the window. Shows in the CEO
  updates feed as status.update.
- Workspace demos: engine proxies top-level company workspace files from
  Hermes (GET /companies/{slug}/files[/{name}]); dashboard lists them
  with links so deliverables like index.html render live in the browser.
- Engine logs at info level so dispatcher activity is visible.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 14:43:06 -05:00
fez5587andClaude Fable 5 7ab6db469d Consultant escalation policy + milestone delivery checks
Manager policy, active only when a company employs a consultant:
- a task that blows its wall-clock budget or blocks on machine failure
  (crashed worker, capability gap — anything except needs_input) is
  reassigned to the consultant with the failure context appended
- every objective rollup spawns a consultant review task: verify each
  deliverable against acceptance criteria, write milestone-check.md,
  verdict per deliverable, fix nothing

Also: employee_role_check widened to include consultant (db + live);
consultant sprite shirt color in the office.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 14:34:12 -05:00
fez5587andClaude Fable 5 4796274ea5 Consultant path + per-company pause
- create_profile accepts a provider; non-custom providers (anthropic,
  openai-codex) skip the pool base_url and use Hermes GUI credentials —
  externally billed consultants
- consultant role charter; EmployeeSpec carries model+provider;
  POST /companies/{slug}/employees hires into an existing company
- decomposition may assign role consultant, with explicit cost guidance
- POST /companies/{slug}/pause|/resume flips lifecycle_state; dispatcher,
  standups and directives already filter on active, in-flight work
  finishes; dashboard gets a per-company pause button

Verified: ChatGPT OAuth consultant (gpt-5.4-mini) completed a kanban task
end-to-end via Hermes credential pool; pause/resume roundtrip with 409
guard on double-pause.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 14:28:29 -05:00
fez5587andClaude Fable 5 cea98aeea7 Manager standup: idle team -> manager plans next work
When an active company has no ready/in-progress/blocked work but does have
delivered history, the dispatcher creates a manager research task: skim the
workspace, write standup-report.md with a milestone check per employee and
2-4 proposed next tasks with acceptance criteria. Propose-only — execution
still requires a shareholder directive. 4h cooldown per company.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 14:16:58 -05:00
fez5587andClaude Fable 5 30876b3423 Extraction retry: 3 attempts with backoff
Empty-content responses from the pool got through the single retry once
two companies ran concurrently; 3 attempts with 3s/6s backoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 13:53:56 -05:00
fez5587andClaude Fable 5 b141900ad7 Office: company switcher tabs + active objective line
Tabs render only when more than one active company exists; objective line
shows the newest in-progress objective above the canvas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 13:33:48 -05:00
fez5587andClaude Fable 5 f41eac033f Research room + task kinds
- Decomposition now classifies each task kind (build/research/review);
  research/review map to matching work_item types, dispatcher dispatches
  them alongside task/subtask/defect
- Office: walled research room (bookshelves, reading table, own floor)
  bottom-right; generalized room routing (per-room door waypoints);
  workers on research-type tasks walk there and read (page-flip anim)
  instead of sitting at a desk; break area moved to mid-floor

Verified live: research directive decomposed into 4 research + 1 build
task; worker rendered at the reading table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 13:20:08 -05:00
fez5587andClaude Fable 5 a858337edc Dispatcher self-healing + QA report classification fix
- Poll now includes blocked work items: when Hermes retries a transiently
  blocked task and it is active again, the item auto-resumes (task.resumed
  event) instead of staying blocked forever. Blocked items whose kanban
  task is done/review are left alone — re-finishing them every tick would
  spam events and duplicate cost entries.
- Extraction prompt: a QA/review task that finished its checks is
  task.completed even when it found defects — findings are the
  deliverable. Previously "accessibility fails" wording classified the
  task as blocked.

Verified live: misclassified QA task re-extracted to done; transiently
blocked task auto-resumed; wall-clock cap fired on a 30-min runaway.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 12:58:40 -05:00
fez5587andClaude Fable 5 a0bae6dc51 Office pathing fixes: room test uses x+y, door waypoints, live typing anim
- inConf() was x-only, so the break area routed through the conference door
- door crossings now go west-waypoint -> doorway -> target (no wall clipping)
- workers face the viewer at their desk; typing anim/monitor glow computed
  from live state in the draw loop instead of waiting for the next poll

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 12:28:10 -05:00
fez5587andClaude Fable 5 b3138fb5b0 Office v1: top-down pixel office + sibling-context handoff in dispatch
- /office rebuilt Chrono Trigger style: tile map (work floor, walled
  conference room with door, break area), 4-direction sprites with walk
  cycles; employees path through the door and walk to their desk when
  working (typing anim, lit monitor), to the conference room with a "?"
  bubble when blocked on an answer, to the water cooler when idle. All
  movement derives from polled engine state only.
- Dispatcher now appends completed-sibling task reports to each task body
  so decomposed tasks are no longer blind to each other's output (fixes
  the "apply the patch task A made" capability block).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 12:24:40 -05:00
fez5587andClaude Fable 5 c2320c3dc8 Clarification answer path + pixel office v0
- POST /companies/{slug}/work-items/{id}/answer: shareholder answers a
  blocked item; answer is appended to the description and the existing
  kanban task is rerun (status=ready + updated body), or the item goes
  back to ready for fresh dispatch if it was never dispatched
- Dashboard: answer button on blocked work item rows (native prompt)
- /office: pixel-art 2D office view — one desk row per employee, avatar
  color by role, LED/typing animation driven only by real engine status,
  live event ticker (PRD 12: no fake activity)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 12:01:37 -05:00
fez5587andClaude Fable 5 fd3feb6a08 Shareholder line: directives endpoint + CEO milestone updates
- POST /companies/{slug}/directives: free-form shareholder message becomes
  an objective (reuses manager decomposition), logs directive.received
- Objective rollup now emits a CEO-voiced milestone.update event via one
  pool call (plain-text fallback if the LLM call fails)
- _chat_structured retries once on empty/invalid JSON from the pool
  (observed empty-content responses breaking protocol extraction)
- Dashboard: per-company shareholder textarea + CEO updates feed; refresh
  skips DOM rewrite while a textarea is focused

Verified end-to-end: directive -> 3 tasks -> rework after handoff block ->
rollup -> CEO milestone update; gaswatch index.html now on-brand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 11:58:38 -05:00
fez5587andClaude Fable 5 312a99393b Objective rollup: objective goes done when all child tasks are done/cancelled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 10:19:27 -05:00
fez5587andClaude Fable 5 9a1b03b15e Fix workspace dispatch: kanban workspace_kind is 'dir', block on dispatch 4xx
- Hermes rejects workspace_kind 'path' (valid: dir/scratch/worktree).
- Dispatch failure now blocks the work item with a dispatch.failed event
  instead of retrying the same 400 every tick.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 10:15:05 -05:00
fez5587andClaude Fable 5 4fd6f3fd1d Slice 1: engine dashboard + persistent company workspaces
- engine/static/index.html served at /: companies, employees, objectives,
  work items, live event feed (5s poll), global pause/resume button.
- Persistent per-company workspace on the Hermes host
  (/opt/data/farmhouse/<slug>, created via files API at company creation);
  dispatcher passes it as kanban workspace_path so artifacts persist across
  tasks instead of dying in scratch dirs.
- hermes_client.mkdir; gaswatch backfilled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 10:08:58 -05:00
fez5587andClaude Fable 5 9b6e7a23f6 Slice 1: dispatcher loop + objective decomposition — first live objective completed
- engine/dispatcher.py: 10s tick, bounded in-flight (3), ready->kanban dispatch
  with budget mapping (goal_max_turns/max_runtime_seconds), poll->AgentMessage
  extraction->events, wall-clock cap with run termination, blocked triage state.
- engine/protocol.py: schema-enforced pool calls — raw report -> AgentMessage,
  objective brief -> task decomposition (3.6s live).
- engine/main.py: POST /companies/{slug}/objectives (manager decompose ->
  child work items, role-matched round-robin), GET work-items.
- schema: work_item.hermes_task_id/dispatched_at, employee.role.
- Hermes integration fixes discovered live:
  * profiles must use the pool custom endpoint (provider config written into
    per-profile config; 'ollama' provider = Ollama Cloud, wants API key)
  * kanban toolset was globally disabled in deployed Hermes config — removed
    from agent.disabled_toolsets (backup in scratchpad)
  * no_skills profiles (73 bundled skills drowned 9B tool discipline)
  * souls spell out kanban_show first, kanban_complete/kanban_block with
    required args last — after this, tasks complete reliably.
- Live result: GasWatch objective decomposed into 3 tasks, all completed by
  qwen3.5:9b employees (mvp_features.md, onepager.md, report.md), 4 cost
  entries totaling ~24 min wall, full event trail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 09:49:26 -05:00
fez5587andClaude Fable 5 c8bfa0c0ab Slice 1: engine core — compose stack, db layer, company/employee API
- docker-compose.yml: Postgres 16 (schema auto-applied) + Redis, nonstandard
  host ports 5433/6380.
- engine/db.py: async psycopg pool, append_event in caller's transaction.
- engine/souls.py: versioned role charters (manager/engineer/qa) + reporting
  protocol appended to every soul.
- engine/main.py: POST/GET companies, employee hire with Hermes profile
  creation (outside tx, retryable; DB authoritative), event feed, archive
  with profile cleanup, global pause/resume in Redis.
- Verified live end-to-end: create -> 4 events + 3 real Hermes profiles;
  pause flips health; archive 204 removes profiles, keeps rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 00:36:36 -05:00
fez5587andClaude Fable 5 d05004e9cd Slice 1: Hermes adapter with live-verified round-trips
- engine/hermes_client.py: cookie-auth async client — profiles (create/soul/
  model/delete), kanban tasks (create with tenant + runaway budget mapping,
  idempotency via work-item UUID, update/delete), dispatch, runs, workers.
- engine/config.py: env-driven settings (.env stays gitignored).
- tests/test_hermes_live.py: live smoke against Hermes 0.19.0 — all pass:
  profile round-trip, task create (t_*), idempotent re-create, status patch,
  cleanup. No dispatch triggered (no GPU burn).
- Discovery: kanban responses wrap in {task}; webhooks are inbound triggers,
  so engine polls run/task status (ADR-001 fallback is the primary channel).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 00:34:20 -05:00
fez5587andClaude Fable 5 ad4f603799 Step 5+6: event schema v1, core DDL, policy table, Slice 1 acceptance demo
- db/schema.sql: 9 core tables, append-only event log (trigger-enforced),
  deny-by-default policy_rule with seeded globals, runaway budgets on work items.
  Validated against Postgres 16 (DDL applies, trigger rejects UPDATE).
- engine/schemas/events.py: AgentMessage (flat, inference-enforced) +
  EventEnvelope pydantic models; models are the schema (ADR-003).
- adr/ADR-003: event schema and data model decisions.
- SLICE1_DEMO.md: verbatim acceptance script for Slice 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 23:26:49 -05:00
fez5587andClaude Fable 5 fdf7a67db0 Add PRD, addendum, pre-implementation docs, ADRs, and capability-gate benchmarks
- PRD v1.0 plus addendum with environment reality checks (qwen3.5:9b pool, runaway protection, MVP trim)
- Pre-implementation checklist and GitHub integration plan
- ADR-001: build on Hermes Agent 0.19.0 as agent runtime; engine stays source of truth
- ADR-002: engine stack (FastAPI, Postgres, Redis, React)
- Benchmark suites + results: all five capability gates PASS, pool scaling 1.92x at 4 concurrent

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 22:58:52 -05:00
fez5587 dc665519a8 Initial commit 2026-08-03 18:28:51 -05:00