Skip to content

[bug] DeepSeek Harness never loads teamai's hooks unless the member runs dsh --patch #1219

Closed

Description

@SaulMoro

Problem

teamai writes its dsh hooks to ~/.teamai/dsh/hooks.json and a patch overlay to ~/.teamai/dsh/cordis.patch.yml, then asks the member to start dsh with --patch "<path>" (src/dsh-hooks.ts:108). A member who runs plain dsh, which is the default and the only option in a launcher that takes no flags, gets no teamai hook: no project rules, no session-start sync, no env hint, no usage. doctor still reports ✔ Project rules reach dsh through its session-start hook, because it compares the patch and hooks.json bytes.

dsh already applies a patch from its home on every boot. readProfilePatches composes the bundle layers, <DSH_HOME>/profiles/<name>/cordis.patch.yml, then $DSH_HOME/cordis.patch.yml, then any --patch overlays (packages/boot/app-boot/src/profile-context.ts). The home layer is in the published app-boot 0.1.7-rc.2 and 0.2.0-rc.2.

flowchart TB
    subgraph boot ["dsh boot: readProfilePatches, applied in order"]
        b["bundle layers"] --> p["$DSH_HOME/profiles/&lt;name&gt;/cordis.patch.yml"] --> h["$DSH_HOME/cordis.patch.yml"] --> o["--patch overlays"]
    end
    t["~/.teamai/dsh/cordis.patch.yml<br/>mounts teamai's hooks.json"]:::teamai
    t -. "today: only when the member runs dsh --patch" .-> o
    row["teamai's row, merged in<br/>(member's rows kept)"]:::added -- "proposed: every boot" --> h
    classDef teamai fill:#2f5f8f,stroke:#1f4569,color:#fff;
    classDef added fill:#2f8f4f,stroke:#1f6b39,color:#fff;
Loading

Evidence

  • dsh source at 687f282e (dsh-v0.2.1-rc.2): readProfilePatches and composeProfile (apps/cli/src/profile-boot.ts). ~/.teamai/dsh/cordis.patch.yml is in none of the layers.
  • dsh's own hook parser (parseClaudeCodeConfig, selectHookGroups) parses all six entries of teamai's hooks.json, so the file is right. Only the mount is missing.
  • An isolated-HOME pull writes the bridge, and doctor passes its check. dsh's boot source shows that plain dsh does not load that bridge.

Two more problems on the same path

  • Hook writes are sandboxed. With --patch, hook commands run in dsh-bash-sandbox (or dsh-pwsh-sandbox) under workspace-write, rooted at the boot cwd. Under the default permission policy, writes to ~/.teamai fail silently unless dsh started in $HOME, so session-start sync and usage stay off even when the hook runs. Read-only handlers (project rules, env hint) work.
  • A stale note. The doctor text in src/resources/rules.ts:1672 says the hook "runs detached, so the first request can miss the rules". Since dsh-hooks-claude-code 0.1.7-rc.1 the SessionStart run is awaited before the agent starts.

Fix

Mount the hooks plugin from $DSH_HOME/cordis.patch.yml. That file belongs to the member, so the writer inserts or updates only teamai's row and keeps the other rows. Removal deletes only that row. Drop the --patch instruction and the stale note. The sandbox needs its own decision: the hooks that write could move their writes out of the hook process, or teamai could document that sync needs dsh started in $HOME.

Done when

  • Plain dsh loads teamai's hooks.
  • A member's own rows in $DSH_HOME/cordis.patch.yml survive pull and uninstall.
  • doctor checks the mount in $DSH_HOME/cordis.patch.yml, not the bytes of a file dsh never reads.
  • Under the default sandbox, sync and usage either work or doctor says they cannot write teamai's state. Mounting the hooks alone does not close this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions