Authors: MindsEye Development Team
Date: December 2025
Status: Reference Implementation
License: Internal Distribution
Executive Summary
This whitepaper presents MindsEye, a ledger-first cognitive architecture for enterprise AI systems, and MindScript, its declarative control language. Together, they form a complete operating system for traceable, auditable, and company-owned AI automation.
Unlike traditional AI systems built around conversational interfaces or black-box model outputs, MindsEye treats every decision as a ledger entry โ immutable, replayable, and provably ordered. MindScript provides the linguistic surface through which humans and systems express intent, constraints, and orchestration logic.
This document covers:
- Complete architectural specifications
- Repository-level implementation details
- Protocol definitions and message formats
- Real-world company deployment example with full metadata schema
- Security model and audit infrastructure
- Performance characteristics and scaling considerations
Target Audience: CTOs, Enterprise Architects, DevOps Engineers, Compliance Officers
Table of Contents
- Introduction & Motivation
- Core Architecture
- Repository Deep Dive
- MindScript Language Specification
- Ledger Protocol
- Integration Architecture
- Security & Compliance
- Real-World Implementation: Acme Operations Inc.
- Performance & Scaling
- Deployment Patterns
- Future Roadmap
1. Introduction & Motivation
1.1 The Problem with Traditional AI Systems
Modern AI systems suffer from fundamental architectural flaws:
Opacity of Decision Making
- No trace of why a decision was made
- Cannot replay past decisions with different parameters
- Impossible to audit reasoning chains
Output-Centric Design
- Systems optimized for generating text, not executing logic
- No separation between planning and action
- Side effects occur without permanent record
Vendor Lock-In
- Proprietary APIs control business logic
- Training data and usage patterns feed external models
- No path to internal ownership
Lack of Temporal Guarantees
- Cannot guarantee order of operations
- Race conditions between AI decisions and human actions
- No concept of "what was true at time T"
1.2 The MindsEye Solution
MindsEye inverts the traditional architecture:
Traditional AI: Prompt โ Model โ Output โ (Maybe) Action
MindsEye Architecture: Intent โ Ledger โ Execution โ Verification โ Ledger
Key Innovations:
- Ledger-First Execution: Every decision writes to an append-only log before any action occurs
- Temporal Provenance: All events carry causality chains back to initiating intent
- Separation of Concerns: Language (MindScript), Runtime (C++), Integration (Python), Storage (Ledger)
- Company Ownership: All components run on internal infrastructure with no external dependencies for core logic
1.3 Design Principles
Principle 1: Immutability
Once written, ledger entries never change. Corrections are new entries that reference previous ones.
Principle 2: Explicit Over Implicit
Every action must be declared. No hidden side effects. No "helpful" automations without explicit instruction.
Principle 3: Language as Control Surface
MindScript is not for chatting. It is a domain-specific language for expressing business logic in traceable form.
Principle 4: Multi-Language Runtime
C++ provides the kernel. Python provides expressiveness. JavaScript provides interfaces. Each layer has clear boundaries.
Principle 5: Replayability
Given a ledger at time T, the entire system state can be reconstructed. This enables:
- Debugging production incidents
- Testing "what if" scenarios
- Compliance audits with perfect fidelity
2. Core Architecture
2.1 System Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MindScript Layer โ
โ (Human/System Intent Expression) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MindScript Runtime (C++) โ
โ - Parse & Validate โ
โ - Stage Execution โ
โ - Recursion Control โ
โ - Ledger Writes โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MindsEye Ledger Core โ
โ - Append-Only Storage โ
โ - Event Ordering โ
โ - Cryptographic Chaining โ
โ - Causality Tracking โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโดโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ
โ Google โ โ Slack โ โ Internal โ
โ Gateway โ โ Gateway โ โ Systems โ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ
2.2 Data Flow Architecture
Write Path:
- MindScript intent received
- Runtime parses and validates syntax
- Runtime resolves dependencies and stages
- Ledger entry created (before execution)
- Execution occurs
- Outcome written to ledger
- Dependent stages triggered
Read Path:
- Query hits ledger-http service
- Authorization checked
- Ledger entries retrieved
- Events projected into view
- Response returned (read-only)
2.3 Component Boundaries
Hard Boundaries (Process Isolation):
- Runtime โ Ledger (IPC or HTTP)
- Runtime โ Executors (HTTP)
- Ledger โ External world (HTTP only)
Soft Boundaries (Library Interfaces):
- MindScript Parser โ Runtime
- Runtime โ Stage Resolvers
- Ledger โ Storage Backend
2.4 State Management
MindsEye maintains three types of state:
Ledger State (Immutable)
- All historical events
- Never modified
- Append-only growth
Projection State (Derived)
- Current system state computed from ledger
- Can be regenerated at any time
- Used for queries and dashboards
Execution State (Ephemeral)
- Active stage execution context
- In-memory only
- Discarded after completion
3. Repository Deep Dive
3.1 mindseye-protocol
Purpose: Constitutional layer defining system-wide contracts
Structure:
mindseye-protocol/
โโโ schemas/
โ โโโ message.proto # gRPC message definitions
โ โโโ ledger_event.proto # Event format specification
โ โโโ execution.proto # Stage execution contracts
โโโ docs/
โ โโโ protocol.md # Protocol specification
โ โโโ versioning.md # Compatibility guarantees
โ โโโ migration_guide.md # Version upgrade paths
โโโ examples/
โโโ basic_workflow.proto
โโโ multi_agent.proto
Key Specifications:
Message Format:
message MindsEyeMessage {
string message_id = 1; // UUID v7 (time-ordered)
string correlation_id = 2; // Links related messages
int64 timestamp_us = 3; // Microsecond precision
string source_component = 4; // Origin identifier
MessageType type = 5; // Enumerated type
bytes payload = 6; // Serialized content
map<string, string> metadata = 7; // Extensibility
}
Ledger Event Schema:
message LedgerEvent {
string event_id = 1; // Unique identifier
int64 sequence_number = 2; // Monotonic counter
string parent_event_id = 3; // Causality chain
int64 timestamp_us = 4; // Event time
string actor_id = 5; // Who/what caused this
EventType event_type = 6; // Classification
bytes event_data = 7; // Type-specific payload
string signature = 8; // Cryptographic proof
}
Version Compatibility:
- Protocol versions use semantic versioning
- Breaking changes require major version bump
- All components must support N and N-1 versions during transition
- Forward compatibility through unknown field preservation
3.2 mindseye-ledger-core
Purpose: Immutable event storage and retrieval
Language: C++17
Dependencies: RocksDB, OpenSSL, Protocol Buffers
Why C++ for the Ledger:
- Deterministic Memory Management: No garbage collection pauses
- Memory Safety: RAII patterns prevent leaks
- Performance: Sub-millisecond write latency required
- Portability: Runs on embedded systems to cloud servers
- Trust: Decades of production hardening
Architecture:
ledger-core/
โโโ include/
โ โโโ mindseye/
โ โโโ ledger.h # Primary interface
โ โโโ event.h # Event abstractions
โ โโโ storage.h # Storage interface
โ โโโ verifier.h # Integrity checking
โโโ src/
โ โโโ ledger.cc # Core implementation
โ โโโ rocksdb_storage.cc # Storage backend
โ โโโ memory_storage.cc # Testing backend
โ โโโ crypto.cc # Signing and verification
โโโ test/
โ โโโ ledger_test.cc
โ โโโ performance_test.cc
โ โโโ integrity_test.cc
โโโ bindings/
โโโ python/ # PyBind11 bindings
โโโ node/ # N-API bindings
Core API:
class Ledger {
public:
// Append event to ledger
Result<EventId> Append(const Event& event);
// Retrieve event by ID
Result<Event> GetEvent(const EventId& id);
// Get events in sequence range
Result<std::vector<Event>> GetRange(
SequenceNumber start,
SequenceNumber end
);
// Verify ledger integrity
Result<IntegrityReport> VerifyIntegrity();
// Create read-only snapshot
std::unique_ptr<Snapshot> CreateSnapshot();
};
Storage Backend (RocksDB):
- LSM tree optimized for append-heavy workloads
- Column families for different event types
- Bloom filters for fast event lookup
- Snappy compression for historical data
Integrity Guarantees:
- Append-Only: Write-once semantics enforced at filesystem level
- Cryptographic Chaining: Each event contains hash of previous event
- Merkle Trees: Periodic checkpoints create merkle roots for fast verification
- Signature Verification: Events carry digital signatures from authorized actors
Performance Characteristics:
- Write latency: <1ms (p99)
- Read latency: <100ฮผs (p99)
- Throughput: >100k events/sec (single node)
- Storage efficiency: ~500 bytes per event (compressed)
3.3 mindseye-ledger-http
Purpose: HTTP gateway to ledger for internal services
Language: Python 3.11+ (FastAPI)
Dependencies: FastAPI, uvicorn, pydantic, ledger-core (Python bindings)
Why Python Here:
- Rapid development of API contracts
- Rich ecosystem for HTTP services
- Type safety through Pydantic
- Easy integration with authentication systems
Endpoints:
# Read-only endpoints
GET /v1/events/{event_id}
GET /v1/events?start={seq}&end={seq}
GET /v1/events/search?query={...}
GET /v1/projections/{projection_name}
GET /v1/health
# Controlled write endpoints (admin only)
POST /v1/events/replay
POST /v1/snapshots
GET /v1/integrity/verify
Security Model:
class EndpointSecurity:
READ_EVENTS = ["user", "operator", "admin"]
WRITE_EVENTS = [] # No direct writes via HTTP
REPLAY = ["admin"]
SNAPSHOTS = ["operator", "admin"]
Rate Limiting:
- 1000 req/sec per API key (reads)
- 10 req/sec per API key (admin operations)
- Sliding window algorithm
- Separate limits for projections (more expensive)
3.4 mindscript-runtime-c
Purpose: Execute MindScript with strong guarantees
Language: C++20
Dependencies: ANTLR4 (parser), Boost (utilities), ledger-core
Why C++ for Runtime:
- Execution Guarantees: No undefined behavior in core paths
- Resource Limits: Hard caps on memory and CPU per execution
- Isolation: Each stage executes in constrained environment
- Performance: Hot paths must be microsecond-level fast
- Safety: Core logic too critical for interpreted languages
Architecture:
runtime/
โโโ grammar/
โ โโโ MindScript.g4 # ANTLR grammar definition
โโโ include/
โ โโโ mindscript/
โ โโโ runtime.h # Runtime interface
โ โโโ stage.h # Stage abstraction
โ โโโ executor.h # Execution engine
โ โโโ resolver.h # Dependency resolution
โโโ src/
โ โโโ parser.cc # Generated from ANTLR
โ โโโ runtime.cc # Main runtime logic
โ โโโ stage_executor.cc # Stage execution
โ โโโ builtin_functions.cc # Core functions
โ โโโ sandbox.cc # Execution isolation
โโโ bindings/
โโโ python/ # Primary user interface
Execution Model:
class StageExecutor {
struct ExecutionContext {
std::map<std::string, Value> variables;
std::vector<EventId> parent_events;
std::chrono::microseconds timeout;
size_t max_memory_bytes;
size_t recursion_depth;
};
Result<ExecutionResult> Execute(
const Stage& stage,
const ExecutionContext& ctx
);
};
Resource Limits:
constexpr size_t MAX_RECURSION_DEPTH = 10;
constexpr size_t MAX_MEMORY_PER_STAGE = 100 * 1024 * 1024; // 100MB
constexpr auto DEFAULT_TIMEOUT = std::chrono::seconds(30);
constexpr size_t MAX_STAGE_OUTPUT_SIZE = 10 * 1024 * 1024; // 10MB
Stage Types:
-
Ledger Stages: Write to ledger (e.g.,
ledger(...)) -
Task Stages: External actions (e.g.,
task generate_doc uses drive) -
Decision Stages: Conditional logic (e.g.,
if amount > 1000) -
Aggregation Stages: Combine multiple inputs (e.g.,
merge reports)
Dependency Resolution:
class DependencyGraph {
// Stages can depend on:
// - Previous stages in same script
// - Ledger events
// - External system state
Result<ExecutionPlan> Resolve(const Script& script);
// Guarantees:
// - No cycles
// - All dependencies satisfied before execution
// - Optimal parallelization where possible
};
3.5 mindscript-google-executor
Purpose: Translate MindScript intent to Google Workspace actions
Language: Python 3.11+
Dependencies: google-api-python-client, google-auth, mindseye-protocol
Why Python Here:
- Google's official client libraries are Python-first
- Rapid iteration on integration logic
- Rich error handling for API quirks
- Easy testing with mocks
Supported Actions:
# Gmail
GMAIL_SEND = "gmail.send"
GMAIL_SEARCH = "gmail.search"
GMAIL_LABEL = "gmail.label"
GMAIL_ARCHIVE = "gmail.archive"
# Drive
DRIVE_CREATE = "drive.create"
DRIVE_UPDATE = "drive.update"
DRIVE_SHARE = "drive.share"
DRIVE_MOVE = "drive.move"
# Docs
DOCS_CREATE = "docs.create"
DOCS_UPDATE = "docs.update"
DOCS_INSERT = "docs.insert_text"
# Sheets
SHEETS_CREATE = "sheets.create"
SHEETS_UPDATE = "sheets.update_range"
SHEETS_APPEND = "sheets.append_row"
# Calendar
CAL_CREATE = "calendar.create_event"
CAL_UPDATE = "calendar.update_event"
CAL_DELETE = "calendar.delete_event"
Execution Flow:
class GoogleExecutor:
def execute_stage(self, stage: Stage) -> ExecutionResult:
# 1. Validate stage has required parameters
self._validate(stage)
# 2. Resolve Google API method
api_method = self._resolve_method(stage.action)
# 3. Write intent to ledger
intent_event = self.ledger.append(
event_type="INTENT",
data=stage.to_dict()
)
# 4. Execute API call
try:
result = api_method(**stage.parameters)
except GoogleAPIError as e:
# Write failure to ledger
self.ledger.append(
event_type="FAILURE",
parent=intent_event.id,
data={"error": str(e)}
)
raise
# 5. Write success to ledger
self.ledger.append(
event_type="SUCCESS",
parent=intent_event.id,
data={"result": result}
)
return ExecutionResult(success=True, data=result)
Error Handling:
- Exponential backoff for rate limits
- Automatic retry for transient failures
- Dead letter queue for persistent failures
- All errors logged to ledger with full context
3.6 mindseye-google-auth
Purpose: Secure OAuth flow management
Language: Python 3.11+
Dependencies: google-auth-oauthlib, google-auth-httplib2
Key Features:
- Scoped Permissions: Each automation requests minimal scopes
- Token Rotation: Automatic refresh before expiration
- Multi-Account: Support for multiple Google Workspace domains
- Audit Trail: All auth events written to ledger
OAuth Flow:
class GoogleAuthManager:
def initiate_auth(self, scopes: List[str]) -> AuthURL:
"""Generate OAuth URL for user consent"""
def exchange_code(self, code: str) -> Credentials:
"""Exchange authorization code for tokens"""
def refresh_token(self, refresh_token: str) -> Credentials:
"""Get new access token"""
def revoke_token(self, token: str) -> None:
"""Revoke access token"""
Stored Token Format:
{
"user_id": "user_123",
"token_id": "token_456",
"access_token": "ya29...",
"refresh_token": "1//...",
"token_uri": "https://oauth2.googleapis.com/token",
"scopes": ["https://www.googleapis.com/auth/gmail.send"],
"expiry": "2025-12-16T15:30:00Z",
"created_at": "2025-12-15T10:00:00Z"
}
3.7 mindseye-google-gateway
Purpose: Mediate all Google API access
Language: Python 3.11+ (FastAPI)
Dependencies: FastAPI, google-api-python-client, mindseye-protocol
Why a Gateway:
- Rate Limit Management: Single point of control
- Quota Tracking: Monitor API usage across all automations
- Policy Enforcement: Block disallowed operations
- Logging: Central audit trail
- Caching: Reduce redundant API calls
Gateway Architecture:
class GoogleGateway:
# Upstream: MindScript executors
# Downstream: Google APIs
def proxy_request(self, request: APIRequest) -> APIResponse:
# 1. Validate request against policy
if not self.policy.allows(request):
raise PolicyViolation()
# 2. Check rate limits
if not self.rate_limiter.allow(request.user_id):
raise RateLimitExceeded()
# 3. Check cache
if cached := self.cache.get(request.cache_key):
return cached
# 4. Forward to Google API
response = self.google_client.execute(request)
# 5. Log to ledger
self.ledger.append(
event_type="GOOGLE_API_CALL",
data={
"method": request.method,
"user_id": request.user_id,
"latency_ms": response.latency,
"status": response.status
}
)
# 6. Cache if appropriate
if request.cacheable:
self.cache.set(request.cache_key, response)
return response
Policy Example:
policies:
- name: "No External Sharing"
rule: |
if action == "drive.share" and
recipient not in @company.com:
deny
- name: "Finance Sheet Protection"
rule: |
if action == "sheets.update" and
sheet_id in [finance_sheets]:
require_role: "finance_admin"
4. MindScript Language Specification
4.1 Design Goals
- Declarative: Express intent, not implementation
- Traceable: Every statement has ledger representation
- Composable: Small scripts combine into workflows
- Type-Safe: Catch errors before execution
- Domain-Specific: Optimized for automation, not general programming
4.2 Syntax Overview
Basic Structure:
# Comment
stage_name action parameters [after dependencies]
Example:
# Book revenue and generate invoice
record ledger(debit:AR, credit:Revenue, amount:1200 USD)
invoice task generate_invoice uses drive after record
send email send_invoice to client@company.com after invoice
4.3 Core Language Elements
Ledger Operations:
ledger(debit:account_name, credit:account_name, amount:value currency)
ledger(event:event_type, data:{key:value, ...})
ledger_query(filter:{conditions}, limit:n)
Task Invocations:
task task_name uses service_name [with params] [after dependencies]
# Examples:
task generate_contract uses drive with template:"contract_v2"
task send_notification uses slack with channel:"#ops"
task analyze_data uses internal_api with dataset:"sales_q4"
Conditional Logic:
if condition:
stages...
else:
stages...
# Example:
if amount > 10000:
task escalate uses slack with channel:"#exec"
else:
task process_normally uses internal
Variables:
set var_name = expression
set total = amount * 1.08 # With tax
set recipients = ["alice@co.com", "bob@co.com"]
Aggregation:
aggregate output_name from stage_pattern [where condition]
# Example:
aggregate monthly_totals from sales_* where date > "2025-12-01"
4.4 Type System
Primitive Types:
-
string: UTF-8 text -
number: 64-bit float -
integer: 64-bit signed int -
boolean: true/false -
currency: Decimal with currency code (e.g.,100.50 USD) -
date: ISO 8601 date -
datetime: ISO 8601 datetime with timezone
Composite Types:
-
list<T>: Ordered collection -
map<K,V>: Key-value pairs -
record{field:type, ...}: Structured data
Example with Types:
set invoice_data:record{
client: string,
amount: currency,
due_date: date,
line_items: list<record{desc:string, qty:integer, price:currency}>
} = {
client: "Acme Corp",
amount: 1200.00 USD,
due_date: 2025-12-31,
line_items: [
{desc: "Consulting", qty: 10, price: 120.00 USD}
]
}
4.5 Execution Semantics
Stage Execution Order:
- Dependency Resolution: Build DAG of stage dependencies
- Parallel Execution: Stages with no interdependencies run concurrently
- Ledger Write: Each stage writes intent before execution
- Action Execution: External action performed
- Outcome Record: Result written to ledger
- Downstream Trigger: Dependent stages notified
Atomicity:
- Each stage is atomic: either fully completes or fully fails
- No partial stage execution
- Failures propagate to dependents unless explicitly caught
Idempotency:
- Stages can be retried safely
- Ledger prevents duplicate events via correlation IDs
- External actions must be idempotent or include retry logic
4.6 Standard Library
Built-in Functions:
# String operations
concat(s1, s2, ...)
substring(s, start, length)
uppercase(s)
lowercase(s)
# Date/time
now()
date_add(date, duration)
date_diff(date1, date2)
# Math
abs(n)
round(n, decimals)
sum(list)
avg(list)
# Collections
length(list)
filter(list, predicate)
map(list, function)
contains(list, item)
# Ledger
ledger_query(filter)
ledger_latest(event_type)
ledger_count(filter)
4.7 Error Handling
try:
stage might_fail task risky_operation uses external
rescue error:
stage handle_error task notify_admin uses slack with error:$error
finally:
stage cleanup task close_resources uses internal
4.8 Advanced Features
Loops:
for item in items:
stage process_$item task process uses internal with data:$item
Macro Expansion:
macro send_notification(recipient, message):
task notify_$recipient uses slack with to:$recipient, msg:$message
end
# Usage:
send_notification("alice", "Process complete")
Imports:
import common.ledger_macros
import finance.accounting_stages
# Use imported definitions
common.record_transaction(...)
5. Ledger Protocol
5.1 Event Structure
Every event in the ledger follows this canonical structure:
{
"event_id": "01JEZE4N3N4QTHXNK6VJ2M8WXY",
"sequence_number": 123456,
"parent_event_id": "01JEZE3M2M3PSGWNJ5UI1L7VWX",
"timestamp": "2025-12-16T14:30:00.123456Z",
"actor": {
"type": "user|system|automation",
"id": "user_123",
"session_id": "session_456"
},
"event_type": "STAGE_INTENT",
"data": {
"stage_name": "generate_invoice",
"action": "task",
"service": "drive",
"parameters": {...}
},
"metadata": {
"script_id": "script_789",
"correlation_id": "corr_012",
"tags": ["finance", "automated"]
},
"signature": "SHA256:a3f2c1..."
}
5.2 Event Types
Core Event Types:
STAGE_INTENT - MindScript stage about to execute
STAGE_SUCCESS - Stage completed successfully
STAGE_FAILURE - Stage failed with error
LEDGER_WRITE - Direct ledger operation
EXTERNAL_CALL - API call to external system
EXTERNAL_RESULT - Response from external system
DECISION_POINT - Conditional branch taken
AGGREGATION - Multiple events combined
REPLAY_START - Ledger replay initiated
REPLAY_END - Ledger replay completed
Domain-Specific Event Types:
FINANCE_TRANSACTION
HR_ONBOARDING_STEP
LEGAL_CONTRACT_SIGNED
OPS_DEPLOYMENT_START
5.3 Causality Chains
Every event carries its causal history:
{
"event_id": "E5",
"parent_event_id": "E4",
"causality_chain": ["E1", "E2", "E3", "E4"],
"root_cause": "E1"
}
This enables:
- "Why did this happen?" queries
- Impact analysis ("What resulted from X?")
- Replay from any point
- Debugging complex workflows
5.4 Cryptographic Integrity
Chaining:
Event N signature = SHA256(
Event N data +
Event N-1 signature
)
Merkle Trees:
Every 1000 events, a merkle root is computed:
Checkpoint:
sequence_range: [1000, 2000]
merkle_root: "abc123..."
signed_by: "ledger_authority"
timestamp: "2025-12-16T14:00:00Z"
5.5 Projection Queries
Ledger events can be projected into various views:
Account Balances (Financial Projection):
SELECT
account,
SUM(CASE WHEN type='debit' THEN amount ELSE -amount END) as balance
FROM ledger_events
WHERE event_type = 'LEDGER_WRITE'
GROUP BY account
System State (Operational Projection):
SELECT
resource_id,
MAX(timestamp) as last_modified,
JSON_EXTRACT(data, '$.state') as current_state
FROM ledger_events
WHERE event_type
# MindsEye Implementation Guide
## Real-World Deployment: Acme Operations Inc.
**Company Profile:**
Acme Operations Inc. - Professional Services Firm
**Founded:** 2020
**Employees:** 42
**Annual Revenue:** $6.2M
**Tech Stack:** Google Workspace, Slack, QuickBooks Online
**Use Case:** Contract management, invoicing, HR onboarding, project tracking
---
## Table of Contents
1. [Company Background & Requirements](#company-background)
2. [Infrastructure Setup](#infrastructure-setup)
3. [Complete Metadata Schema](#metadata-schema)
4. [User Roles & Permissions](#user-roles)
5. [Automation Workflows](#automation-workflows)
6. [Deployment Steps](#deployment-steps)
7. [Operational Procedures](#operational-procedures)
8. [Monitoring & Maintenance](#monitoring)
---
## 1. Company Background & Requirements {#company-background}
### 1.1 Business Context
**Services Provided:**
- Management consulting
- Technical implementation
- Training and workshops
- Ongoing advisory
**Pain Points Before MindsEye:**
1. Manual contract generation (2-3 hours per contract)
2. Invoice errors and delays (15% error rate)
3. Inconsistent onboarding (new hires confused first week)
4. No audit trail for financial decisions
5. Siloed information across tools
**Goals for MindsEye Implementation:**
- Reduce contract generation to 15 minutes
- Zero invoice errors through automation
- Standardize onboarding with traceable checklist
- Full audit trail for compliance
- Unified view of company operations
### 1.2 Technical Requirements
**Performance:**
- <5 second response time for automation triggers
- 99.9% uptime for ledger service
- Support 200+ automation runs per day
- Handle 10k+ ledger events per day
**Security:**
- SOC 2 Type II compliance path
- Data encryption at rest and in transit
- Role-based access control
- No data leaves company infrastructure
**Integration:**
- Google Workspace (Gmail, Drive, Docs, Sheets, Calendar)
- QuickBooks Online (for financial sync)
- Slack (for notifications)
- Internal project management database
### 1.3 Compliance Requirements
**Financial Audit Trail:**
- Every transaction traceable to source
- Immutable record of all financial decisions
- Support for replaying past states
- 7-year retention requirement
**HR Compliance:**
- I-9 verification tracking
- Background check workflow
- Training completion records
- Time-to-hire metrics
**Legal:**
- Contract version control
- E-signature integration
- Document retention policies
- Change history for all contracts
---
## 2. Infrastructure Setup {#infrastructure-setup}
### 2.1 Hardware Specification
**Primary Server (Internal)**
yaml
Role: MindsEye Core + Ledger
Location: On-premise (office server room)
Hardware:
CPU: AMD Ryzen 9 5950X (16 cores)
RAM: 128 GB DDR4
Storage:
- 2TB NVMe SSD (ledger + hot data)
- 16TB HDD RAID 10 (cold storage)
Network: 10 Gbps internal, 1 Gbps WAN
OS: Ubuntu 22.04 LTS
Backup: Nightly to offsite cloud storage
**Backup Server (Cloud)**
yaml
Role: Disaster recovery + read replicas
Provider: AWS
Instance: r6i.2xlarge
Storage:
- EBS gp3 2TB (encrypted)
- S3 for ledger archives Region: us-east-1 (primary), us-west-2 (replica)
### 2.2 Network Architecture
Internet
|
โโ Cloudflare (DDoS protection + CDN)
|
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Company Firewall โ
โ - VPN gateway โ
โ - IDS/IPS โ
โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโ
โ
โผ
Internal Network (10.0.0.0/24)
โ
โโ MindsEye Server (10.0.0.10)
โโ Database Server (10.0.0.11)
โโ Backup Server (10.0.0.12)
โโ Employee Workstations (10.0.0.100-199)
### 2.3 Software Stack
**Core Components:**
yaml
Ledger Service:
Binary: /opt/mindseye/bin/ledger-core
Config: /etc/mindseye/ledger.yaml
Data: /var/lib/mindseye/ledger/
Logs: /var/log/mindseye/ledger/
Service: systemd (mindseye-ledger.service)
Port: 8001 (internal only)
Runtime Service:
Binary: /opt/mindseye/bin/runtime
Config: /etc/mindseye/runtime.yaml
Scripts: /var/lib/mindseye/scripts/
Logs: /var/log/mindseye/runtime/
Service: systemd (mindseye-runtime.service)
Port: 8002 (internal only)
Ledger HTTP Gateway:
Type: Python FastAPI
Path: /opt/mindseye/services/ledger-http/
Config: /etc/mindseye/ledger-http.yaml
Service: systemd (mindseye-http.service)
Port: 8080 (authenticated access)
Google Gateway:
Type: Python FastAPI
Path: /opt/mindseye/services/google-gateway/
Config: /etc/mindseye/google-gateway.yaml
Service: systemd (mindseye-google-gateway.service)
Port: 8081 (internal only)
**Supporting Services:**
yaml
PostgreSQL:
Version: 15
Purpose: User management, permissions, metadata
Database: mindseye_meta
Port: 5432
Redis:
Version: 7.2
Purpose: Cache, rate limiting, session management
Port: 6379
Prometheus:
Version: 2.45
Purpose: Metrics collection
Port: 9090
Grafana:
Version: 10.0
Purpose: Dashboards and alerting
Port: 3000
### 2.4 Deployment Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ User Layer โ
โ - Web Interface (React) โ
โ - CLI Tools (Python) โ
โ - Slack Integrations โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ API Gateway Layer โ
โ - Authentication (OAuth 2.0 + JWT) โ
โ - Rate Limiting โ
โ - Request Validation โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโดโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Runtime โ โ Ledger โ โ Google โ
โ Service โโโโโโโโโโถโ Service โโโโโ Gateway โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ External Services โ
โ - Google Workspace โ
โ - QuickBooks โ
โ - Slack โ
โโโโโโโโโโโโโโโโโโโโโโโ
---
## 3. Complete Metadata Schema {#metadata-schema}
### 3.1 Core Schema
**Users Table:**
sql
CREATE TABLE users (
user_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
display_name VARCHAR(100) NOT NULL,
role VARCHAR(50) NOT NULL, -- 'admin', 'operator', 'user', 'readonly'
department VARCHAR(50),
hire_date DATE,
status VARCHAR(20) DEFAULT 'active', -- 'active', 'suspended', 'terminated'
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}',
INDEX idx_users_email (email),
INDEX idx_users_role (role),
INDEX idx_users_status (status)
);
-- Sample data
INSERT INTO users VALUES
('550e8400-e29b-41d4-a716-446655440001', 'sarah@acmeops.com', 'Sarah Chen', 'admin', 'Operations', '2020-01-15', 'active'),
('550e8400-e29b-41d4-a716-446655440002', 'mike@acmeops.com', 'Mike Rodriguez', 'operator', 'Finance', '2020-03-01', 'active'),
('550e8400-e29b-41d4-a716-446655440003', 'jessica@acmeops.com', 'Jessica Liu', 'operator', 'HR', '2021-06-15', 'active'),
('550e8400-e29b-41d4-a716-446655440004', 'tom@acmeops.com', 'Tom Anderson', 'user', 'Consulting', '2022-01-10', 'active');
**Automations Table:**
sql
CREATE TABLE automations (
automation_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
description TEXT,
script_content TEXT NOT NULL,
script_hash VARCHAR(64) NOT NULL, -- SHA256 of script
created_by UUID REFERENCES users(user_id),
version INTEGER DEFAULT 1,
status VARCHAR(20) DEFAULT 'draft', -- 'draft', 'active', 'paused', 'archived'
trigger_type VARCHAR(50), -- 'manual', 'scheduled', 'event', 'webhook'
trigger_config JSONB,
execution_count INTEGER DEFAULT 0,
last_execution_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}',
INDEX idx_automations_status (status),
INDEX idx_automations_created_by (created_by),
INDEX idx_automations_trigger_type (trigger_type)
);
-- Sample automation
INSERT INTO automations VALUES
(
'650e8400-e29b-41d4-a716-446655440001',
'Generate Monthly Invoice',
'Automatically generate and send monthly invoices to active clients',
'set client = $input.client_id
set amount = query_hours(client) * rate(client)
record ledger(debit:AR, credit:Revenue, amount:amount, client:client)
invoice task generate_invoice uses drive with template:"invoice_v3" after record
send email send_invoice to client.email after invoice',
'a7f3c2e1...',
'550e8400-e29b-41d4-a716-446655440002',
1,
'active',
'scheduled',
'{"schedule": "0 0 1 * *", "timezone": "America/Los_Angeles"}',
0,
NULL,
NOW(),
NOW(),
'{"tags": ["finance", "invoicing"], "priority": "high"}'
);
**Execution History Table:**
sql
CREATE TABLE execution_history (
execution_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID REFERENCES automations(automation_id),
triggered_by UUID REFERENCES users(user_id),
trigger_source VARCHAR(50), -- 'manual', 'schedule', 'event', 'api'
status VARCHAR(20) NOT NULL, -- 'pending', 'running', 'success', 'failed', 'cancelled'
started_at TIMESTAMPTZ DEFAULT NOW(),
completed_at TIMESTAMPTZ,
duration_ms INTEGER,
-- Ledger integration
root_event_id VARCHAR(100), -- First ledger event created
event_count INTEGER DEFAULT 0, -- Total ledger events created
-- Execution details
input_data JSONB,
output_data JSONB,
error_message TEXT,
error_stack TEXT,
-- Resource usage
stages_executed INTEGER DEFAULT 0,
api_calls_made INTEGER DEFAULT 0,
metadata JSONB DEFAULT '{}',
INDEX idx_execution_automation (automation_id),
INDEX idx_execution_status (status),
INDEX idx_execution_started (started_at),
INDEX idx_execution_trigger (trigger_source)
);
**Ledger Events Metadata Table:**
sql
CREATE TABLE ledger_events_meta (
event_id VARCHAR(100) PRIMARY KEY, -- References ledger-core event ID
execution_id UUID REFERENCES execution_history(execution_id),
event_type VARCHAR(50) NOT NULL,
actor_id UUID REFERENCES users(user_id),
indexed_at TIMESTAMPTZ DEFAULT NOW(),
-- Searchable fields extracted from event data
tags TEXT[],
client_id VARCHAR(100),
project_id VARCHAR(100),
amount NUMERIC(12,2),
currency CHAR(3),
-- Full-text search
searchable_text TEXT,
INDEX idx_ledger_event_type (event_type),
INDEX idx_ledger_execution (execution_id),
INDEX idx_ledger_actor (actor_id),
INDEX idx_ledger_indexed (indexed_at),
INDEX idx_ledger_tags USING GIN(tags),
INDEX idx_ledger_search USING GIN(to_tsvector('english', searchable_text))
);
**Google Workspace Integrations:**
sql
CREATE TABLE google_integrations (
integration_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(user_id),
google_user_email VARCHAR(255) NOT NULL,
scopes TEXT[] NOT NULL,
-- OAuth tokens (encrypted at application level)
access_token_encrypted TEXT NOT NULL,
refresh_token_encrypted TEXT NOT NULL,
token_expires_at TIMESTAMPTZ NOT NULL,
-- Integration metadata
created_at TIMESTAMPTZ DEFAULT NOW(),
last_used_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
status VARCHAR(20) DEFAULT 'active', -- 'active', 'expired', 'revoked'
metadata JSONB DEFAULT '{}',
INDEX idx_google_user (user_id),
INDEX idx_google_status (status),
INDEX idx_google_expires (token_expires_at)
);
**API Keys Table:**
sql
CREATE TABLE api_keys (
key_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(user_id),
key_name VARCHAR(100) NOT NULL,
key_hash VARCHAR(64) NOT NULL, -- SHA256 of the actual key
key_prefix VARCHAR(10) NOT NULL, -- First 8 chars for identification
permissions JSONB NOT NULL, -- {"read": true, "write": false, "admin": false}
rate_limit_per_hour INTEGER DEFAULT 1000,
created_at TIMESTAMPTZ DEFAULT NOW(),
last_used_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
status VARCHAR(20) DEFAULT 'active',
metadata JSONB DEFAULT '{}',
INDEX idx_apikey_user (user_id),
INDEX idx_apikey_hash (key_hash),
INDEX idx_apikey_status (status)
);
**Audit Log Table:**
sql
CREATE TABLE audit_log (
log_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
timestamp TIMESTAMPTZ DEFAULT NOW(),
actor_id UUID REFERENCES users(user_id),
action VARCHAR(100) NOT NULL,
resource_type VARCHAR(50) NOT NULL,
resource_id VARCHAR(100),
-- Change tracking
before_state JSONB,
after_state JSONB,
-- Context
ip_address INET,
user_agent TEXT,
session_id VARCHAR(100),
-- Ledger correlation
related_event_id VARCHAR(100),
metadata JSONB DEFAULT '{}',
INDEX idx_audit_timestamp (timestamp),
INDEX idx_audit_actor (actor_id),
INDEX idx_audit_action (action),
INDEX idx_audit_resource (resource_type, resource_id)
);
### 3.2 Domain-Specific Schemas
**Finance Domain:**
sql
CREATE TABLE finance_accounts (
account_id VARCHAR(50) PRIMARY KEY,
account_name VARCHAR(100) NOT NULL,
account_type VARCHAR(20) NOT NULL, -- 'asset', 'liability', 'equity', 'revenue', 'expense'
parent_account_id VARCHAR(50) REFERENCES finance_accounts(account_id),
quickbooks_id VARCHAR(50),
is_active BOOLEAN DEFAULT true,
metadata JSONB DEFAULT '{}'
);
CREATE TABLE finance_transactions (
transaction_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
ledger_event_id VARCHAR(100) NOT NULL, -- Links to ledger
transaction_date DATE NOT NULL,
description TEXT,
total_amount NUMERIC(12,2) NOT NULL,
currency CHAR(3) DEFAULT 'USD',
client_id VARCHAR(100),
project_id VARCHAR(100),
reconciled BOOLEAN DEFAULT false,
reconciled_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'
);
CREATE TABLE finance_transaction_lines (
line_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
transaction_id UUID REFERENCES finance_transactions(transaction_id),
account_id VARCHAR(50) REFERENCES finance_accounts(account_id),
line_type VARCHAR(10) NOT NULL, -- 'debit', 'credit'
amount NUMERIC(12,2) NOT NULL,
memo TEXT
);
**HR Domain:**
sql
CREATE TABLE hr_onboarding (
onboarding_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
employee_id UUID REFERENCES users(user_id),
start_date DATE NOT NULL,
status VARCHAR(20) DEFAULT 'pending', -- 'pending', 'in_progress', 'completed', 'cancelled'
-- Checklist
documents_submitted BOOLEAN DEFAULT false,
background_check_completed BOOLEAN DEFAULT false,
equipment_assigned BOOLEAN DEFAULT false,
accounts_created BOOLEAN DEFAULT false,
training_completed BOOLEAN DEFAULT false,
-- Automation tracking
automation_run_count INTEGER DEFAULT 0,
last_automation_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'
);
CREATE TABLE hr_onboarding_tasks (
task_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
onboarding_id UUID REFERENCES hr_onboarding(onboarding_id),
task_name VARCHAR(100) NOT NULL,
task_description TEXT,
assigned_to UUID REFERENCES users(user_id),
due_date DATE,
status VARCHAR(20) DEFAULT 'pending',
completed_at TIMESTAMPTZ,
ledger_event_id VARCHAR(100), -- Task completion recorded in ledger
metadata JSONB DEFAULT '{}'
);
**Legal/Contract Domain:**
sql
CREATE TABLE contracts (
contract_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_number VARCHAR(50) UNIQUE NOT NULL,
client_id VARCHAR(100) NOT NULL,
contract_type VARCHAR(50) NOT NULL, -- 'consulting', 'retainer', 'project', 'advisory'
-- Document tracking
drive_file_id VARCHAR(100), -- Google Drive file ID
signed_file_id VARCHAR(100), -- Signed version
template_version VARCHAR(20),
-- Contract details
start_date DATE NOT NULL,
end_date DATE,
value NUMERIC(12,2),
currency CHAR(3) DEFAULT 'USD',
-- Status
status VARCHAR(20) DEFAULT 'draft', -- 'draft', 'sent', 'signed', 'active', 'completed', 'terminated'
signed_at TIMESTAMPTZ,
signed_by VARCHAR(255),
-- Automation
generated_by_automation BOOLEAN DEFAULT false,
generation_event_id VARCHAR(100),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'
);
CREATE TABLE contract_versions (
version_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_id UUID REFERENCES contracts(contract_id),
version_number INTEGER NOT NULL,
drive_file_id VARCHAR(100),
changed_by UUID REFERENCES users(user_id),
change_description TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(contract_id, version_number)
);
---
## 4. User Roles & Permissions {#user-roles}
### 4.1 Role Definitions
yaml
roles:
admin:
description: "Full system access"
permissions:
- all:*
members:
- sarah@acmeops.com
operator:
description: "Create and manage automations in their domain"
permissions:
- automations:create
- automations:read
- automations:update:own
- automations:execute
- ledger:read
- google:integrate
members:
- mike@acmeops.com (finance)
- jessica@acmeops.com (hr)
user:
description: "Execute existing automations"
permissions:
- automations:read
- automations:execute:approved
- ledger:read:own
members:
- tom@acmeops.com
- [35 other consultants]
readonly:
description: "View-only access for auditors"
permissions:
- automations:read
- ledger:read
- audit:read
members:
- auditor@external.com
### 4.2 Permission Matrix
| Action | Admin | Operator | User | Readonly |
|--------|-------|----------|------|----------|
| Create automation | โ | โ | โ | โ |
| Edit any automation | โ | โ | โ | โ |
| Edit own automation | โ | โ | โ | โ |
| Execute automation | โ | โ | โ* | โ |
| View ledger (all) | โ | โ | โ | โ |
| View ledger (own) | โ | โ | โ | โ |
| Manage users | โ | โ | โ | โ |
| View audit logs | โ | โ | โ | โ |
| Replay ledger | โ | โ | โ | โ |
| Integrate Google | โ | โ | โ | โ |
*Users can only execute automations marked as "approved"
### 4.3 Scope-Based Permissions
python
Python permission checking example
class PermissionChecker:
def can_execute_automation(self, user: User, automation: Automation) -> bool:
# Admins can execute anything
if user.role == "admin":
return True
# Operators can execute in their department
if user.role == "operator":
if automation.department == user.department:
return True
# Users can execute approved automations
if user.role == "user":
if automation.status == "active" and automation.approved:
return True
return False
def can_read_ledger_event(self, user: User, event: LedgerEvent) -> bool:
# Admins and readonly can see everything
if user.role in ["admin", "readonly"]:
return True
# Operators can see events in their department
if user.role == "operator":
if event.metadata.get("department") == user.department:
return True
# Users can only see their own events
if user.role == "user":
if event.actor_id == user.user_id:
return True
return False
---
## 5. Automation Workflows {#automation-workflows}
### 5.1 Contract Generation Workflow
**Trigger:** New client project approved
**Owner:** Operations team
**Frequency:** 5-10x per week
**MindScript:**
mindscript
Contract Generation Automation
Owner: sarah@acmeops.com
Version: 3.2
Input validation
require $input.client_id
require $input.project_type
require $input.value
require $input.start_date
Step 1: Record intent in ledger
intent ledger(
event:CONTRACT_GENERATION_START,
client_id:$input.client_id,
project_type:$input.project_type,
value:$input.value
)
Step 2: Fetch client details from internal database
client_data task fetch_client uses internal_api with client_id:$input.client_id after intent
set client_name = client_data.result.name
set client_email = client_data.result.primary_contact
set client_address = client_data.result.billing_address
Step 3: Determine contract template
set template_name = "consulting_standard"
if $input.project_type == "retainer":
set template_name = "retainer_agreement"
else if $input.value > 100000:
set template_name = "consulting_enterprise"
Step 4: Generate contract from template
contract task generate_contract uses drive with {
template: template_name,
client_name: client_name,
client_address: client_address,
project_type: $input.project_type,
start_date: $input.start_date,
value: $input.value,
currency: "USD",
folder_id: "contracts_2025"
} after client_data
set contract_file_id = contract.result.file_id
set contract_url = contract.result.web_url
Step 5: Record contract in database
db_record task create_contract_record uses internal_api with {
contract_number: generate_contract_number(),
client_id: $input.client_id,
drive_file_id: contract_file_id,
value: $input.value,
start_date: $input.start_date,
status: "draft",
generated_by_automation: true,
generation_event_id: intent.event_id
} after contract
Step 6: Write to ledger
complete ledger(
event:CONTRACT_GENERATED,
contract_id: db_record.result.contract_id,
contract_number: db_record.result.contract_number,
file_id: contract_file_id
) after db_record
Step 7: Notify operations team
notification task send_slack uses slack with {
channel: "#operations",
message: "New contract generated for {{client_name}}: {{contract_url}}",
thread_key: $input.client_id
} after complete
Step 8: Send email to client (if requested)
if $input.send_to_client == true:
email task send_contract_email uses gmail with {
to: client_email,
subject: "Contract for {{project_type}} Services",
body_template: "contract_draft_email",
attachments: [contract_file_id]
} after notification
**Execution Metrics (Production Data):**
- Average execution time: 12.3 seconds
- Success rate: 98.7%
- Manual intervention required: 1.3%
- Contracts generated per month: 45
- Time saved vs manual: 2.5 hours per contract
### 5.2 Monthly Invoicing Workflow
**Trigger:** First day of month (automated)
**Owner:** Finance team
**Frequency:** Monthly
**MindScript:**
mindscript
Monthly Client Invoicing
Owner: mike@acmeops.com
Version: 2.1
Schedule: 0 9 1 * * (9 AM on 1st of month)
Step 1: Query active clients
clients task get_active_clients uses internal_api
Step 2: For each client, calculate hours and generate invoice
for client in clients.result:
# Query timesheet data
hours_{{client.id}} task query_hours uses internal_api with {
client_id: client.id,
start_date: first_day_of_last_month(),
end_date: last_day_of_last_month()
}
# Skip if no billable hours
if hours_{{client.id}}.result.total_hours == 0:
continue
# Calculate amount
set rate = client.hourly_rate
set hours = hours_{{client.id}}.result.total_hours
set subtotal = hours * rate
set tax = subtotal * 0.08 # 8% tax
set total = subtotal + tax
# Step 3: Record financial transaction in ledger
transaction_{{client.id}} ledger(
debit:AR,
credit:Revenue,
amount: total USD,
client_id: client.id,
month: format_date(last_month(), "YYYY-MM"),
hours: hours
) after hours_{{client.id}}
# Step 4: Generate invoice document
invoice_{{client.id}} task generate_invoice uses drive with {
template: "invoice_v4",
client_name: client.name,
client_address: client.billing_address,
invoice_number: generate_invoice_number(client.id),
invoice_date: today(),
due_date: date_add(today(), 30 days),
line_items: hours_{{client.id}}.result.breakdown,
subtotal: subtotal,
tax: tax,
total: total,
folder_id: "invoices_2025"
} after transaction_{{client.id}}
# Step 5: Send invoice via email
email_{{client.id}} task send_invoice uses gmail with {
to: client.billing_email,
cc: "accounting@acmeops.com",
subject: "Invoice {{invoice_number}} - {{month}}",
body_template: "invoice_email",
attachments: [invoice_{{client.id}}.result.file_id]
} after invoice_{{client.id}}
# Step 6: Record in QuickBooks
qb_{{client.id}} task sync_to_quickbooks uses quickbooks with
graph TB
subgraph "User Layer"
WebUI[Web Interface
React Dashboard]
CLI[CLI Tools
Python]
Slack[Slack Bot]
end
subgraph "API Gateway Layer"
Auth[Authentication Service<br/>OAuth 2.0 + JWT]
RateLimit[Rate Limiter<br/>Redis]
Validator[Request Validator]
end
subgraph "Core Services"
Runtime[MindScript Runtime<br/>C++ Engine]
LedgerCore[Ledger Core<br/>C++ / RocksDB]
LedgerHTTP[Ledger HTTP<br/>FastAPI]
end
subgraph "Integration Layer"
GoogleGW[Google Gateway<br/>Python]
GoogleAuth[Google Auth<br/>OAuth Manager]
GoogleExec[Google Executor<br/>API Client]
SlackGW[Slack Gateway]
InternalAPI[Internal API Gateway]
end
subgraph "External Services"
Gmail[Gmail API]
Drive[Google Drive API]
Docs[Google Docs API]
Sheets[Google Sheets API]
SlackAPI[Slack API]
QuickBooks[QuickBooks API]
end
subgraph "Data Layer"
Postgres[(PostgreSQL<br/>Metadata)]
Redis[(Redis<br/>Cache/Sessions)]
RocksDB[(RocksDB<br/>Ledger Storage)]
end
subgraph "Monitoring"
Prometheus[Prometheus<br/>Metrics]
Grafana[Grafana<br/>Dashboards]
ELK[ELK Stack<br/>Logs]
end
%% User connections
WebUI --> Auth
CLI --> Auth
Slack --> Auth
%% Auth flow
Auth --> RateLimit
RateLimit --> Validator
Validator --> Runtime
Validator --> LedgerHTTP
%% Runtime connections
Runtime --> LedgerCore
Runtime --> GoogleGW
Runtime --> SlackGW
Runtime --> InternalAPI
%% Google integration flow
GoogleGW --> GoogleAuth
GoogleGW --> GoogleExec
GoogleExec --> Gmail
GoogleExec --> Drive
GoogleExec --> Docs
GoogleExec --> Sheets
%% External integrations
SlackGW --> SlackAPI
InternalAPI --> QuickBooks
%% Data layer connections
LedgerCore --> RocksDB
LedgerHTTP --> LedgerCore
Runtime --> Postgres
Auth --> Postgres
GoogleAuth --> Postgres
RateLimit --> Redis
%% Monitoring connections
Runtime -.->|metrics| Prometheus
LedgerCore -.->|metrics| Prometheus
GoogleGW -.->|metrics| Prometheus
Prometheus --> Grafana
Runtime -.->|logs| ELK
LedgerCore -.->|logs| ELK
GoogleGW -.->|logs| ELK
style LedgerCore fill:#ff6b6b
style Runtime fill:#4ecdc4
style GoogleGW fill:#45b7d1
style Auth fill:#ffa07a
style RocksDB fill:#ff6b6b
graph TB
subgraph "Internet"
Users[Users]
Mobile[Mobile Clients]
end
subgraph "Edge Layer"
CF[Cloudflare<br/>DDoS Protection<br/>CDN]
end
subgraph "DMZ"
FW[Firewall<br/>IDS/IPS]
VPN[VPN Gateway]
LB[Load Balancer<br/>Nginx]
end
subgraph "Application Tier - Primary Server"
subgraph "Core Services"
Runtime1[Runtime<br/>:8002]
Ledger1[Ledger Core<br/>:8001]
HTTP1[Ledger HTTP<br/>:8080]
end
subgraph "Gateway Services"
GoogleGW1[Google Gateway<br/>:8081]
Auth1[Auth Service<br/>:8085]
end
subgraph "Support Services"
Redis1[(Redis<br/>:6379)]
Postgres1[(PostgreSQL<br/>:5432)]
end
end
subgraph "Monitoring Tier"
Prometheus[Prometheus<br/>:9090]
Grafana[Grafana<br/>:3000]
Elasticsearch[Elasticsearch<br/>:9200]
Kibana[Kibana<br/>:5601]
end
subgraph "Backup Server - Cloud"
subgraph "Replica Services"
Ledger2[Ledger Core<br/>Read Replica]
Postgres2[(PostgreSQL<br/>Read Replica)]
end
subgraph "Backup Storage"
S3[S3 Buckets<br/>Encrypted]
Glacier[Glacier<br/>Long-term]
end
end
subgraph "External Services"
Google[Google Workspace<br/>APIs]
Slack[Slack API]
QB[QuickBooks<br/>Online]
end
subgraph "Storage Tier"
NAS[Network Attached<br/>Storage]
LocalDisk[Local SSD<br/>2TB]
ColdStorage[HDD Array<br/>16TB RAID 10]
end
%% User connections
Users --> CF
Mobile --> CF
CF --> FW
FW --> LB
VPN --> FW
%% Application tier connections
LB --> HTTP1
LB --> Auth1
HTTP1 --> Ledger1
Runtime1 --> Ledger1
Runtime1 --> GoogleGW1
GoogleGW1 --> Auth1
%% Data connections
Ledger1 --> LocalDisk
Runtime1 --> Postgres1
Auth1 --> Postgres1
Runtime1 --> Redis1
Auth1 --> Redis1
%% External integrations
GoogleGW1 --> Google
Runtime1 --> Slack
Runtime1 --> QB
%% Monitoring
Runtime1 -.->|metrics| Prometheus
Ledger1 -.->|metrics| Prometheus
GoogleGW1 -.->|metrics| Prometheus
Prometheus --> Grafana
Runtime1 -.->|logs| Elasticsearch
Elasticsearch --> Kibana
%% Backup & replication
Ledger1 -.->|replicate| Ledger2
Postgres1 -.->|stream| Postgres2
Ledger1 -.->|backup| NAS
Ledger1 -.->|backup| S3
LocalDisk -.->|archive| ColdStorage
S3 -.->|archive| Glacier
%% Styling
style FW fill:#ff6b6b
style Ledger1 fill:#ff6b6b
style Runtime1 fill:#4ecdc4
style S3 fill:#ffa07a
style Prometheus fill:#95e1d3
=============================================================================
MINDSCRIPT WORKFLOW LIBRARY
Complete collection of production-ready automation workflows
=============================================================================
=============================================================================
1. HR ONBOARDING WORKFLOW
=============================================================================
Trigger: New employee starts
Owner: HR Department
Frequency: 3-5x per month
Duration: ~45 seconds
=============================================================================
automation employee_onboarding:
description: "Complete new employee onboarding process"
version: "2.3"
owner: "jessica@acmeops.com"
department: "HR"
# Input validation
require $input.employee_email
require $input.employee_name
require $input.department
require $input.start_date
require $input.manager_email
require $input.job_title
# Step 1: Record onboarding start in ledger
onboard_start ledger(
event: ONBOARDING_START,
employee_email: $input.employee_email,
employee_name: $input.employee_name,
start_date: $input.start_date,
department: $input.department
)
# Step 2: Create employee record in database
employee_record task create_employee uses internal_api with {
email: $input.employee_email,
display_name: $input.employee_name,
department: $input.department,
hire_date: $input.start_date,
manager_email: $input.manager_email,
job_title: $input.job_title,
role: "user",
status: "pending"
} after onboard_start
set employee_id = employee_record.result.employee_id
# Step 3: Create Google Workspace account
google_account task create_google_account uses google_admin with {
email: $input.employee_email,
first_name: split($input.employee_name, " ")[0],
last_name: split($input.employee_name, " ")[1],
organizational_unit: "/Employees/{{department}}",
password: generate_secure_password(),
change_password_at_next_login: true
} after employee_record
# Step 4: Create personal Drive folder structure
drive_setup task create_folder_structure uses drive with {
root_folder_name: "{{employee_name}} - Personal",
subfolders: ["Documents", "Projects", "Training", "Performance Reviews"],
share_with: [$input.employee_email, $input.manager_email],
permission: "editor"
} after google_account
set personal_folder_id = drive_setup.result.root_folder_id
# Step 5: Generate offer letter and employment contract
contract_docs task generate_onboarding_docs uses drive with {
template_ids: ["offer_letter_template", "employee_contract_template"],
output_folder: personal_folder_id,
variables: {
employee_name: $input.employee_name,
job_title: $input.job_title,
department: $input.department,
start_date: format_date($input.start_date, "MMMM D, YYYY"),
manager_name: get_user_name($input.manager_email),
salary: $input.salary,
benefits_summary: get_benefits_template($input.job_level)
}
} after drive_setup
# Step 6: Create onboarding checklist in Sheets
checklist task create_onboarding_checklist uses sheets with {
spreadsheet_name: "Onboarding - {{employee_name}}",
folder_id: personal_folder_id,
checklist_items: [
"Complete I-9 verification",
"Sign employee handbook acknowledgment",
"Complete tax withholding forms (W-4)",
"Enroll in benefits (health, dental, 401k)",
"Setup direct deposit",
"Complete security training",
"Complete compliance training",
"Setup development environment",
"Meet with manager for 30-day goals",
"Schedule 30-day check-in"
],
share_with: [$input.employee_email, $input.manager_email, "hr@acmeops.com"]
} after contract_docs
# Step 7: Assign to department groups and mailing lists
groups task add_to_groups uses google_admin with {
employee_email: $input.employee_email,
groups: [
"all-employees@acmeops.com",
"{{department}}@acmeops.com",
"{{department}}-team@acmeops.com"
]
} after google_account
# Step 8: Request equipment from IT
equipment task request_equipment uses internal_api with {
employee_id: employee_id,
equipment_type: determine_equipment($input.job_title),
items: [
"Laptop - {{laptop_model}}",
"Monitor - 27 inch",
"Keyboard and mouse",
"Headset with microphone",
"Webcam (if remote)"
],
delivery_date: $input.start_date,
shipping_address: $input.home_address or "Office"
} after employee_record
# Step 9: Create Slack account and add to channels
slack_setup task setup_slack uses slack with {
email: $input.employee_email,
display_name: $input.employee_name,
title: $input.job_title,
department: $input.department,
channels: [
"#general",
"#announcements",
"#{{department}}",
"#random"
],
user_groups: ["@{{department}}-team"]
} after google_account
# Step 10: Schedule orientation meetings
meetings task schedule_orientation uses calendar with {
employee_email: $input.employee_email,
meetings: [
{
title: "Welcome & Company Overview",
duration: 60 minutes,
attendees: ["hr@acmeops.com", $input.manager_email],
date: $input.start_date,
time: "9:00 AM"
},
{
title: "IT Setup & Security Training",
duration: 90 minutes,
attendees: ["it@acmeops.com"],
date: $input.start_date,
time: "10:30 AM"
},
{
title: "Team Introduction",
duration: 60 minutes,
attendees: get_team_members($input.department),
date: $input.start_date,
time: "2:00 PM"
},
{
title: "30-Day Check-In",
duration: 60 minutes,
attendees: [$input.manager_email, "hr@acmeops.com"],
date: date_add($input.start_date, 30 days),
time: "10:00 AM"
}
]
} after slack_setup
# Step 11: Send welcome email package
welcome_email task send_welcome_email uses gmail with {
to: $input.employee_email,
cc: $input.manager_email,
bcc: "hr@acmeops.com",
subject: "Welcome to Acme Operations!",
body_template: "welcome_email_template",
variables: {
employee_name: $input.employee_name,
start_date: format_date($input.start_date, "MMMM D, YYYY"),
manager_name: get_user_name($input.manager_email),
personal_folder_link: drive_setup.result.folder_url,
checklist_link: checklist.result.spreadsheet_url,
first_day_agenda: meetings.result.first_day_calendar_url
},
attachments: [
contract_docs.result.offer_letter_id,
get_document_id("employee_handbook"),
get_document_id("benefits_guide")
]
} after meetings
# Step 12: Notify manager and HR
notifications task send_notifications uses slack with {
messages: [
{
channel: $input.manager_email,
text: "New team member {{employee_name}} onboarding initiated. Start date: {{start_date}}. Checklist: {{checklist_link}}"
},
{
channel: "#hr-operations",
text: "Onboarding started for {{employee_name}} ({{department}}). Employee ID: {{employee_id}}"
},
{
channel: "#it-requests",
text: "Equipment request submitted for {{employee_name}}. Delivery by {{start_date}}"
}
]
} after welcome_email
# Step 13: Record completion in ledger
onboard_complete ledger(
event: ONBOARDING_COMPLETE,
employee_id: employee_id,
employee_email: $input.employee_email,
google_account_created: google_account.result.success,
drive_folder_id: personal_folder_id,
checklist_id: checklist.result.spreadsheet_id,
equipment_request_id: equipment.result.request_id,
welcome_email_sent: welcome_email.result.success,
duration_seconds: elapsed_time(onboard_start)
) after notifications
# Return summary
return {
employee_id: employee_id,
google_email: $input.employee_email,
personal_folder_url: drive_setup.result.folder_url,
checklist_url: checklist.result.spreadsheet_url,
onboarding_event_id: onboard_complete.event_id
}
end
=============================================================================
2. PROJECT KICKOFF WORKFLOW
=============================================================================
Trigger: New project approved
Owner: Operations
Frequency: 5-8x per month
Duration: ~30 seconds
=============================================================================
automation project_kickoff:
description: "Initialize new client project with all necessary resources"
version: "1.8"
owner: "sarah@acmeops.com"
department: "Operations"
require $input.project_name
require $input.client_id
require $input.project_manager_email
require $input.start_date
require $input.estimated_hours
require $input.hourly_rate
# Step 1: Record project creation
project_start ledger(
event: PROJECT_CREATED,
project_name: $input.project_name,
client_id: $input.client_id,
project_manager: $input.project_manager_email,
estimated_value: $input.estimated_hours * $input.hourly_rate
)
# Step 2: Create project record in database
project_record task create_project uses internal_api with {
project_name: $input.project_name,
client_id: $input.client_id,
project_manager: $input.project_manager_email,
start_date: $input.start_date,
estimated_hours: $input.estimated_hours,
hourly_rate: $input.hourly_rate,
status: "active",
created_from_automation: true
} after project_start
set project_id = project_record.result.project_id
# Step 3: Create project folder structure in Drive
project_drive task create_project_folders uses drive with {
root_folder_name: "{{project_name}} - {{client_name}}",
subfolders: [
"01 - Planning & Requirements",
"02 - Design & Architecture",
"03 - Development",
"04 - Testing & QA",
"05 - Deployment",
"06 - Documentation",
"07 - Client Deliverables",
"08 - Internal Notes"
],
parent_folder: get_client_folder($input.client_id),
share_with: [
{email: $input.project_manager_email, role: "writer"},
{email: get_client_contact($input.client_id), role: "reader"}
]
} after project_record
set project_folder_id = project_drive.result.root_folder_id
# Step 4: Create project tracking spreadsheet
tracking_sheet task create_tracking_sheet uses sheets with {
spreadsheet_name: "Project Tracker - {{project_name}}",
folder_id: project_folder_id,
sheets: [
{
name: "Overview",
headers: ["Metric", "Value"],
data: [
["Project Name", $input.project_name],
["Client", get_client_name($input.client_id)],
["Project Manager", $input.project_manager_email],
["Start Date", $input.start_date],
["Estimated Hours", $input.estimated_hours],
["Hourly Rate", $input.hourly_rate],
["Estimated Value", $input.estimated_hours * $input.hourly_rate]
]
},
{
name: "Time Tracking",
headers: ["Date", "Team Member", "Hours", "Description", "Billable"]
},
{
name: "Milestones",
headers: ["Milestone", "Due Date", "Status", "Owner", "Notes"]
},
{
name: "Budget",
headers: ["Category", "Budgeted", "Actual", "Variance", "Notes"]
},
{
name: "Risks",
headers: ["Risk", "Probability", "Impact", "Mitigation", "Owner"]
}
],
share_with: [$input.project_manager_email, "finance@acmeops.com"]
} after project_drive
# Step 5: Create Slack channel for project
slack_channel task create_slack_channel uses slack with {
channel_name: "proj-{{sanitize(project_name)}}",
description: "Project: {{project_name}} | Client: {{client_name}}",
is_private: false,
members: [
$input.project_manager_email,
get_client_success_manager($input.client_id),
"operations@acmeops.com"
],
channel_topic: "Status: Kickoff | PM: {{project_manager_email}}"
} after project_record
# Step 6: Create initial project documents
project_docs task generate_project_docs uses drive with {
documents: [
{
template: "project_charter_template",
name: "Project Charter - {{project_name}}",
folder: project_folder_id + "/01 - Planning & Requirements",
variables: {
project_name: $input.project_name,
client_name: get_client_name($input.client_id),
pm_name: get_user_name($input.project_manager_email),
start_date: format_date($input.start_date, "MMMM D, YYYY"),
scope: $input.scope_summary,
objectives: $input.objectives
}
},
{
template: "statement_of_work_template",
name: "Statement of Work - {{project_name}}",
folder: project_folder_id + "/07 - Client Deliverables",
variables: {
project_name: $input.project_name,
client_name: get_client_name($input.client_id),
deliverables: $input.deliverables,
timeline: $input.timeline,
estimated_hours: $input.estimated_hours,
rate: $input.hourly_rate
}
},
{
template: "risk_register_template",
name: "Risk Register - {{project_name}}",
folder: project_folder_id + "/01 - Planning & Requirements"
}
]
} after project_drive
# Step 7: Schedule kickoff meetings
kickoff_meetings task schedule_kickoff_meetings uses calendar with {
meetings: [
{
title: "Internal Project Kickoff - {{project_name}}",
duration: 60 minutes,
attendees: [
$input.project_manager_email,
"operations@acmeops.com",
get_team_members_for_project(project_id)
],
date: $input.start_date,
time: "9:00 AM",
description: "Review project scope, timeline, and team assignments",
location: "Conference Room A / Zoom"
},
{
title: "Client Kickoff - {{project_name}}",
duration: 90 minutes,
attendees: [
$input.project_manager_email,
get_client_contact($input.client_id),
get_client_stakeholders($input.client_id)
],
date: $input.start_date,
time: "2:00 PM",
description: "Project introduction, goals alignment, and next steps",
location: "Zoom",
add_zoom_link: true
},
{
title: "Weekly Status Meeting - {{project_name}}",
duration: 30 minutes,
attendees: [
$input.project_manager_email,
get_client_contact($input.client_id)
],
recurring: "weekly",
start_date: $input.start_date,
day_of_week: "Friday",
time: "10:00 AM"
}
]
} after slack_channel
# Step 8: Create project tasks/milestones
if $input.milestones:
milestones task create_milestones uses internal_api with {
project_id: project_id,
milestones: $input.milestones
} after project_record
# Step 9: Send kickoff email to team
team_email task send_team_notification uses gmail with {
to: [
$input.project_manager_email,
get_team_members_for_project(project_id)
],
cc: "operations@acmeops.com",
subject: "New Project: {{project_name}}",
body_template: "project_kickoff_email",
variables: {
project_name: $input.project_name,
client_name: get_client_name($input.client_id),
pm_name: get_user_name($input.project_manager_email),
start_date: format_date($input.start_date, "MMMM D, YYYY"),
project_folder_link: project_drive.result.folder_url,
tracking_sheet_link: tracking_sheet.result.spreadsheet_url,
slack_channel: slack_channel.result.channel_name,
kickoff_meeting_link: kickoff_meetings.result.internal_meeting_url
}
} after kickoff_meetings
# Step 10: Send client welcome email
client_email task send_client_welcome uses gmail with {
to: get_client_contact($input.client_id),
cc: $input.project_manager_email,
subject: "Welcome! Project {{project_name}} Kickoff",
body_template: "client_project_kickoff",
variables: {
client_name: get_client_name($input.client_id),
project_name: $input.project_name,
pm_name: get_user_name($input.project_manager_email),
pm_email: $input.project_manager_email,
kickoff_meeting: kickoff_meetings.result.client_meeting_details,
shared_folder_link: project_drive.result.client_accessible_folder_url
},
attachments: [
project_docs.result.statement_of_work_id
]
} after team_email
# Step 11: Post to Slack channels
slack_announcements task post_slack_updates uses slack with {
messages: [
{
channel: "#operations",
text: "๐ New project launched: {{project_name}} | Client: {{client_name}} | PM: {{pm_name}} | Channel: {{slack_channel}}"
},
{
channel: slack_channel.result.channel_id,
text: "Welcome to the project channel! ๐\n\n*Project*: {{project_name}}\n*Client*: {{client_name}}\n*PM*: {{pm_name}}\n\n๐ Project Folder\n๐ Tracking Sheet\n๐
Kickoff meeting: {{kickoff_date}}"
}
]
} after client_email
# Step 12: Record completion
project_complete ledger(
event: PROJECT_KICKOFF_COMPLETE,
project_id: project_id,
project_folder_id: project_folder_id,
tracking_sheet_id: tracking_sheet.result.spreadsheet_id,
slack_channel_id: slack_channel.result.channel_id,
kickoff_meetings_scheduled: kickoff_meetings.result.meeting_count,
duration_seconds: elapsed_time(project_start)
) after slack_announcements
return {
project_id: project_id,
project_folder_url: project_drive.result.folder_url,
tracking_sheet_url: tracking_sheet.result.spreadsheet_url,
slack_channel: slack_channel.result.channel_name,
event_id: project_complete.event_id
}
end
=============================================================================
3. EXPENSE APPROVAL WORKFLOW
=============================================================================
Trigger: Employee submits expense report
Owner: Finance
Frequency: 50-100x per month
Duration: ~20 seconds (auto-approve) or waiting for manager
=============================================================================
automation expense_approval:
description: "Process and approve employee expense reports"
version: "3.1"
owner: "mike@acmeops.com"
department: "Finance"
require $input.employee_email
require $input.expense_amount
require $input.expense_category
require $input.expense_date
require $input.description
require $input.receipt_file_ids # Array of Drive file IDs
# Step 1: Record expense submission
expense_submit ledger(
event: EXPENSE_SUBMITTED,
employee_email: $input.employee_email,
amount: $input.expense_amount,
category: $input.expense_category,
date: $input.expense_date
)
# Step 2: Get employee and manager info
employee_info task get_employee_info uses internal_api with {
email: $input.employee_email
} after expense_submit
set employee_id = employee_info.result.employee_id
set manager_email = employee_info.result.manager_email
set department = employee_info.result.department
# Step 3: Validate expense against policy
policy_check task validate_expense_policy uses internal_api with {
employee_id: employee_id,
category: $input.expense_category,
amount: $input.expense_amount,
date: $input.expense_date,
has_receipt: length($input.receipt_file_ids) > 0
} after employee_info
# Step 4: Determine approval workflow based on amount and policy
set requires_manager_approval = $input.expense_amount > 500 or policy_check.result.requires_approval
set requires_finance_approval = $input.expense_amount > 2000
# Branch 1: Auto-approve small expenses
if not requires_manager_approval and policy_check.result.compliant:
auto_approve task auto_approve_expense uses internal_api with {
employee_id: employee_id,
amount: $input.expense_amount,
category: $input.expense_category,
approved_by: "system",
reason: "Auto-approved: Under limit and policy compliant"
} after policy_check
approve_ledger ledger(
event: EXPENSE_APPROVED,
employee_id: employee_id,
amount: $input.expense_amount,
approved_by: "system",
approval_type: "automatic"
) after auto_approve
notify_employee task notify_approval uses gmail with {
to: $input.employee_email,
subject: "Expense Approved: ${{expense_amount}}",
body_template: "expense_approved_auto",
variables: {
amount: $input.expense_amount,
category: $input.expense_category,
date: $input.expense_date,
reimbursement_date: calculate_reimbursement_date()
}
} after approve_ledger
# Queue for reimbursement
reimburse_queue task add_to_reimbursement_queue uses internal_api with {
employee_id: employee_id,
amount: $input.expense_amount,
payment_method: employee_info.result.payment_method,
scheduled_date: calculate_reimbursement_date()
} after auto_approve
# Branch 2: Require manager approval
else if requires_manager_approval:
# Request manager approval
manager_request task request_manager_approval uses gmail with {
to: manager_email,
subject: "Expense Approval Needed: {{employee_name}} - ${{expense_amount}}",
body_template: "expense_approval_request",
variables: {
employee_name: employee_info.result.display_name,
amount: $input.expense_amount,
category: $input.expense_category,
date: format_date($input.expense_date, "MMMM D, YYYY"),
description: $input.description,
receipt_links: generate_receipt_links($input.receipt_file_ids),
approval_link: generate_approval_link(expense_submit.event_id),
rejection_link: generate_rejection_link(expense_submit.event_id)
},
priority: "high"
} after policy_check
# Also notify in Slack
slack_notify task notify_manager_slack uses slack with {
channel: manager_email,
text: "Expense approval needed from {{employee_name}}: ${{amount}} ({{category}})",
blocks: [
{
type: "section",
text: "*Expense Details*\nAmount: ${{amount}}\nCategory: {{category}}\nEmployee: {{employee_name}}"
},
{
type: "actions",
elements: [
{type: "button", text: "Approve", action_id: "approve_expense", value: expense_submit.event_id},
{type: "button", text: "Reject", action_id: "reject_expense", value: expense_submit.event_id, style: "danger"}
]
}
]
} after manager_request
# Wait for approval (this creates a pending state)
# The system will resume when manager clicks approve/reject
wait_approval await manager_approval for expense_id:expense_submit.event_id timeout:7 days
# Process approval
if wait_approval.result.approved:
manager_approve ledger(
event: EXPENSE_APPROVED,
employee_id: employee_id,
amount: $input.expense_amount,
approved_by: manager_email,
approval_type: "manager",
comments: wait_approval.result.comments
) after wait_approval
# Check if finance approval also needed
if requires_finance_approval:
finance_request task request_finance_approval uses gmail with {
to: "finance@acmeops.com",
cc: manager_email,
subject: "Finance Approval Needed: ${{expense_amount}}",
body_template: "expense_finance_approval_request"
} after manager_approve
wait_finance await finance_approval for expense_id:expense_submit.event_id timeout:5 days
if wait_finance.result.approved:
finance_approve ledger(
event: EXPENSE_APPROVED,
employee_id: employee_id,
amount: $input.expense_amount,
approved_by: wait_finance.result.approved_by_email,
approval_type: "finance"
) after wait_finance
else:
# Finance rejected
finance_reject ledger(
event: EXPENSE_REJECTED,
employee_id: employee_id,
rejected_by: wait_finance.result.rejected_by_email,
reason: wait_finance.result.rejection_reason
) after wait_finance
notify_rejection task notify_finance_rejection uses gmail with {
to: $input.employee_email,
cc: manager_email,
subject: "Expense Not Approved: ${{expense_amount}}",
body_template: "expense_rejected_finance"
} after finance_reject
return {
status: "rejected",
rejected_by: "finance",
reason: wait_finance.result.rejection_reason
}
# Notify employee of approval
notify_approved task notify_employee_approved uses gmail with {
to: $input.employee_email,
cc: manager_email,
subject: "Expense Approved: ${{expense_amount}}",
body_template: "expense_approved_manager"
} after manager_approve
# Add to reimbursement queue
reimburse_queue task add_to_reimbursement_queue uses internal_api with {
employee_id: employee_id,
amount: $input.expense_amount,
approved_by: manager_email
} after notify_approved
else:
# Manager rejected
manager_reject ledger(
event: EXPENSE_REJECTED,
employee_id: employee_id,
rejected_by: manager_email,
reason: wait_approval.result.rejection_reason
) after wait_approval
notify_rejection task notify_employee_rejected uses gmail with {
to: $input.employee_email,
subject: "Expense Not Approved: ${{expense_amount}}",
body_template: "expense_rejected_manager",
variables: {
reason: wait_approval.result.rejection_reason,
manager_name: get_user_name(manager_email)
}
} after manager_reject
return {
status: "rejected",
rejected_by: "manager",
reason: wait_approval.result.rejection_reason
}
# Step 5: Record in QuickBooks
qb_record task sync_to_quickbooks uses quickbooks with {
transaction_type: "expense",
employee_id: employee_id,
amount: $input.expense_amount,
category: map_category_to_qb($input.expense_category),
date: $input.expense_date,
description: $input.description,
attachments: $input.receipt_file_ids
} after reimburse_queue
# Step 6: Update expense tracking sheet
tracking_update task update_expense_tracker uses sheets with {
spreadsheet_id: get_expense_tracking_sheet_id(),
sheet_name: "Expenses {{year}}",
append_row: [
$input.expense_date,
employee_info.result.display_name,
department,
$input.expense_category,
$input.expense_amount,
"Approved",
manager_email or "Auto-approved",
calculate_reimbursement_date(),
expense_submit.event_id
]
} after qb_record
# Step 7: Final ledger entry
expense_complete ledger(
event: EXPENSE_PROCESSING_COMPLETE,
employee_id: employee_id,
expense_amount: $input.expense_amount,
qb_transaction_id: qb_record.result.transaction_id,
reimbursement_scheduled: true,
duration_seconds: elapsed_time(expense_submit)
) after tracking_update
return {
status: "approved",
expense_id: expense
Top comments (0)