mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7c686d5cf | ||
|
|
314664ecd6 | ||
|
|
11f89b1345 | ||
|
|
2481956c11 | ||
|
|
8804e121b6 | ||
|
|
7b3de48dbd | ||
|
|
5ebf57bdbf | ||
|
|
089e629021 | ||
|
|
58b70710db | ||
|
|
d645d83c47 | ||
|
|
179f912170 | ||
|
|
a604f82110 | ||
|
|
ae8e72ddb5 | ||
|
|
fd38b303f0 | ||
|
|
387b242aea |
No files matched your search
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 2026-08-30-ios-extension-version-verification
|
||||
date: 2026-08-30
|
||||
status: promoted
|
||||
scope: iOS release artifact verification
|
||||
evidence: build 45 Xcode archive warning plus direct PlistBuddy inspection of the exported IPA
|
||||
destination: .codex/skills/release-mobile/SKILL.md
|
||||
review_after: 2027-02-28
|
||||
---
|
||||
|
||||
## Symptom
|
||||
|
||||
The signed iOS build logged that the widget extension build number 44 did not
|
||||
match the containing app build number 45, even though export completed.
|
||||
|
||||
## Reproduction
|
||||
|
||||
Build iOS version 1.0.6 with EAS auto-increment from build 44 to 45 and retain the
|
||||
archive log. Extract the resulting IPA with `ditto`, then read the containing app
|
||||
and every packaged extension `Info.plist` with `PlistBuddy`.
|
||||
|
||||
## Cause
|
||||
|
||||
The archive warning described an intermediate state and was not authoritative
|
||||
for the exported package. Direct IPA inspection showed both the app and
|
||||
`LiveDrawWidget.appex` at version 1.0.6 build 45.
|
||||
|
||||
## Remediation
|
||||
|
||||
For every iOS release, inspect version and build values in the exported app and
|
||||
all packaged extensions. Reject or rebuild only when the final IPA values differ;
|
||||
do not accept or reject a release from archive warnings alone.
|
||||
|
||||
## Evidence
|
||||
|
||||
`PlistBuddy` read `CFBundleShortVersionString` 1.0.6 and `CFBundleVersion` 45 from
|
||||
both packaged plists. `codesign --verify --deep --strict` passed for the app, and
|
||||
the verified IPA SHA-256 was
|
||||
`9d4779bddac4647911a3a38e4ee37cf794c2b8691e0746a041b629c62b308e7f`.
|
||||
@@ -54,5 +54,9 @@ additional TestFlight distribution requires another fresh authorization.
|
||||
|
||||
Preserve platform signing and local EAS versioning. After a build, verify that
|
||||
tracked changes are limited to the expected version metadata, then independently
|
||||
read the artifact version and signature. Report the artifact, version/build
|
||||
number, upload result when authorized, and store read-back state.
|
||||
read the artifact version and signature. For an iOS IPA, inspect every packaged
|
||||
app extension as well as the containing app and require matching
|
||||
`CFBundleShortVersionString` and `CFBundleVersion` values. Treat Xcode archive
|
||||
warnings as diagnostic evidence, not the final artifact state: decide whether to
|
||||
reject or rebuild only after reading the exported IPA itself. Report the artifact,
|
||||
version/build number, upload result when authorized, and store read-back state.
|
||||
@@ -25,11 +25,18 @@ MCP service in one npm/Turborepo workspace.
|
||||
and prove the relevant compatibility contracts still hold. Preserve deployed
|
||||
interfaces and supported client behavior; repository checks alone do not
|
||||
prove a live change is safe.
|
||||
10. Scope work to the task. Route bounded implementation through the project
|
||||
`implementation` agent when delegation is useful; the primary agent retains
|
||||
acceptance, review, and final verification. Do not delegate trivial edits.
|
||||
10. Delegate every substantive repository task to at least one project agent so
|
||||
detailed exploration or execution stays out of the primary context.
|
||||
"Substantive" includes repository exploration, multi-file reasoning,
|
||||
implementation, test execution, or contract/risk analysis. Use `repo_scout`
|
||||
for read-only investigation and `implementation` for bounded changes; use
|
||||
the additional roles according to `docs/agents/routing.md`. The primary
|
||||
agent retains scope, acceptance, review, and the final answer. Skip
|
||||
delegation only for trivial conversation, a single obvious lookup, or a
|
||||
mechanical one-line edit whose coordination cost exceeds the work.
|
||||
11. Use high-effort reviewers only for the risk triggers in
|
||||
`docs/agents/routing.md`.
|
||||
12. Agents must not use em dash characters in text they add to this repository.
|
||||
|
||||
## Repository map
|
||||
|
||||
|
||||
@@ -92,8 +92,8 @@ android {
|
||||
applicationId 'com.sauci.app'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 47
|
||||
versionName "1.0.5"
|
||||
versionCode 48
|
||||
versionName "1.0.6"
|
||||
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
||||
}
|
||||
signingConfigs {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"expo": {
|
||||
"name": "Sauci",
|
||||
"slug": "sauci",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/icon.png",
|
||||
"scheme": "app.sauci",
|
||||
@@ -16,12 +16,15 @@
|
||||
"ios": {
|
||||
"supportsTablet": false,
|
||||
"bundleIdentifier": "com.sauci.app",
|
||||
"config": {
|
||||
"usesNonExemptEncryption": false
|
||||
},
|
||||
"entitlements": {
|
||||
"com.apple.security.application-groups": [
|
||||
"group.com.sauci.app"
|
||||
]
|
||||
},
|
||||
"buildNumber": "43",
|
||||
"buildNumber": "45",
|
||||
"usesAppleSignIn": true,
|
||||
"googleServicesFile": "./GoogleService-Info.plist",
|
||||
"infoPlist": {
|
||||
@@ -183,7 +186,7 @@
|
||||
"backgroundColor": "#1a1a2e"
|
||||
},
|
||||
"package": "com.sauci.app",
|
||||
"versionCode": 47,
|
||||
"versionCode": 48,
|
||||
"googleServicesFile": "./google-services.json",
|
||||
"permissions": [
|
||||
"RECEIVE_BOOT_COMPLETED",
|
||||
|
||||
@@ -570,7 +570,7 @@
|
||||
INFOPLIST_FILE = Sauci/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -599,7 +599,7 @@
|
||||
INFOPLIST_FILE = Sauci/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -772,7 +772,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = ../targets/widget/generated.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
CURRENT_PROJECT_VERSION = 44;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = BXVPBATDZY;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@@ -782,7 +782,7 @@
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.sauci.app.LiveDrawWidget;
|
||||
@@ -808,7 +808,7 @@
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = ../targets/widget/generated.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
CURRENT_PROJECT_VERSION = 44;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = BXVPBATDZY;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@@ -818,7 +818,7 @@
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
MARKETING_VERSION = 1.0.5;
|
||||
MARKETING_VERSION = 1.0.6;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.5</string>
|
||||
<string>1.0.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -47,9 +47,11 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>43</string>
|
||||
<string>45</string>
|
||||
<key>GOOGLE_ANALYTICS_INAPURCHASE_COLLECTION_ENABLED</key>
|
||||
<false/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<string>com.apple.widgetkit-extension</string>
|
||||
</dict>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>43</string>
|
||||
<string>45</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.5</string>
|
||||
<string>1.0.6</string>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
@@ -1,9 +1,12 @@
|
||||
# Agent routing and effort
|
||||
|
||||
The primary agent owns scope, acceptance criteria, task decomposition, and the
|
||||
final answer. Use one implementation agent when a bounded handoff will keep noisy
|
||||
execution out of the primary context. Do not pay the coordination cost for a
|
||||
trivial one-file edit. Add other agents only for separable work or a risk trigger.
|
||||
The primary agent owns scope, acceptance criteria, task decomposition, review,
|
||||
and the final answer. Every substantive repository task must delegate at least
|
||||
one bounded unit to the best-fit project agent. Use `repo_scout` for read-only
|
||||
discovery or analysis and `implementation` for product or harness changes. Add
|
||||
other agents only for separable work or the risk triggers below. Skip delegation
|
||||
only for trivial conversation, a single obvious lookup, or a mechanical one-line
|
||||
edit whose coordination cost exceeds the work.
|
||||
|
||||
## Implementation and integration
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Sauci Mobile Release Notes
|
||||
|
||||
## v1.0.6 — 30 August 2026
|
||||
_iOS build 44 · Android build 48_
|
||||
|
||||
A little more clarity, momentum, and playfulness for your shared check-ins.
|
||||
|
||||
- **Your turn at a glance** — A private Home prompt now shows when questions from your partner are waiting, without revealing their answers.
|
||||
- **New ways to play** — Browse, send, and respond to Dares together from a dedicated shared space.
|
||||
- **Streaks that fit your day** — Shared streaks now follow your local day, with clearer progress and reminder controls.
|
||||
- **Smoother shared moments** — Leaner syncing keeps questions, matches, chat, and Live Draw feeling current with less unnecessary refreshing.
|
||||
|
||||
## v1.0.1 (Build 30) - January 2025
|
||||
|
||||
### New Features
|
||||
|
||||
+1
-1
@@ -258,7 +258,7 @@ To verify you're using the correct keystore:
|
||||
keytool -list -v -keystore android/sauci-release.keystore -storepass <password>
|
||||
```
|
||||
|
||||
Expected SHA1: `C3:70:C5:8C:85:E5:B5:92:97:82:A9:B0:47:98:40:99:AC:C8:47:43`
|
||||
Expected EAS production upload-key SHA1: `F0:60:26:C7:54:B0:46:F2:80:FE:AC:43:8A:69:10:BD:9A:62:B4:59`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -40,6 +40,13 @@ for (const file of allFiles) {
|
||||
}
|
||||
|
||||
if (!scoped) {
|
||||
const agentsFile = path.join(root, 'AGENTS.md');
|
||||
const agents = await readFile(agentsFile, 'utf8');
|
||||
const noEmDashRule = 'Agents must not use em dash characters in text they add to this repository.';
|
||||
if (!agents.includes(noEmDashRule)) {
|
||||
fail(agentsFile, 'agent writing rule against em dash characters is missing', `restore: ${noEmDashRule}`);
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
|
||||
const codexConfigFile = path.join(root, '.codex', 'config.toml');
|
||||
const codexConfig = await readFile(codexConfigFile, 'utf8');
|
||||
|
||||
Reference in new issue
Block a user