vibe coded with โค๏ธ

Documentation

How Changy evaluates change plans, and how to configure it.

Concept app. A working exploration of an idea, built and shared to show what's possible โ€” not a supported commercial product. Expect rough edges, no SLA and no roadmap guarantees. It has been tested in a demo environment only, not in production. Try it on test Macs first; feedback is very welcome.

Overview

Changy ingests a company's change-management policy, a draft change plan, and any supporting documents or codebases; evaluates the plan for gaps against a rubric derived from that policy (or a generic ITIL v4 checklist if no policy is supplied); helps fill those gaps through a follow-up interview; and generates audience-specific communications for end users, management, stakeholders, and colleagues.

Version 0.1.0: evaluation, interview, and communications generation are verified end to end with real runs against the bundled model. The Jira, Confluence, Jamf Pro, and Intune integrations, plus web search, are unit-tested against mocked responses only โ€” not yet validated against real instances. See the status section on the product page for the full picture.

Requirements

  • macOS 26 (Tahoe) or later
  • Apple Silicon, if using the bundled on-device model (no restriction if using an OpenAI-compatible API backend instead)
  • ~4.3GB free space for the bundled Qwen2.5-7B-Instruct (4-bit) model, already inside the signed app โ€” no first-run download

Installation

Download Changy (a 3.6 GB .zip โ€” most of that is the bundled on-device model), then:

  1. Unzip it
  2. Drag Changy.app to /Applications
  3. Open it

Signed and notarized with a Developer ID Application certificate โ€” Gatekeeper opens it normally, no right-click-to-open workaround needed.

Try It With the Examples

Two example documents, built to exercise the full evaluate โ†’ interview โ†’ enrich pipeline end to end, are available to download below โ€” they aren't bundled inside the app download itself, so grab them separately:

company-policy-example.md

A fictional company's IT change-management policy with 7 concrete, checkable criteria โ€” risk assessment, backout plan, testing, CAB approval, change window, communication, and post-implementation review.

โฌ‡ Download company-policy-example.md

draft-change-plan-example.md

A deliberately incomplete draft change plan (a Jamf Pro upgrade) that satisfies some of that policy's criteria and is missing others, so a real evaluation run has genuine gaps to find.

โฌ‡ Download draft-change-plan-example.md

Add the policy file as the Company Policy document and the draft plan as the Draft Change Plan:

Changy Documents screen with company-policy-example.md and draft-change-plan-example.md added
Documents โ€” both example files added.

Run an evaluation. Against this pair, a real run scores it 2 of 7 criteria satisfied (Risk Assessment, Testing), 1 partially satisfied (CAB Approval โ€” the plan states the risk level but never mentions sign-off), and 4 missing (Backout Plan, Change Window, Communication, Post-Implementation Review) โ€” each finding cites the specific part of the plan it's based on:

Changy Evaluation screen: 2 of 7 required criteria satisfied, 1 partially satisfied, 4 missing, each with a specific citation
Evaluation โ€” cited, specific findings against the policy-derived rubric.

The Interview screen turns each gap into a concrete follow-up question. Answer them, apply the answers, and the plan is revised in place:

Changy confirmation screen shown after applying interview answers to the draft plan
Interview โ€” answers applied, plan updated.
The draft change plan document after enrichment, with new Backout Plan, CAB Approval, Communication, and Post-Implementation Review sections merged in
The same document afterward โ€” all four gaps closed, merged directly into the plan.

From there, Communications generates an audience-appropriate write-up in one click โ€” see the feature grid above for an example.

How Configuration Works

Every setting has three possible sources, checked in this order:

  1. MDM-forced โ€” pushed via a Configuration Profile's Managed Preferences payload. The app detects a value was actually forced by an administrator (not just present) via CFPreferencesAppValueIsForced, and locks the corresponding control in Settings with the usual "set by your organization" treatment.
  2. User Settings โ€” whatever the user set in-app, stored in standard UserDefaults.
  3. Built-in default โ€” used if neither of the above set a value (e.g. the local MLX backend, or every integration off).

Any MDM โ€” Jamf, Kandji, Intune, or a manually installed profile โ€” can push this configuration. It's an "Application" / custom-preferences payload of type com.apple.ManagedClient.preferences, targeting the app's bundle identifier, com.spectrechen.changy, as the domain.

Configuration Reference

Every key Changy reads, exactly as it appears in the shipped configuration schema:

KeyTypeDefaultPurpose
forcedBackendStringmlxWhich LLM backend to use: mlx or openAICompatible
openAICompatibleBaseURLStringhttps://api.openai.com/v1Base URL for the OpenAI-compatible backend
openAICompatibleAPIKeyStringemptyAPI key for that endpoint
openAICompatibleModelNameStringgpt-4o-miniModel name to request
webSearchEnabledBool*falseAllow evaluation to check claims via Brave Search
braveSearchAPIKeyStringemptyBrave Search API key
jiraEnabledBool*falseEnable the Jira lookup tool
jiraBaseURL / jiraEmail / jiraAPITokenStringemptyJira connection details (see below)
confluenceEnabledBool*falseEnable the Confluence lookup tool
confluenceBaseURL / confluenceEmail / confluenceAPITokenStringemptyConfluence connection details (see below)
jamfEnabledBool*falseEnable the Jamf Pro lookup tool
jamfBaseURL / jamfClientID / jamfClientSecretStringemptyJamf Pro API client credentials
intuneEnabledBool*falseEnable the Microsoft Intune lookup tool
intuneTenantID / intuneClientID / intuneClientSecretStringemptyIntune app registration credentials

* Booleans are pushed as the literal string "true" or "false" in the profile, not a plist <true/>/<false/> โ€” Managed Preferences values are read as strings.

Security Note

Managed Preferences are plaintext. Any value pushed this way โ€” API keys, client secrets โ€” lands in /Library/Managed Preferences/com.spectrechen.changy.plist as plaintext, readable by anyone with defaults read access to that Mac. This is an accepted tradeoff for an enterprise-managed, FileVault-encrypted fleet, not a secrets vault. Only push real secrets this way on devices you already trust for that purpose, and only force the keys you actually want centrally controlled โ€” omit anything you want users or Settings to keep control of.

Local Model (MLX)

The default backend. A bundled, 4-bit-quantized Qwen2.5-7B-Instruct model runs entirely on-device via Apple's MLX framework โ€” no first-run download, fully offline. This is what forcedBackend: mlx selects, and it's the default if the key isn't set at all.

Changy Settings screen showing LLM Backend, OpenAI-Compatible Backend, and Web Search options
Settings โ€” the same backend and web search options a Configuration Profile can also force.

OpenAI-Compatible API

Point Changy at any OpenAI-compatible endpoint instead โ€” useful for centralizing on an org-wide model deployment rather than the bundled local one.

<key>forcedBackend</key>
<string>openAICompatible</string>

<key>openAICompatibleBaseURL</key>
<string>https://api.openai.com/v1</string>

<key>openAICompatibleAPIKey</key>
<string>sk-...</string>

<key>openAICompatibleModelName</key>
<string>gpt-4o-mini</string>

Jira & Confluence

Off by default, independently toggled. Both share the same two-field auth shape: leave *Email blank for a Data Center instance (the token is used as a Bearer PAT), or fill it in for Cloud (Basic auth with the token as an API token).

<key>jiraEnabled</key>
<string>true</string>
<key>jiraBaseURL</key>
<string>https://yourcompany.atlassian.net</string>
<key>jiraEmail</key>
<string>you@yourcompany.com</string>
<key>jiraAPIToken</key>
<string>...</string>

<key>confluenceEnabled</key>
<string>true</string>
<key>confluenceBaseURL</key>
<string>https://yourcompany.atlassian.net/wiki</string>
<key>confluenceEmail</key>
<string>you@yourcompany.com</string>
<key>confluenceAPIToken</key>
<string>...</string>
Changy Settings screen showing Web Search, Jira, and Confluence configuration, all off by default
Settings โ€” Web Search, Jira, and Confluence, each independently toggled.

Jamf Pro

Authenticates the same way Jarl does โ€” a Jamf Pro API Role and API Client (client ID + secret), configured under Settings โ†’ System โ†’ API Roles and Clients in Jamf Pro.

<key>jamfEnabled</key>
<string>true</string>
<key>jamfBaseURL</key>
<string>https://yourcompany.jamfcloud.com</string>
<key>jamfClientID</key>
<string>...</string>
<key>jamfClientSecret</key>
<string>...</string>

Microsoft Intune

Uses an Azure AD app registration (tenant ID + client ID + client secret).

<key>intuneEnabled</key>
<string>true</string>
<key>intuneTenantID</key>
<string>...</string>
<key>intuneClientID</key>
<string>...</string>
<key>intuneClientSecret</key>
<string>...</string>
Changy Settings screen showing full Jamf Pro and Microsoft Intune configuration fields
Settings โ€” Jamf Pro and Intune, same pattern: enable, then fill in the connection details.

Not yet validated against real servers: all four enterprise integrations, plus web search, are implemented and unit-tested against mocked responses only โ€” no test credentials were available during development. Validate against a real instance before relying on them in production.

An optional tool (Brave Search API) the model can invoke during evaluation to check a draft plan's claims against current, real-world information. Off by default โ€” enabling it sends the plan's rubric criteria and derived search queries to a third-party search API, which an organization may not want without opting in.

<key>webSearchEnabled</key>
<string>true</string>
<key>braveSearchAPIKey</key>
<string>...</string>