[object Object]

← back to Homesonspec

verify Apple review poller lifecycle

7cf4bed812e2670f0266376031c2b40d4e784bfe · 2026-09-04 11:30:41 -0700 · Steve

Files touched

Diff

commit 7cf4bed812e2670f0266376031c2b40d4e784bfe
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 4 11:30:41 2026 -0700

    verify Apple review poller lifecycle
---
 ops/apple-review-poller.mjs                        |  4 +-
 ops/apple-review-poller.test.mjs                   |  7 ++-
 .../TK-10337-apple-review-poller-e2e-proof.json    | 50 ++++++++++++++++++++++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/ops/apple-review-poller.mjs b/ops/apple-review-poller.mjs
index 1dfb1d13..f9080605 100644
--- a/ops/apple-review-poller.mjs
+++ b/ops/apple-review-poller.mjs
@@ -49,8 +49,8 @@ function notify(state, outcome) {
   ]);
 }
 
-function removeScheduler() {
-  return spawnSync('/bin/launchctl', ['remove', JOB_LABEL], { encoding: 'utf8' });
+export function removeScheduler(label = JOB_LABEL) {
+  return spawnSync('/bin/launchctl', ['remove', label], { encoding: 'utf8' });
 }
 
 export function run({ fixturePath = null, runtimeDir = resolve('ops/runtime') } = {}) {
diff --git a/ops/apple-review-poller.test.mjs b/ops/apple-review-poller.test.mjs
index 603e0258..87de4974 100644
--- a/ops/apple-review-poller.test.mjs
+++ b/ops/apple-review-poller.test.mjs
@@ -4,7 +4,7 @@ import { tmpdir } from 'node:os';
 import { join } from 'node:path';
 import test from 'node:test';
 
-import { classifyState, parseAppState, run } from './apple-review-poller.mjs';
+import { classifyState, parseAppState, removeScheduler, run } from './apple-review-poller.mjs';
 
 const row = (state) => `🟡 Homes on Spec          ${state}         1.0\n`;
 
@@ -37,3 +37,8 @@ test('missing app is a retryable error, never a false terminal result', () => {
   assert.equal(parseAppState('⚪ Different App PREPARE_FOR_SUBMISSION 1.0'), null);
   assert.deepEqual(classifyState(null), { terminal: false, outcome: 'unknown' });
 });
+
+test('scheduler removal returns a real launchctl result for an absent isolated label', () => {
+  const result = removeScheduler('com.steve.homesonspec-apple-review-test-absent');
+  assert.equal(typeof result.status, 'number');
+});
diff --git a/verification/TK-10337-apple-review-poller-e2e-proof.json b/verification/TK-10337-apple-review-poller-e2e-proof.json
new file mode 100644
index 00000000..18a45c93
--- /dev/null
+++ b/verification/TK-10337-apple-review-poller-e2e-proof.json
@@ -0,0 +1,50 @@
+{
+  "intent": "Poll App Store Connect every 15 minutes until Homes on Spec receives a terminal Apple review decision, then notify locally and remove the polling job.",
+  "riskTier": "R3",
+  "environment": "macOS gui/501 LaunchAgent with read-only App Store Connect ipa-status integration",
+  "buildIdentity": "672b968924f9ade6f799fec58e773e6beb55ee86 plus scheduler-removal test follow-up",
+  "timestamp": "2026-09-04T18:30:12Z",
+  "baseline": {
+    "app": "Homes on Spec",
+    "state": "WAITING_FOR_REVIEW",
+    "source": "live App Store Connect read through ipa-status"
+  },
+  "checks": [
+    {
+      "boundary": "state parsing and terminal classification",
+      "verdict": "PASS",
+      "evidence": "node --test ops/apple-review-poller.test.mjs: 5/5 passed; covers pending, approved, rejection, missing-app, persistence, and launchctl invocation behavior"
+    },
+    {
+      "boundary": "live authenticated Apple read",
+      "verdict": "PASS",
+      "evidence": "2026-09-04T18:26:38.562Z returned Homes on Spec WAITING_FOR_REVIEW with commandStatus 0"
+    },
+    {
+      "boundary": "retry-safe network failure",
+      "verdict": "PASS",
+      "evidence": "A fetch failure at 2026-09-04T18:26:24.073Z persisted state=unknown, terminal=false and did not remove the scheduler"
+    },
+    {
+      "boundary": "persistent scheduler install and first real run",
+      "verdict": "PASS",
+      "evidence": "launchctl gui/501/com.steve.homesonspec-apple-review shows run interval 900 seconds, runs=1, last exit code=0; first scheduled event at 2026-09-04T18:27:00.968Z persisted WAITING_FOR_REVIEW"
+    },
+    {
+      "boundary": "terminal self-removal",
+      "verdict": "PASS",
+      "evidence": "Isolated LaunchAgent com.steve.homesonspec-review-poller-e2e was bootstrapped, removed through exported removeScheduler(), returned status 0, and launchctl subsequently confirmed it absent while the production poller remained loaded"
+    },
+    {
+      "boundary": "runtime audit trail",
+      "verdict": "PASS",
+      "evidence": "ops/runtime/apple-review-poller.jsonl and apple-review-status.json record timestamps, state, outcome, command status, and errors; runtime directory is gitignored"
+    }
+  ],
+  "cleanup": {
+    "temporaryLaunchAgent": "removed",
+    "productionLaunchAgent": "retained intentionally until a terminal Apple decision",
+    "externalMutation": "none; App Store access is GET/read-only"
+  },
+  "verdict": "PASS"
+}

← 672b9689 add App Store review completion poller  ·  back to Homesonspec  ·  auto-data-snapshot: 2026-09-04T11:31:34 (65 data files) — ap 90ca06fc →