Everything below is grounded in Spettro.xcodeproj/project.pbxproj and
Local.xcconfig. The project has exactly one app target (Spettro),
two configurations (Debug, Release), and no test targets.
Build settings come from three places, in increasing order of precedence:
- Xcode defaults — anything not mentioned anywhere else.
- Project-level configurations — the
XCBuildConfigurationblocks on thePBXProject "Spettro"object. These setMACOSX_DEPLOYMENT_TARGET = 26.5, compiler warnings, and optimization levels. No base xcconfig. - Target-level configurations — the
XCBuildConfigurationblocks on thePBXNativeTarget "Spettro"object. Both Debug and Release useLocal.xcconfigas their base configuration (baseConfigurationReference), then override specific keys inline.
Local.xcconfig itself contains exactly one line of substance:
DEVELOPMENT_TEAM = <your-team-id>
It is gitignored on purpose (see .gitignore) — it's the dev's personal
signing team and should never be committed. If you clone the repo fresh,
create your own Local.xcconfig at the repo root with your team ID, or
signing will fail at build time.
| Where | Value |
|---|---|
| Project-level Debug/Release | 26.5 |
| Target-level Debug/Release | 26.0 |
The target-level value wins, so the effective
MACOSX_DEPLOYMENT_TARGET is 26.0. The 26.5 on the project object is
a leftover default and has no effect on the built product. (Doc 02 notes
the same split.)
| Setting | Value |
|---|---|
PRODUCT_NAME |
$(TARGET_NAME) → Spettro |
PRODUCT_BUNDLE_IDENTIFIER |
to.eyed.Spettro |
MARKETING_VERSION |
1.0 |
CURRENT_PROJECT_VERSION |
1 |
| Product type | com.apple.product-type.application |
| Product reference | Spettro.app in BUILT_PRODUCTS_DIR |
The bundle id to.eyed.Spettro is what defaults write to.eyed.Spettro …
targets when persisting the explicit CLI path (see doc 03).
| Setting | Value |
|---|---|
CODE_SIGN_STYLE |
Automatic |
CODE_SIGN_IDENTITY[sdk=macosx*] |
Apple Development |
DEVELOPMENT_TEAM |
from Local.xcconfig |
ENABLE_HARDENED_RUNTIME |
YES |
ENABLE_APP_SANDBOX |
NO |
Signing is fully automatic against an Apple Development identity; the
only machine-specific input is the team ID injected via Local.xcconfig.
The hardened runtime is on for both configurations.
The app is not sandboxed (ENABLE_APP_SANDBOX = NO). That's
deliberate: it must spawn spettro as a subprocess, read/write
~/.spettro/config.json and ~/.spettro/memory.md outside its container,
and run user shell commands in the terminal drawer. Sandboxing would
forbid all of that.
All six RUNTIME_EXCEPTION_* keys are set explicitly, five of them to
NO (i.e. the entitlement is not granted):
| Setting | Value | Meaning |
|---|---|---|
RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES |
NO |
No DYLD_* env overrides |
RUNTIME_EXCEPTION_ALLOW_JIT |
NO |
No JIT |
RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY |
NO |
No unsigned executable memory |
RUNTIME_EXCEPTION_DEBUGGING_TOOL |
YES |
Is a debugging tool (may attach) |
RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION |
NO |
No rwx pages |
RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION |
NO |
Library validation stays on |
Only the debugging-tool exception is granted — consistent with an app that manages a long-lived child process and surfaces its logs.
Because the target is non-sandboxed, these are inert but recorded anyway:
AUTOMATION_APPLE_EVENTS = NO, and every ENABLE_RESOURCE_ACCESS_* key
(audio input, calendars, camera, contacts, location, photo library) is
NO. ENABLE_USER_SELECTED_FILES = readonly grants read-only access to
files the user picks in open/save panels.
There is no .entitlements file in the repo (CODE_SIGN_ENTITLEMENTS
is never set). Every entitlement is generated by Xcode from the build
settings above — primarily the hardened-runtime exceptions, the
resource-access toggles, and REGISTER_APP_GROUPS = YES (which registers
any app-group identifiers at signing time; the project defines none, so
this is effectively a no-op placeholder).
There is no checked-in Info.plist: GENERATE_INFOPLIST_FILE = YES
makes Xcode synthesize one at build time. Values come from
INFOPLIST_KEY_* build settings:
| Build setting | Generated key | Value |
|---|---|---|
INFOPLIST_KEY_CFBundleDisplayName |
CFBundleDisplayName |
Spettro |
INFOPLIST_KEY_LSApplicationCategoryType |
LSApplicationCategory |
public.app-category.developer-tools |
INFOPLIST_KEY_NSHumanReadableCopyright |
NSHumanReadableCopyright |
(empty string) |
Everything else in the generated plist (CFBundleName,
CFBundleShortVersionString from MARKETING_VERSION,
CFBundleVersion from CURRENT_PROJECT_VERSION, etc.) is Xcode's
standard synthesis.
| Setting | Value |
|---|---|
ASSETCATALOG_COMPILER_APPICON_NAME |
AppIcon |
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME |
AccentColor |
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS |
YES |
| Setting | Value |
|---|---|
SWIFT_VERSION |
5.0 |
SWIFT_DEFAULT_ACTOR_ISOLATION |
MainActor |
SWIFT_APPROACHABLE_CONCURRENCY |
YES |
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY |
YES |
SWIFT_ACTIVE_COMPILATION_CONDITIONS (Debug) |
DEBUG $(inherited) |
SWIFT_OPTIMIZATION_LEVEL (Debug) |
-Onone |
SWIFT_COMPILATION_MODE (Release) |
wholemodule |
ENABLE_PREVIEWS |
YES |
Two of these shape the whole codebase:
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor— every type is MainActor-isolated unless explicitly opted out, which is why the model layer can touch UI state freely (see doc 06 onAppModel).SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUGin Debug builds — this is what gates the mock data inPreviewSupport.swiftbehind#if DEBUG.
ENABLE_TESTABILITY = YES in Debug only (project level), as usual.
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
Standard for an app embedding SwiftPM frameworks. The two package products
(SwiftTerm, Textual) are linked in the target's Frameworks phase — see
SwiftPM dependencies.
Everything in the target-level configuration is identical between Debug and Release. All variation lives at the project level:
| Setting | Debug | Release |
|---|---|---|
GCC_OPTIMIZATION_LEVEL |
0 |
(default -s) |
SWIFT_OPTIMIZATION_LEVEL |
-Onone |
(default -O) |
SWIFT_COMPILATION_MODE |
(incremental) | wholemodule |
DEBUG_INFORMATION_FORMAT |
dwarf |
dwarf-with-dsym |
ENABLE_TESTABILITY |
YES |
(absent) |
ENABLE_NS_ASSERTIONS |
(default on) | NO |
ONLY_ACTIVE_ARCH |
YES |
(absent) |
MTL_ENABLE_DEBUG_INFO |
INCLUDE_SOURCE |
NO |
GCC_PREPROCESSOR_DEFINITIONS |
DEBUG=1 |
(absent) |
The default configuration for command-line builds (xcodebuild without
-configuration) is Release — both XCConfigurationList blocks set
defaultConfigurationName = Release.
From the PBXProject attributes block:
LastSwiftUpdateCheck/LastUpgradeCheck=2660- Target created with Xcode 26.6 (
CreatedOnToolsVersion = 26.6) developmentRegion = en; known regionsen,BaseobjectVersion = 77(the Xcode 16+ format that supportsPBXFileSystemSynchronizedRootGroup— which is why theSpettro/source folder has no per-file references in the pbxproj)BuildIndependentTargetsInParallel = 1
git clone <repo> && cd Spettro
echo 'DEVELOPMENT_TEAM = <your-team-id>' > Local.xcconfig
xcodebuild -project Spettro.xcodeproj -scheme Spettro \
-configuration Debug buildThat, plus a spettro CLI binary (see
Building and running), is the entire
setup. There are no other secrets, scripts, or generated files involved.