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: Genericrun_gwsshell-exec tool replaces 6+ custom GWS tool functions. Slack MCP server replaces custom Slack tools. Seealt-architecture-cli-native-agent.mdfor rationale.
Effort summary
| # | Ticket | Pts | Step | Milestone | Same as Plan A? |
|---|---|---|---|---|---|
| 1 | Create GCP project and service account | 2 | 1 | — | Yes (Plan A #1) |
| 2 | Request DWD approval from Eden IT | 2 | 1 | — | Yes (Plan A #2) |
| 3 | Create Slack app for Eden workspace | 3 | 1 | — | Yes (Plan A #3) |
| 4a | Design identity mapping schema and token convention | 3 | 2 | — | Yes (Plan A 4a) |
| 4b | Build resolve_identity lookup function + seed mapping | 4 | 2 | — | Yes (Plan A 4b) |
| 5a | Build core PII redaction function (email, name, phone) | 4 | 2 | — | Yes (Plan A 5a) |
| 5b | Write PII redaction test fixtures and validation suite | 3 | 2 | — | Yes (Plan A 5b) |
| B1 | Build run_gws and gws_schema tools with command whitelist | 5 | 3 | — | New |
| B2 | Connect Slack MCP server and validate | 3 | 3 | M1 | New (replaces Plan A #6, 7, 8a, 8b) |
| B3 | Build Mastra agent scaffold with run_gws + Slack MCP tools | 5 | 3 | M1 | Modified (Plan A 9a) |
| B4 | Build chat interface and deploy to Cloud Run for M1 demo | 4 | 3 | M1 | Yes (Plan A 9b) |
| B5 | GWS command reference + integration tests across all GWS surfaces | 5 | 4 | M2 | New (replaces Plan A 10-16) |
| B6 | Build cross-platform orchestration and project registry | 5 | 5 | M3 | Yes (Plan A #17) |
| B7 | End-to-end validation and production deploy | 4 | 5 | M3 | Yes (Plan A #18) |
| Total | 52 |
Comparison to Plan A
| Plan A (Custom Tools) | Plan B (CLI-Native) | Delta | |
|---|---|---|---|
| Tickets | 18 | 14 | −4 |
| Points | 75 | 52 | −23 (31% less) |
| Custom GWS tools | 6 functions + registration ticket | 2 generic tools | −5 tickets |
| Custom Slack tools | 3 functions + caching ticket | 0 (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.mdfor full descriptions.
| # | Ticket | Pts | Plan A ref |
|---|---|---|---|
| 1 | Create GCP project and service account for Eden Command Center | 2 | Plan A #1 |
| 2 | Request DWD approval from Eden IT | 2 | Plan A #2 |
| 3 | Create Slack app for Eden workspace | 3 | Plan 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.mdfor full descriptions.
| # | Ticket | Pts | Plan A ref |
|---|---|---|---|
| 4a | Design identity mapping schema and token convention | 3 | Plan A 4a |
| 4b | Build resolve_identity lookup function + seed mapping | 4 | Plan A 4b |
| 5a | Build core PII redaction function (email, name, phone) | 4 | Plan A 5a |
| 5b | Write PII redaction test fixtures and validation suite | 3 | Plan 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_gwsexecutes any allowedgwsCLI command and returns PII-redacted JSON;gws_schemalets 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 jsonviaexecFile(notexec— 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
- Accepts a CLI command string (e.g.
- 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
- Accepts an API method name (e.g.
- Build a command whitelist:
- Allowed services:
drive,gmail,calendar,admin,driveactivity:v2,sheets,docs - Read-only operations only — block
delete,update,send,insert,modify,trashsubcommands - Reject any command not matching the whitelist
- Allowed services:
- Unit tests: whitelist enforcement,
execFileargument construction, PII redaction on sample GWS outputs - Install
@googleworkspace/cliin 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 JSONrun_gws("gmail users messages delete", ...)is rejected by the whitelistrun_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), neverexec(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.comwith 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.comand 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_gwstools), 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_gwsandgws_schemaregistered as tools- Slack MCP tools connected as an MCP tool provider
pii_redactprocessor on all tool outputs
- Write the agent system prompt:
- GWS command reference: for each query type, the exact
gwscommand 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)
- GWS command reference: for each query type, the exact
- 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_gwscommands for Drive/Gmail/Calendar queries (can test with mock or Brainforge workspace) - Agent uses
gws_schemawhen 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 tsxor 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
gwscommand 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.md9b 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_gwstools), 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_gwsagainst each GWS API via DWD (with real Eden data once DWD is approved):- Drive search —
gws drive files listwith query, folder, MIME type filters - Drive Activity —
gws driveactivity:v2 activity queryfor folder/file audit trails - File comments —
gws drive comments listfor comment metadata and replies - Gmail —
gws gmail users messages list+gws gmail users messages getfor thread metadata - Calendar —
gws calendar events listfor event metadata, attendees, scheduling - Admin SDK —
gws admin directory users listfor org directory
- Drive search —
- 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_gwscommand for 10+ GWS query types
Out of scope
- Building individual tool functions (that’s Plan A)
- Cross-platform orchestration (Ticket B6)
Acceptance Criteria
run_gwssuccessfully 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" })
- “Search for documents about the rebrand” →
- 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.mdfor 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:
| Replace | With (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 modifications | Update 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
| Step | Plan A tickets | Plan A pts | Plan B tickets | Plan B pts | Notes |
|---|---|---|---|---|---|
| 1. Auth | 1, 2, 3 | 7 | 1, 2, 3 | 7 | Identical |
| 2. PII | 4a, 4b, 5a, 5b | 14 | 4a, 4b, 5a, 5b | 14 | Identical |
| 3. Slack tools | 6, 7, 8a, 8b | 14 | B2 | 3 | Slack MCP replaces 4 custom tools |
| 3. GWS generic tools | — | — | B1 | 5 | New: run_gws + whitelist |
| 3. Agent scaffold | 9a | 4 | B3 | 5 | B3 is +1 pt (more prompt engineering) |
| 3. Chat UI + deploy | 9b | 4 | B4 | 4 | Identical |
| 4. GWS surfaces | 10-16 | 23 | B5 | 5 | Biggest savings: 7 tickets → 1 |
| 5. Orchestration | 17 | 5 | B6 | 5 | Identical |
| 5. Deploy | 18 | 4 | B7 | 4 | Identical |
| Total | 18 tickets | 75 | 14 tickets | 52 | −23 pts (31%) |