Skip to content

mcpx: Phase 1 of #1675 — owner-only elicitation broker store (0700 dir, 0600 files, migration on open) #1676

Closed

Description

@dezren39

Phase 1 of design #1675 (mcpx elicitation broker hygiene). Design doc: files/designs/code-mcpx-elicitation-broker-hygiene.md in the keep-the-four-repos-healthy goal workspace.

Scope

Give the elicitation broker store an owner-only home, and migrate existing installs without losing pending questions.

  • Add one store-path helper in internal/elicit (working name StorePath) that both open sites use — today internal/daemon/hooks.go OpenBroker (~L288-294) and internal/cli/elicit.go broker() (~L37-44) each assemble <state>/logs/elicit.db independently with defaults.PublicDirMode (0755).
  • The store moves to a dedicated subdirectory of the state dir (name settled in triage), created at defaults.DirMode (0700); the DB, -wal and -shm files are 0600 after open.
  • Migration on open: if a legacy logs/elicit.db exists and the new path does not, move it before opening (rename; copy-then-delete fallback across filesystems). If migration fails, fall back to opening the legacy path tightened in place rather than losing state. Pending questions must survive: a question pending across the upgrade stays answerable (the broker's core promise — asker and answerer are different processes, possibly days apart).
  • Tightening on open: after opening, chmod the store dir to 0700 and DB files to 0600 if looser (covers dirs/files created by older binaries or a permissive umask — MkdirAll does not chmod an existing directory). Failure to tighten is a returned error, not a log line. Tightening must be idempotent and safe when the daemon and CLI open the store concurrently (re-stat; SQLite WAL + busy_timeout already handle concurrent access).
  • The shared logs directory keeps PublicDirMode — out of scope (recorded decision on design(mcpx): elicitation broker hygiene — owner-only store, bounded retention, redacted events, review-first answering #1675).
  • Retire conformance gap elicitation-state-storage-protected (internal/conformance/coverage_clientfeatures.go).

Evidence (main d39e611, 2026-10-28)

  • Origin mcpx: elicitation storage is readable by any local user and never pruned; elicitation UI and response validation rows dezren39/darwin-nix#255 acceptance: "The elicitation broker store is permission-restricted to the owner (no world/group read) and this is verified on disk."
  • internal/defaults/defaults.json:214: publicDirMode: 0755 vs dirMode: 0700 at :211 — the codebase already distinguishes the two; the broker's open sites chose the public one.
  • Owner-only precedent in-tree: internal/artifacts creates dirs at 0o700 throughout; daemon Paths.Ensure (internal/daemon/paths.go ~L411-419) creates state/cache at 0o700.
  • What is at risk in the store: elicit.Route (internal/elicit/elicit.go ~L504-527) sends password/credential-shaped fields to the human audience because an agent should not hold them; sampling requests are "stored exactly as sent" (internal/daemon/hooks.go sampleViaBroker ~L180-187).

Acceptance

  • Fresh open: store dir mode 0700, elicit.db/-wal/-shm mode 0600, asserted in tests via stat.
  • Legacy logs/elicit.db containing a pending question: after open at the new path, the question is listed and answerable; the legacy file is gone (or, in the fallback path, tightened in place).
  • Pre-loosened store dir/files (simulating an older install): modes tightened on open.
  • Daemon + CLI opening the store concurrently does not error on the tightening step.
  • Gap elicitation-state-storage-protected retired with the tests as evidence.
  • CI green for pkgs/mcpx (tests run in GitHub Actions).

Activity

  1. added
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 28, 2026
  2. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 28, 2026
  3. 66 remaining items

  4. added
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Oct 29, 2026
  5. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  6. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 29, 2026
  7. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions