Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Here Be Dragons — Babysitter Monorepo
page:docs-here-be-dragonsa5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
II.
Page JSON

page:docs-here-be-dragons

Structured · live

Here Be Dragons — Babysitter Monorepo json

Inspect the normalized record payload exactly as the atlas UI reads it.

File · wiki/docs/here-be-dragons.mdCluster · wiki
Record JSON
{
  "id": "page:docs-here-be-dragons",
  "_kind": "Page",
  "_file": "wiki/docs/here-be-dragons.md",
  "_cluster": "wiki",
  "attributes": {
    "nodeKind": "Page",
    "sourcePath": "docs/here-be-dragons.md",
    "sourceKind": "repo-docs",
    "title": "Here Be Dragons — Babysitter Monorepo",
    "displayName": "Here Be Dragons — Babysitter Monorepo",
    "slug": "docs/here-be-dragons",
    "articlePath": "wiki/docs/here-be-dragons.md",
    "article": "\n# Here Be Dragons — Babysitter Monorepo\n\nUnmarked coupling, maintenance hazards, missing caveats, and dangerous zones. This is the map of places where a well-intentioned change will bite you.\n\n**Legend:** ~~strikethrough~~ = fixed/mitigated\n\n---\n\n## Hotspot Map\n\nFiles/modules that concentrate the most danger across multiple categories.\n\n| File | Categories | Top Risk |\n|------|-----------|----------|\n| `packages/genty/core/src/session.ts` | coupling, caveat | 8 env vars read with complex fallback chain, 900s timeout unexplained *(model default + anthropic conversion now logged)* |\n| `packages/adapters/core/src/provider-resolver.ts` | coupling | 6-level region chain, 5-level model chain *(model source + Google→Vertex now logged)* |\n| `packages/genty/platform/src/harness/internal/createRun/orchestration/effects.ts` | hazard, coupling, caveat | Double-cast type assertions, process.env mutations *(retry loop now logged)* |\n| `packages/genty/platform/src/harness/piWrapper/moduleSupport.ts` | coupling, caveat | Azure env mutations *(URL parse + import error now logged)* |\n| `packages/adapters/core/src/spawn-runner.ts` | hazard | 8+ PTY kill/write failures *(4 now logged in spawn-runner)* |\n| `packages/genty/core/src/agenticTools/shared/process.ts` | caveat, hazard | Ripgrep path cached at module load |\n| `packages/adapters/webui/src/lib/global-registry.ts` | coupling | globalThis shared mutable state, duplicated in observer-dashboard |\n| `packages/genty/platform/src/harness/internal/createRun/planProcess/phase.ts` | hazard | 3-layer recovery chain invisible without verbose *(code block extraction now rejects non-process blocks)* |\n| ~~`packages/babysitter-sdk/src/storage/journal.ts`~~ | ~~fallback~~ | ~~Atomicity abandoned~~ → now throws on ENOENT. Queue errors logged. |\n| ~~`packages/adapters/core/src/kanban.ts`~~ | ~~hazard~~ | ~~2518 lines, 6+ sealed switch statements, stringly-typed status values~~ -> status/workflow mappings now use typed tables with coverage tests. |\n\n---\n\n## Critical Dragons\n\n### process.env mutation couples modules through ambient state\n**Files:** `packages/adapters/observability/src/logger.ts`, `packages/adapters/observability/src/logger-simple.ts`, `packages/adapters/observability/src/index.ts`\n\n**FIXED for package writers:** Pi Azure defaults now return an overlay instead of writing `AZURE_OPENAI_*`; agent-core and agent-platform config helpers delegate to explicit scoped runtime config state; adapters CLI and TUI logging setup reconfigure observability without writing `ADAPTER_OBSERVABILITY_MODE` into `process.env`.\n\n**Remaining caveat:** observability defaults still read `ADAPTER_LOG_LEVEL`, `ADAPTER_LOG_FILE`, `ADAPTER_LOG_PRETTY`, and `ADAPTER_OBSERVABILITY_MODE` from ambient env at module/runtime boundaries. Keep future changes on explicit config surfaces rather than adding new in-process env writers.\n\n**Tracked separately:** #584 is the focused implementation issue for replacing these ambient in-process writes with an explicit env/config contract. Keep #601 changes from duplicating that larger refactor.\n\n### ~~globalThis shared mutable state with duplicate definitions~~\n**Files:** `packages/adapters/webui/src/lib/global-registry.ts`, `packages/observer-dashboard/src/lib/global-registry.ts`\n\n**FIXED:** Extracted `createGlobalRegistry<TMap>` factory. All three copies (webui, gateway, observer-dashboard) now use the same factory with domain-specific type maps. Factory is canonical source, copies marked.\n\n### ~~Double-cast type assertions bypass all safety~~\n**Files:** `packages/genty/core/src/loop/agent-loop.ts:209`, `packages/genty/platform/src/harness/internal/createRun/orchestration/effects.ts:128-129`, `packages/genty/platform/src/cost/journal.ts`\n\n**FIXED:** agent-loop.ts now validates shape at runtime before cast. effects.ts removed 3 double-casts (TaskDef has index sig, session has public abort). cost/journal.ts replaced blind cast with field-by-field validation.\n\n### ~~Background process registry orphans on options object recreation~~\n**File:** `packages/genty/runtime/src/background/state.ts:13-35`\n\n**FIXED:** Added `registryId` string key alongside WeakMap. Same logical owner with `registryId` reuses existing registry instead of creating a new one.\n\n### ~~Silent stdout truncation at 50MB~~\n**File:** `packages/genty/core/src/agenticTools/shared/process.ts:55-84`\n\n**FIXED:** Now emits a visible `[babysitter] WARNING: stdout truncated at ... bytes` message in the output when truncation triggers. Caller can see that data was lost.\n\n---\n\n## Coupling Map\n\n### Env var coupling (writer → reader, no contract)\n\n| Writer | Env Var | Reader | Risk |\n|--------|---------|--------|------|\n| `piWrapper/moduleSupport.ts` | `AZURE_OPENAI_RESOURCE_NAME` | `session.ts`, Pi module | Init-order dependent |\n| `piWrapper/moduleSupport.ts` | `AZURE_OPENAI_BASE_URL` | `session.ts`, Pi module | Mutated in-place |\n| `piWrapper/moduleSupport.ts` | `AZURE_OPENAI_DEPLOYMENT_NAME_MAP` | Pi module | Conditional write |\n| `agent-core/config/state.ts` | Any key via `setConfigValue(\"global\")` | All process.env readers | Permanent mutation |\n| `agent-platform/config/state.ts` | Any key via `setConfigValue(\"global\")` | Platform tool/config readers | Permanent mutation |\n| `adapters/cli/index.ts` | `ADAPTER_LOG_LEVEL`, `ADAPTER_LOG_FILE` | `observability/logger.ts` | Startup coupling |\n\n### Cross-package internal imports (fragile)\n\n| Importer | Imports From (internal path) | Risk |\n|----------|----------------------------|------|\n| `genty` tests | `sdk/src/storage` (createRunDir, appendEvent) | SDK refactor breaks genty |\n| `hooks-adapter/core` tests | `adapter-claude/src/mappings`, `adapter-codex/src/mappings` | Adapter restructure breaks core |\n| `hooks-adapter/adapter-codex` tests | `cli/src/cli/stdin`, `cli/src/cli/adapter-loader` | CLI module changes break adapter tests |\n\n### Circular dependency (via re-export shim)\n\n`genty-core` → re-exports from `agent-runtime` (BackgroundProcessRegistry) → `agent-runtime` may import from `genty-core`. Documented with backward-compat shim comment but fragile.\n\n### ~~Stringly-typed event contracts (no compile-time safety)~~\n\n**FIXED:** `BABYSITTER_EVENT_KINDS` const array is now the single source of truth. Type union and Set are both derived from it — cannot drift apart.\n\n---\n\n## Maintenance Minefields\n\n### ~~Shell invocation — 5 locations, subtly different~~\n\n**FIXED:** Shell argv construction is centralized in `@a5c-ai/genty-runtime` through `buildShellInvocation()`. Runtime background spawning, genty-core session execution, and core/platform bash tools all use the shared contract.\n\n### ~~Kanban status — 6+ sealed switch statements~~\n**File:** `packages/adapters/core/src/kanban.ts` (2518 lines)\n\n**FIXED:** #586 replaced the repeated status/workflow switch pattern with typed mapping tables and focused coverage in `packages/adapters/core/tests/kanban.test.ts`. Adding a new status or workflow state now has a single mapping contract and tests that enumerate the supported values.\n\n### ~~Process definition extraction — any code block as fallback~~\n**File:** `packages/genty/platform/src/harness/internal/createRun/planProcess/recovery.ts:33-106`\n\n**FIXED:** Non-process code blocks are now rejected (`return null`) instead of being extracted and executed.\n\n### Validation uses triple-quote-style matching\n**File:** `packages/genty/platform/src/harness/internal/createRun/planProcess/validationSource.ts:294-300`\n\n```typescript\nif (properties.has(\"agent\") && kindValue !== \"\\\"agent\\\"\" && kindValue !== \"'agent'\" && kindValue !== \"`agent`\")\n```\n\nThree quote styles checked separately with hardcoded strings. Adding a new kind requires adding 3 branches. Easy copy-paste bug.\n\n### ~~Magic numbers without constants~~\n\n**FIXED:** Extracted to named constants: `MAX_SHELL_OUTPUT_TAIL_CHARS`, `MAX_NON_SHELL_OUTPUT_HEAD_CHARS`, `DEFAULT_GLOB_LIMIT`, `MAX_GLOB_LIMIT`. ULID slices and `DEFAULT_MAX_TOOL_CALLS` documented inline.\n\n---\n\n## Missing Caveats\n\n### ~~File read silently capped at 10,000 lines~~\n**File:** `packages/genty/core/src/agenticTools/tools/fileSystem.ts:42-45`\n\n**FIXED:** Now appends `(capped at 10000 lines — requested N)` when limit is reduced.\n\n### HTTP fetch response truncated at 50,000 chars\n**File:** `packages/genty/core/src/agenticTools/tools/execution.ts:136-140`\n\nUnless `raw: true`, response bodies are truncated. The `... (truncated)` suffix is appended but the agent may not notice. Truncated JSON/HTML is unparseable.\n\n### Ripgrep path cached at module load — never invalidated\n**File:** `packages/genty/core/src/agenticTools/shared/process.ts:11-26`\n\n`getRgPath()` checks `@vscode/ripgrep` on first call, caches result forever. If ripgrep is installed after first use, the stale `\"rg\"` fallback is used permanently.\n\n### AbortController timeout is advisory, not enforced\n**File:** `packages/genty/core/src/session.ts:96-100`\n\nThe timeout sets an abort signal but doesn't guarantee the request stops. Fetch implementations check the signal asynchronously — requests can exceed the timeout window.\n\n### ~~Circuit breaker constants are unexplained~~\n**FIXED:** Each constant now has a comment explaining what it guards against.\n\n### ~~DEFAULT_TIMEOUT_MS = 900_000 (15 minutes) — unexplained~~\n**FIXED:** Comment added: accommodates long-running model responses and Azure cold-start latency.\n\n### ~~Tool dispose requires exact array reference~~\n**File:** `packages/genty/core/src/agenticTools/index.ts:40-50`\n\n**FIXED:** Tool definitions are now tracked by both returned array and individual tool object ownership. Passing a shallow-copied definitions array to `disposeAgentCoreToolDefinitions()` still resolves the owning options and clears retained background task state.\n\n### ~~Lazy init race on piWrapper failure~~\n**File:** `packages/genty/platform/src/harness/piWrapper.ts:82-92`\n\n**FIXED:** Initialization failures now record the failure and retry-after timestamp. Immediate retries rethrow the recorded failure instead of hammering session creation, while retries after the backoff window can recover from transient failures.\n\n### ~~Platform-specific shell path assumption~~\n**File:** `packages/genty/core/src/agenticTools/tools/execution.ts:53-56`\n\n**FIXED:** Shell invocation now uses the shared runtime helper in `@a5c-ai/genty-runtime`, so agentic shell execution paths share one argv construction contract instead of hardcoding `/bin/bash` in each caller.\n\n---\n\n## Tech Debt Indicators\n\n### Aggregate metrics (2,730 TypeScript files)\n\n| Category | Count | Assessment |\n|----------|-------|-----------|\n| `@ts-ignore` / `@ts-expect-error` | 41 | Low (35 in generated validator.ts) |\n| `eslint-disable` comments | 69 | Low — mostly `no-explicit-any`, `no-var-requires`, `react/no-danger` |\n| Explicit `any` type annotations | 207 | Acceptable — concentrated in adapters/serialization, not business logic |\n| Commented-out code blocks | 20+ files | Low accumulation — comments often explain why removed |\n| Skipped/conditional tests | 20+ suites | Mostly justified; unexplained `SessionDetailScreen` skips fixed |\n| E2E/integration tests | 6 files | Gap: no E2E for orchestration, hook-adapter lifecycle, or trigger dispatch |\n| Pre-release packages (0.1.0) | 5 | atlas, atlas/webui, kradle/cli, kradle/sdk, compendium |\n\n### ~~Unexplained skipped tests~~\n\n**FIXED:** `packages/adapters/ui/src/screens/SessionDetailScreen.test.tsx` now runs the realtime flow and empty-state tests instead of unconditionally skipping them.\n\n### Duplicated utility patterns (no shared module)\n\n- **Platform detection**: 13+ instances of `process.platform === 'win32'` across runner/adapter code — no shared `isWindows()` utility\n- **Path normalization**: 35+ files independently implement path handling — no unified utility\n- **Config loading**: Separate implementations in webui, gateway, and observer-dashboard — should be shared\n\n### Structural debt\n\n- **Re-export shims**: `agent-core/src/agenticTools/background/state.ts` re-exports from `agent-runtime` for backward compat (documented, but still fragile circular bridge)\n- **Deprecated-but-active**: 7 deprecated exports in `agent-core/src/types.ts` still consumed downstream. `SessionCreateArgs` deprecated in `agent-platform` but re-exported indefinitely\n- ~~**Duplicate global registry**~~: extracted `createGlobalRegistry` factory, all three copies now thin wrappers\n- ~~**`noImplicitAny: false`** in `packages/adapters/gateway/tsconfig.json`~~ — **FIXED:** set to `true` along with `useUnknownInCatchVariables`\n- **`skipLibCheck: true`** in root `tsconfig.json` — dependency type incompatibilities invisible\n- **E2E gaps**: No end-to-end coverage for babysitter orchestration loop, hook-adapter lifecycle, or trigger dispatching. Heavy reliance on unit tests\n\n### #601 disposition\n\n#601 is an umbrella tracker, not a single safe refactor boundary. Its previously listed WeakMap disposal, piWrapper lazy-init retry, shell invocation, skipped UI-test, kanban exhaustiveness, and in-process env writer streams are fixed. Further observability env-reader cleanup, duplicated utilities, root `skipLibCheck`, and E2E coverage gaps remain active debt and need focused follow-up issues with their own acceptance criteria before implementation.\n",
    "documents": []
  },
  "outgoingEdges": [],
  "incomingEdges": [
    {
      "from": "page:docs",
      "to": "page:docs-here-be-dragons",
      "kind": "contains_page"
    }
  ]
}

Shortcuts

Back to overview
Open graph tab