Linear Tickets — Plan B: CLI-Native Agent (Shell Exec)

Draft tickets for review before committing to Linear. Project: Eden — Data Access + Chat Integration Linear team: EDE3 Milestones: M1 (Apr 6) Slack, M2 (Apr 13) GWS, M3 (Apr 20) Cross-platform + full Command Center Source: alt-architecture-cli-native-agent.md, spike-command-center-data-access.md §5 Estimation: 1 point = 1 hour Stack: Mastra (TypeScript) + Next.js 15 on Cloud Run (Eden GCP, BAA-covered), Vertex AI Gemini API for LLM Architecture: Generic run_gws shell-exec tool replaces 6+ custom GWS tool functions. Slack MCP server replaces custom Slack tools. See alt-architecture-cli-native-agent.md for rationale.


Effort summary

#TicketPtsStepMilestoneSame as Plan A?
1Create GCP project and service account21Yes (Plan A #1)
2Request DWD approval from Eden IT21Yes (Plan A #2)
3Create Slack app for Eden workspace31Yes (Plan A #3)
4aDesign identity mapping schema and token convention32Yes (Plan A 4a)
4bBuild resolve_identity lookup function + seed mapping42Yes (Plan A 4b)
5aBuild core PII redaction function (email, name, phone)42Yes (Plan A 5a)
5bWrite PII redaction test fixtures and validation suite32Yes (Plan A 5b)
B1Build run_gws and gws_schema tools with command whitelist53New
B2Connect Slack MCP server and validate33M1New (replaces Plan A #6, 7, 8a, 8b)
B3Build Mastra agent scaffold with run_gws + Slack MCP tools53M1Modified (Plan A 9a)
B4Build chat interface and deploy to Cloud Run for M1 demo43M1Yes (Plan A 9b)
B5GWS command reference + integration tests across all GWS surfaces54M2New (replaces Plan A 10-16)
B6Build cross-platform orchestration and project registry55M3Yes (Plan A #17)
B7End-to-end validation and production deploy45M3Yes (Plan A #18)
Total52

Comparison to Plan A

Plan A (Custom Tools)Plan B (CLI-Native)Delta
Tickets1814−4
Points7552−23 (31% less)
Custom GWS tools6 functions + registration ticket2 generic tools−5 tickets
Custom Slack tools3 functions + caching ticket0 (Slack MCP)−4 tickets
New tickets (B-only)B1, B2, B5+3 tickets

Step 1 — Source Authentication (same as Plan A)

Tickets 1, 2, 3 are identical to Plan A. See linear-tickets-data-access-chat-integration.md for full descriptions.

#TicketPtsPlan A ref
1Create GCP project and service account for Eden Command Center2Plan A #1
2Request DWD approval from Eden IT2Plan A #2
3Create Slack app for Eden workspace3Plan A #3

Step 2 — Identity Anonymization Layer (same as Plan A)

Tickets 4a, 4b, 5a, 5b are identical to Plan A. See linear-tickets-data-access-chat-integration.md for full descriptions.

#TicketPtsPlan A ref
4aDesign identity mapping schema and token convention3Plan A 4a
4bBuild resolve_identity lookup function + seed mapping4Plan A 4b
5aBuild core PII redaction function (email, name, phone)4Plan A 5a
5bWrite PII redaction test fixtures and validation suite3Plan A 5b

Step 3 — Data Access Tools + Agent + M1

Ticket B1: Build run_gws and gws_schema tools with command whitelist

Estimate: 5 pts

Context

  • Instead of building 6+ individual GWS tool functions, we build two generic tools: run_gws executes any allowed gws CLI command and returns PII-redacted JSON; gws_schema lets the agent discover API method schemas at runtime.
  • Depends on: Ticket 1 (GCP project), Ticket 5a (PII redaction)
  • Architecture reference: alt-architecture-cli-native-agent.md

Goal

Build the two generic GWS tools and the security whitelist so the agent can access any Google Workspace API through the CLI.

Scope

In scope

  • Build run_gws(command, params?) as a Mastra tool:
    • Accepts a CLI command string (e.g. drive files list) and optional params object
    • Spawns gws <command> --params '<json>' --format json via execFile (not exec — no shell injection)
    • Passes service account credentials via env vars (GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE, GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER)
    • Runs raw JSON output through redact() before returning to the agent
    • 10-second timeout on child process
    • Logs every command executed (service, method, params) for audit trail
  • Build gws_schema(method) as a Mastra tool:
    • Accepts an API method name (e.g. drive.files.list)
    • Returns the request/response schema so the agent can learn available parameters
  • Build a command whitelist:
    • Allowed services: drive, gmail, calendar, admin, driveactivity:v2, sheets, docs
    • Read-only operations only — block delete, update, send, insert, modify, trash subcommands
    • Reject any command not matching the whitelist
  • Unit tests: whitelist enforcement, execFile argument construction, PII redaction on sample GWS outputs
  • Install @googleworkspace/cli in the project (npm dependency) and verify it runs in the Docker image

Out of scope

  • Testing against all GWS API surfaces (Ticket B5)
  • Agent scaffold (Ticket B3)
  • Write operations (the Command Center is read-only)

Acceptance Criteria

  • run_gws("drive files list", { pageSize: 5 }) returns PII-redacted JSON
  • run_gws("gmail users messages delete", ...) is rejected by the whitelist
  • run_gws("rm -rf /", ...) is rejected (not a valid service)
  • gws_schema("drive.files.list") returns the API method schema
  • All outputs pass through redact() — no raw emails or names in returned JSON
  • Command audit log captures every execution
  • Child process timeout fires after 10 seconds

Notes / Constraints

  • Use execFile (array of args), never exec (shell string) — this prevents command injection
  • The GWS CLI must be installed globally in the Docker image (npm install -g @googleworkspace/cli)
  • Service account credentials come from GCP Secret Manager, mounted at runtime

Ticket B2: Connect Slack MCP server and validate

Estimate: 3 pts

Context

  • Slack provides an official hosted MCP server at mcp.slack.com with tools for search, channel history, threads, and user profiles. Instead of building 3 custom Slack tool functions, we connect Mastra to Slack’s MCP server directly.
  • Depends on: Ticket 3 (Slack app + token), Ticket 5a (PII redaction)
  • Reference: Slack MCP Server docs

Goal

Connect the Mastra agent to Slack’s official MCP server and validate it can search messages, read threads, and list channels with PII redaction.

Scope

In scope

  • Configure Mastra as an MCP client connecting to mcp.slack.com
  • Authenticate using the Slack app OAuth token from Ticket 3
  • Validate available tools: search messages, read channel history, read thread replies, list channels, user profiles
  • Build a Mastra processor that intercepts all Slack MCP tool outputs and runs redact() before they enter the LLM context
  • Test: search returns results, thread reading works, all outputs are anonymized
  • Document which Slack MCP tools map to the COO’s expected queries

Out of scope

  • Building custom Slack tool functions (fallback option if MCP proves unreliable — would add ~14 pts and revert to Plan A Tickets 6, 7, 8a, 8b)
  • Caching layer (Slack MCP server handles its own caching)

Acceptance Criteria

  • Mastra connects to mcp.slack.com and discovers available tools
  • Search tool returns results for a keyword query
  • Thread reading returns parent + replies
  • All outputs pass through PII redaction processor — anonymized tokens only
  • Connection handles errors gracefully (timeout, auth failure, server unavailable)
  • Documented: tool name → query type mapping for the system prompt

Notes / Constraints

  • Slack MCP server is hosted externally — we don’t control uptime. If it proves unreliable during development, fall back to custom Slack tools (Plan A Tickets 6, 7, 8a, 8b — adds ~14 pts)
  • Semantic search requires Business+ plan. If Eden is on Pro, keyword search only.
  • The PII redaction processor must handle Slack MCP’s response format, which may differ from raw Slack API JSON (Slack MCP returns LLM-friendly text, not raw JSON)

Open Questions

  • Does the Slack MCP server support service-level auth (bot token), or does it require user-level OAuth?
  • What’s the rate limit on the hosted MCP server?

Ticket B3: Build Mastra agent scaffold with run_gws + Slack MCP tools

Estimate: 5 pts

Context

  • The generic tools (B1: run_gws + gws_schema) and Slack MCP (B2) need to be wired into a Mastra agent. Unlike Plan A where the agent has 9 typed tools, this agent has generic tools and needs a detailed system prompt to guide GWS command construction.
  • Depends on: Ticket B1 (run_gws tools), Ticket B2 (Slack MCP)

Goal

Build the Mastra agent that can answer questions about Slack activity using both the generic GWS tools and Slack MCP tools.

Scope

In scope

  • Build a TypeScript Mastra agent (@mastra/core) with:
    • run_gws and gws_schema registered as tools
    • Slack MCP tools connected as an MCP tool provider
    • pii_redact processor on all tool outputs
  • Write the agent system prompt:
    • GWS command reference: for each query type, the exact gws command and params to use (Drive search, Drive Activity, comments, Gmail, Calendar, Admin SDK)
    • Slack tool routing: which MCP tool to use for search vs thread vs stats queries
    • Anonymization rules: always use tokens, never output raw identities
    • Multi-step reasoning: how to chain tool calls (search → read detail → synthesize)
  • Configure Gemini 2.5 Flash as the LLM via Vertex AI API (BAA-covered)
  • Test locally against Slack (M1 focus): agent correctly routes 5+ Slack question types

Out of scope

  • Chat interface (Ticket B4)
  • Cloud Run deployment (Ticket B4)
  • GWS testing across all surfaces (Ticket B5 — M2 scope)

Acceptance Criteria

  • Mastra agent instantiable with run_gws, gws_schema, and Slack MCP tools
  • Agent correctly uses Slack MCP for search/thread/channel queries
  • Agent correctly constructs run_gws commands for Drive/Gmail/Calendar queries (can test with mock or Brainforge workspace)
  • Agent uses gws_schema when it encounters an unfamiliar API method
  • Synthesized answers use only anonymized tokens
  • LLM calls routed to Vertex AI Gemini API
  • System prompt includes complete GWS command reference
  • Runs locally via npx tsx or Next.js dev server

Notes / Constraints

  • The system prompt is critical — it replaces the typed tool schemas from Plan A. Budget extra time for prompt iteration.
  • The agent has more freedom (and more rope) than in Plan A. It can construct any gws command the whitelist allows, which is powerful but means more integration testing.

Ticket B4: Build chat interface and deploy to Cloud Run for M1 demo

Estimate: 4 pts

Identical to Plan A Ticket 9b. See linear-tickets-data-access-chat-integration.md 9b for full description.

Key details:

  • Build Next.js chat page with shadcn/ui (input, message list, streaming)
  • Next.js API route calls Mastra agent directly
  • Deploy to Cloud Run in Eden’s GCP project
  • M1 gate: Danny can chat with the agent about Slack data by April 6

Step 4 — GWS Surfaces Validation (replaces Plan A Tickets 10-16)

Ticket B5: GWS command reference + integration tests across all GWS surfaces

Estimate: 5 pts

Context

  • In Plan A, Step 4 is 7 tickets (23 pts) building individual tool functions for Drive, Drive Activity, Comments, Gmail, Calendar, and Admin SDK, then registering them in the agent. In Plan B, the agent already has run_gws — what’s needed is to validate it works correctly across all GWS API surfaces and refine the system prompt.
  • Depends on: Ticket B1 (run_gws tools), Ticket 2 (DWD approved)
  • Replaces: Plan A Tickets 10, 11, 12, 13, 14, 15, 16

Goal

Validate run_gws against every GWS API surface the COO needs, build the definitive command reference for the system prompt, and ensure PII redaction handles all response shapes.

Scope

In scope

  • Test run_gws against each GWS API via DWD (with real Eden data once DWD is approved):
    1. Drive searchgws drive files list with query, folder, MIME type filters
    2. Drive Activitygws driveactivity:v2 activity query for folder/file audit trails
    3. File commentsgws drive comments list for comment metadata and replies
    4. Gmailgws gmail users messages list + gws gmail users messages get for thread metadata
    5. Calendargws calendar events list for event metadata, attendees, scheduling
    6. Admin SDKgws admin directory users list for org directory
  • For each surface:
    • Document the exact command + params that produce the best results
    • Validate PII redaction handles the response shape (emails, names, phone numbers stripped)
    • Test edge cases: empty results, large result sets (pagination via --page-all), rate limits
    • Add the working command to the agent’s system prompt GWS command reference
  • Update PII redaction fixtures (Ticket 5b) with real response shapes from each GWS API
  • Update the agent system prompt with the final, tested GWS command reference
  • Integration tests: agent correctly constructs and executes the right run_gws command for 10+ GWS query types

Out of scope

  • Building individual tool functions (that’s Plan A)
  • Cross-platform orchestration (Ticket B6)

Acceptance Criteria

  • run_gws successfully queries all 6 GWS API surfaces
  • PII redaction validated against real response shapes from each surface
  • Agent system prompt includes tested command reference with examples for each API
  • Integration tests pass for:
    • “Search for documents about the rebrand” → run_gws("drive files list", { q: "rebrand" })
    • “Who edited the Q1 budget spreadsheet?” → run_gws("driveactivity:v2 activity query", ...)
    • “Show me comments on the strategy doc” → run_gws("drive comments list", { fileId: "..." })
    • “What emails came in about the vendor contract?” → run_gws("gmail users messages list", { q: "vendor contract" })
    • “What meetings does the ops team have this week?” → run_gws("calendar events list", ...)
    • “Who’s in the engineering department?” → run_gws("admin directory users list", { query: "engineering" })
  • Existing Slack queries still work correctly
  • Fixture file updated with ≥ 6 real GWS response shapes

M2 deliverable (Apr 13): Danny can query the agent for Google Workspace activity — file movement, email thread patterns, calendar load, Drive comments — all with anonymized identities. Slack (M1) continues to work. Same chat UI, same Cloud Run deployment.


Step 5 — Cross-Platform Orchestration + Deploy (same as Plan A)

Tickets B6 and B7 are functionally identical to Plan A #17 and #18. See linear-tickets-data-access-chat-integration.md for full descriptions.

Ticket B6: Build cross-platform orchestration and project registry

Estimate: 5 pts (same as Plan A #17)

See Plan A Ticket 17 for full description. The work is the same:

  • Cross-platform query routing (Slack + GWS in parallel)
  • Project registry (project name → Slack channel + Drive folder)
  • System prompt updates for multi-source reasoning
  • 5+ cross-platform test queries

The only difference: in Plan A the orchestration routes to typed tool functions; in Plan B it constructs run_gws commands and calls Slack MCP tools. The orchestration logic and project registry are identical.


Ticket B7: End-to-end validation and production deploy

Estimate: 4 pts (same as Plan A #18)

See Plan A Ticket 18 for full description. The work is the same:

  • 10-15 test queries spanning single-source Slack, single-source GWS, cross-platform, anonymization
  • Cloud Run deployment finalization
  • GCP budget alerts and Vertex AI quotas
  • Deployment runbook
  • Danny signs off on M3

M3 deliverable (Apr 20): Full Command Center — Danny chats with the agent about anything across Google Workspace and Slack. All identities anonymized. Same as Plan A’s M3, same acceptance criteria.


Ticket dependency graph

Ticket 1: Create GCP project (2 pts) ──────────┐
                                                 ├──→ Ticket 4a: Mapping schema (3 pts)
Ticket 2: Request DWD approval (2 pts) ─────────┘         │
                                                           ▼
                                                 Ticket 4b: resolve_identity (4 pts)
                                                           │
Ticket 3: Create Slack app (3 pts) ─────────────┐         │
                                                 ├──→ Ticket 5a: PII redaction core (4 pts)
                                                 │         │
                                                 │    Ticket 5b: PII test suite (3 pts)
                                                 │         │
                                                 │         ▼
                                                 ├── Ticket B1: run_gws + gws_schema (5 pts)
                                                 │
                                                 └── Ticket B2: Slack MCP connection (3 pts)
                                                           │
                                                           ▼
                                                 Ticket B3: Mastra agent scaffold (5 pts)
                                                           │
                                                           ▼
                                                 Ticket B4: Chat UI + Cloud Run deploy (4 pts)
                                                        ↑ M1 gate (Apr 6)
                                                           │
    ┌──────────────────────────────────────────────────────┘
    │  (DWD approved — Ticket 2 — unlocks GWS validation)
    │
    └── Ticket B5: GWS surfaces validation + prompt ref (5 pts)
                        ↑ M2 gate (Apr 13)
                    │
                    ▼
         Ticket B6: Cross-platform orchestration (5 pts)
                    │
                    ▼
         Ticket B7: E2E validation + prod deploy (4 pts)
                        ↑ M3 gate (Apr 20)

Critical paths

M1 critical path (25 pts): Ticket 3 → 4a → 4b → 5a → B1 → B3 → B4. Ticket B2 (Slack MCP) runs in parallel with B1 once the Slack app (Ticket 3) and PII middleware (5a) are done.

M2 critical path (additional 5 pts from M1): Ticket B5 starts once DWD (Ticket 2) is approved. Only one ticket between M1 and M2 (vs 7 tickets in Plan A).

M3 critical path (additional 9 pts from M2): Ticket B6 → B7. Same as Plan A.

Total: 52 pts. M1 critical path is similar to Plan A (25 pts vs 25 pts). M2 is dramatically simpler (5 pts vs 23 pts). M3 is identical.


Fallback: If Slack MCP is unreliable

If the Slack MCP server (mcp.slack.com) proves unreliable during Ticket B2, replace it with Plan A’s custom Slack tools:

ReplaceWith (from Plan A)Additional pts
Ticket B2 (3 pts)Plan A #6 (5) + #7 (3) + 8a (4) + 8b (2) = 14 pts+11 pts
Ticket B3 modificationsUpdate agent scaffold to use custom Slack tools instead of MCP+1 pt

Fallback total: 52 − 3 + 14 + 1 = 64 pts (still 11 pts less than Plan A’s 75 pts, because run_gws still replaces 6 custom GWS tools).


Side-by-side: Plan A vs Plan B

StepPlan A ticketsPlan A ptsPlan B ticketsPlan B ptsNotes
1. Auth1, 2, 371, 2, 37Identical
2. PII4a, 4b, 5a, 5b144a, 4b, 5a, 5b14Identical
3. Slack tools6, 7, 8a, 8b14B23Slack MCP replaces 4 custom tools
3. GWS generic toolsB15New: run_gws + whitelist
3. Agent scaffold9a4B35B3 is +1 pt (more prompt engineering)
3. Chat UI + deploy9b4B44Identical
4. GWS surfaces10-1623B55Biggest savings: 7 tickets → 1
5. Orchestration175B65Identical
5. Deploy184B74Identical
Total18 tickets7514 tickets52−23 pts (31%)