Repository navigation
Automate private Mailchimp account exports and attach them to recurring work #108
Description
Automate private Mailchimp account exports and attach them to recurring work
Status: blocked — source is accepted/deployed; waits for #166 steady state, external credential readiness, and one HUMAN real-provider acceptance run
Tags: enhancement, portal, frontend, backend, infra, data, P1
Depends on: #166 Phase D, canonical first-write evidence, and accepted cleanup; external Dapier credential owner
Satisfied source dependency: #120 is closed completed
Not a dependency: #187 changes one-off import-test selection only and preserves Mailchimp product tests
Blocks: None
Next owner: Dapier credential owner may record sanitized readiness; after #166 cleanup, an authorized DataOps mailing-export operator performs the HUMAN checklist
Resume condition: final canonical Tasks and ordinary deployment are restored, the Dapier item exists, and the non-secret mailing configuration targets the intended post-cutover recurring Task
Final source disposition
The agent-verifiable Mailchimp export product is complete.
Accepted commit e527164429e60c573cd14162a3e9020bd3184d16 is in current source and was deployed. Tester and PM accepted the provider-neutral request/poll/download flow, durable idempotency, private storage, Artifact/Task linkage, controlled download, portal behavior, safe failures, and privacy boundary. On-Call verified deployment and unauthenticated denial without calling Mailchimp.
#120 is now closed as the completed credential-source boundary. Its deployed reader uses the Dapier-owned credential_id: "mailchimp" record through exact-key, read-only IAM and no legacy Mailchimp Secrets Manager permission.
There is no source implementation, test, IAM, bucket, route, portal, or deployment work remaining under #108 unless the bounded HUMAN run reveals a new defect.
Product classification
This is a permanent source export product, not migration/import machinery.
It requests Mailchimp’s asynchronous account-wide audiences export, persists safe run state, stores the ZIP in retained private DataOps storage, creates one private Artifact, and attaches it to recurring work. That is retained under the user decision export from the data source — keep.
#174 removed migration-only APIs, planners, checkpoints, rollback/orphan frameworks, and ongoing importer tests. It explicitly retained live exports.
#187 keeps one-off dry-run import verification out of normal CI. It explicitly leaves Mailchimp, scheduled export, and archive tests in the ordinary backend suite because those tests protect shipped runtime behavior. #108 does not depend on #187 publication, and no one-off import/export/restore command is part of this HUMAN acceptance.
Do not delete, demote, or move the mailing-export product tests to one-off coverage. Do not add migration API support, generic credential access, or compatibility fallback.
Completed acceptance
- Provider-neutral request, status polling, and download are separate from scheduling, persistence, storage, Task attachment, and presentation.
- Mailchimp uses account exports with the
audiencesstage and honest account-wide semantics. - Runs have deterministic idempotency, durable pending/completed/failed state, safe retry actions, and no persisted provider download URL.
- Repeated/concurrent delivery of one run key cannot create duplicate logical provider requests, objects, Artifacts, or Task references.
- Unfinished runs are advanced under the same identity and the one-export/24-hour restriction is not bypassed.
- Completed ZIPs are checksummed and stored in retained, private, versioned, encrypted, TLS-only DataOps storage.
- Authenticated operators can list, start/advance, and download; unauthenticated calls are denied.
- Portal and API expose safe status/actions without credentials, contacts, provider URLs, or raw storage identity.
- Failure categories and logs are actionable and sanitized.
- Read Dapier-managed Mailchimp credential from DynamoDB #120’s Dapier credential reader and exact-key read-only IAM are deployed and production-verified.
- Agent source, test, PM, deployment, and public authorization gates passed.
- [HUMAN] External owner confirms the Dapier
mailchimpitem is populated without revealing its value or storage identity. - [HUMAN] Post-Replace the transitional Tasks table with the final cardId schema #166 configuration references
credentialId: "mailchimp"and the intended final canonical recurring Task. - [HUMAN] One bounded real export passes the provider, private-storage, canonical Task, controlled-download, privacy/log, and idempotency checks below.
- [HUMAN] Only after that pass, the authorized owner explicitly disposes the old Zapier/Google Drive flow.
Preconditions and sequencing
External credential readiness
The Dapier credential owner may populate or re-save the item and record only:
- readiness: populated;
- provider classification: Mailchimp;
- authorization for one DataOps acceptance run.
Do not record the key, server suffix, account identity, table name/ARN, item payload, update timestamp, or Dapier/private admin evidence. This readiness action does not authorize DataOps to call the provider.
#166 steady state
Do not run the real export during repaired A/B/C, writer quiescence, Phase D execution, or cleanup.
The export may write a run, Artifact, and canonical Task reference. Wait until:
- Phase D has deployed the final steady-state application;
- canonical first-write evidence has passed;
- accepted cleanup removed transitional guards and restored ordinary push deployment;
- runtime seeds/schedules are restored;
- the intended recurring Task exists in the final table and its current identity is known privately.
#108 source is already an ancestor of the #166 chain and must not add to or alter A/B/C/D.
Final non-secret configuration
After #166 cleanup, an authorized configuration owner confirms one enabled Mailchimp configuration:
- uses
credentialId: "mailchimp"; - describes account-wide audiences without contact/account-sensitive labels;
- points to the intended final recurring Task;
- contains no key, secret reference, provider download URL, raw storage URI, or legacy Task ID.
If configuration must change, use the ordinary reviewed main-push OIDC deployment path after #166 cleanup. Do not manually deploy or patch Lambda.
HUMAN acceptance run
1. Start and advance one run
Given the preconditions above and the legacy backup still active
When an authorized operator starts the current eligible export once
Then DataOps records requested or pending without exposing credential/provider details and disables duplicate activation while the request is in flight
If Mailchimp is still building the archive, use the scheduled invocation or the visible Advance / retry action on the same durable run. Do not create a different key, repeatedly poll with fixed sleeps, or bypass the provider’s one-export/24-hour limit.
2. Verify completion and canonical relationship
When the provider reports completion
Then the run reaches completed with safe filename/type/nonzero-size/checksum metadata, exactly one private Artifact is created, and exactly one reference appears on the intended final canonical Task
Re-advance the same completed run once. It must return the existing result without another logical provider request, object, Artifact, or Task reference. A stale/missing Task is a failed acceptance result: keep the archive, correct configuration through the ordinary path, and retry attachment without requesting another provider export.
3. Verify controlled access
From an authenticated portal session, use the controlled download action and confirm the private ZIP is obtainable only through the authorized short-lived response. Validate the archive only in an approved private environment.
Confirm the previously issued access expires according to the advertised server policy and requires a fresh authenticated action. Verify unauthenticated list, run, and download calls are denied without revealing whether an archive/account exists.
Never place the ZIP, extracted contacts, screenshot, provider response, signed URL, or storage location in this public repository, issue, CI artifact, shared .tmp/, or unmanaged drive.
4. Verify logs and privacy
Review the bounded run logs privately. They may contain safe transition/status categories only. They must not contain:
- API key, authorization header, or Dapier payload/identifier;
- contacts, audience members, account identity, or archive content;
- Mailchimp signed download URL;
- raw bucket/object identity or browser-visible
s3://URI; - private Task, Artifact, run, or configuration identifiers in public evidence.
5. Decide the legacy flow
Only after all checks pass may the authorized owner disable the old Zapier → Google Drive backup and revoke its obsolete access. Do not delete historical backups in this issue.
If any check fails:
- keep the legacy flow active;
- disable the new mailing configuration only through the ordinary authorized deployment path if required for safety;
- preserve the private archive/run for diagnosis;
- rotate/revoke a credential only if the credential owner determines exposure;
- file a separate
needs groomingproduct/security bug with sanitized failure stage and no private identifiers.
Public-safe evidence
A passing comment records only:
- UTC verification window;
- that the item/configuration were ready, without their identifiers;
- final safe status (
completed); - whether one logical request/object/Artifact/Task reference remained after replay;
- whether controlled download and expiry/reauthorization passed;
- whether unauthenticated denial passed;
- whether private log review found no sensitive data;
- whether the legacy flow was retained or disabled by its authorized owner.
Do not post exact run/configuration/Artifact/Task IDs, account labels, credential/table/bucket/object identifiers, contacts, archive metadata that identifies the account, signed URLs, headers, screenshots with private data, or provider error payloads.
Closure rule
When all HUMAN checks pass, PM may close #108 without a repository commit, provider rerun, migration/import/export test command, or application deployment.
A provider/product failure reopens implementation only through a new bounded issue. Credential absence or denied authorization remains an external blocker, not a reason for DataOps to add a fallback credential source or migration framework.
Evidence
- Tester final PASS: Automate private Mailchimp account exports and attach them to recurring work #108 (comment)
- PM final acceptance: Automate private Mailchimp account exports and attach them to recurring work #108 (comment)
- Accepted commit handoff: Automate private Mailchimp account exports and attach them to recurring work #108 (comment)
- Deployment evidence: Automate private Mailchimp account exports and attach them to recurring work #108 (comment)
- Credential-source deployment/IAM evidence: Read Dapier-managed Mailchimp credential from DynamoDB #120 (comment)
- Closed credential-source disposition: Read Dapier-managed Mailchimp credential from DynamoDB #120
- Migration-framework boundary: Audit one-shot migration tooling and remove it from the Lambda artifact #174
- One-off test-selection boundary: Keep one-off import verification out of ongoing backend CI #187
Out of scope
- Any agent/provider/AWS/credential/data/export/import/restore action from this reconciliation.
- A second real Mailchimp run solely to prove Read Dapier-managed Mailchimp credential from DynamoDB #120.
- Importing/restoring contacts, contact sync, campaign sending, newsletter scheduling, analytics, or a second provider.
- Generic credential APIs, Secrets Manager fallback, migration routes, compatibility paths, or importer tests.
- Deleting historical backups or disabling/revoking the legacy flow before acceptance.
- Changing Replace the transitional Tasks table with the final cardId schema #166 rollout artifacts or running during transition.
Activity
[-]Automate mailing-list exports and upload them to DataOps[/-][+]Automate private Mailchimp account exports and attach them to recurring work[/+]alexeygrigorev commentedon Jul 14, 2026
GROOMED
Issue #108 is now agent-ready with product scope, API + portal behavior, privacy/security boundaries, dependencies, exact verification, and explicit out-of-scope items.
Research notes:
audiencesstage exports all audiences in the account; it is not a single-audience endpoint. The issue now makes this operator-visible and requires handling Mailchimp's one-at-a-time/one-per-24-hours constraint.[HUMAN]; synthetic automated verification can proceed without secrets or personal data.Labels:
enhancement,portal,frontend,backend,infra,data,P1.alexeygrigorev commentedon Jul 14, 2026
SOFTWARE ENGINEER — READY FOR TEST
Implemented the agent-verifiable #108 scope without calling Mailchimp or AWS and without adding any private export data.
Summary
audiencesexports. The adapter validates/derives the server prefix, handlesexport_id,finished,download_url, timeouts, malformed completion, authorization, and concurrency/rate-limit responses without persisting or logging signed URLs.s3://identities; provider secrets, lease values, and provider signed URLs are not returned.[]).Verification (all exit 0)
npm --prefix backend test— 1180/1180 passednpm --prefix backend run typecheck— passednpm --prefix backend run build— passednpm --prefix backend run test:e2e— 344/344 passedNODE_ENV=test SKIP_AUTH=true node --import tsx --test backend/tests/mailing-exports.test.ts— 11/11 passednpx playwright test e2e/mailing-exports.spec.jsfrombackend/— 4/4 passeduv run pytest tests/infra/test_template.py— 18/18 passedmake sam-validate— valid SAM templatemake sam-build— build succeedednode --checkfor both portal app files and fallback API — passedgit diff --check— passedScreenshots captured under ignored
.tmp/screenshots/and visually inspected:.tmp/screenshots/mailing-exports-empty.png.tmp/screenshots/mailing-exports-pending.png.tmp/screenshots/mailing-exports-completed.png.tmp/screenshots/mailing-exports-mobile-failures.pngAcceptance status
[HUMAN]real credential/configuration and one real private export remain intentionally open.aws-infraor live AWS changes were made here.No commit or push performed.
alexeygrigorev commentedon Jul 14, 2026
TEST FAIL — CHANGES REQUESTED
Independent verification found a release-blocking privacy failure. No provider call, AWS write/apply, commit, push, or real/private export was performed; all runtime evidence used synthetic data.
Required changes
Internal S3 identity leaks through generic artifact mutation/attachment APIs. The mailing-specific GET/list sanitization works, but
PUT /api/artifacts/{mailingArtifactId},PUT /api/artifacts/{mailingArtifactId}/attach, and the attached task response expose the storeds3://URI. Synthetic runtime probes returned:{getStatus:200,getLeaksInternalS3:false,putStatus:200,putLeaksInternalS3:true}{attachStatus:200,attachLeaksInternalS3:true,taskStatus:200,taskLeaksInternalS3:true}This violates acceptance criterion 8 and the explicit requirement that internal S3 identity be absent from API/UI output. Apply the mailing-artifact sanitizer to every artifact response path (
create/update/attach/archiveas applicable), and never putstorageUriinto task/bundle artifact refs for private mailing exports. Add regression tests for all generic mutation/attachment/task/bundle read paths and verify portal rendering cannot turn an internal URI into a link.The focused Playwright coverage is not the required portal/viewport matrix.
backend/e2e/mailing-exports.spec.jsserves onlybackend/src/pages/index.html; it does not execute the changed productionfrontend/index.html+frontend/src/app.jssurface. Loading/no-config/pending/completed are checked only at desktop, while only the combined failure state is checked at 390 px, and the loading state has no screenshot. Add production-portal Playwright coverage and cover/capture loading, no-config/empty, pending/manual trigger, completed/download, and supported errors at desktop and 390 px as required.Commands and results
npm --prefix backend test— exit 0; 1180/1180 passed.NODE_ENV=test SKIP_AUTH=true node --import tsx --test tests/mailing-exports.test.tsfrombackend/— exit 0; 11/11 passed.npm --prefix backend run typecheck— exit 0.npm --prefix backend run build— exit 0.uv run pytest tests/infra/test_template.py— exit 0; 18/18 passed.make sam-validate— exit 0; valid template.make sam-build— exit 0; build succeeded.git diff --check— exit 0.npx playwright test e2e/mailing-exports.spec.jsfrombackend/— exit 0; 4/4 passed, but coverage gap above remains.npm --prefix backend run test:e2e— exit 0; 344/344 passed.node --import tsx --input-type=module -e ...synthetic runtime privacy probes — command exit 0; assertions reveal the S3 leaks above.Screenshots inspected
Fresh collision-safe evidence:
.tmp/screenshots/tester-108-20260714T045230Z/mailing-exports-empty.png— valid desktop no-config/empty state; no error/overlap/private data.mailing-exports-pending.png— valid desktop pending/manual action state; no error/overlap/private data.mailing-exports-completed.png— valid desktop completed/link/download state; no raw S3 link/private data.mailing-exports-mobile-failures.png— valid 390 px synthetic failure/action states; no horizontal overflow, overlap, or private data.These screenshots are visually clean but do not replace the missing production-frontend and full desktop/390 state matrix.
Acceptance criteria
audiencesrequest, prefix validation, async fields, and account-wide copy.[HUMAN]— real credential/config and one real private export/task attachment were correctly not attempted.Dependencies kept explicit
[HUMAN]; Automate private Mailchimp account exports and attach them to recurring work #108 is not deployment-unblocked.[HUMAN].Re-test after the S3 response/reference leak is fixed and the production portal + full responsive state coverage is added.
alexeygrigorev commentedon Jul 14, 2026
SOFTWARE ENGINEER — CHANGES APPLIED — READY FOR RETEST
Addressed both release-blocking findings in the Tester report: #108 (comment)
Changes applied
backend/src/responsePrivacy.ts, applied by the Lambda handler to every JSON route response. Any internals3://storageUriis removed, including legacy task/bundle refs already present in persistence.create,get,list,update,attach, andarchive) so S3 identities remain server-side. Generic attachment refs omit S3storageUri; non-S3 external/local refs retain their existing behavior. Controlled authenticated download still resolves the internal artifact server-side and returns only the short-lived download URL.s3://while internal storage remains usable.frontend/index.html+frontend/src/app.jsproduction surface.Changed areas for this retest
backend/src/handler.tsbackend/src/responsePrivacy.tsbackend/src/routes/artifacts.tsbackend/src/mailingExports/service.tsbackend/tests/mailing-exports.test.tsbackend/e2e/mailing-exports.spec.jsThe rest of the original #108 implementation remains in the shared uncommitted worktree. No source repo, provider, AWS, commit, or push operation was performed.
Verification
All listed successful commands exited 0:
npm --prefix backend test— 1180/1180 passednpm --prefix backend run typecheck— passednpm --prefix backend run build— passedNODE_ENV=test SKIP_AUTH=true node --import tsx --test tests/mailing-exports.test.tsfrombackend/— 11/11 passednpx playwright test e2e/mailing-exports.spec.js --workers=1 --reporter=dotfrombackend/— 2/2 passed after the final capture/navigation refinementsnpx playwright test --reporter=dotfrombackend/— isolated full suite 342/342 passed in 2.6muv run pytest tests/infra/test_template.py— 18/18 passedmake sam-validate— valid SAM templatemake sam-build— build succeedednode --check frontend/src/app.js,node --check backend/src/public/app.js, andnode --check backend/src/public/api.js— passedgit diff --check— passedOne earlier full-E2E attempt was invalid because it was run concurrently with
sam build, whose custom builder performs rootnpm ci; this replaced dependencies while Playwright was active. It was discarded and rerun alone, producing the 342/342 result above.Screenshot evidence
Fresh synthetic evidence is under the gitignored directory:
.tmp/screenshots/issue-108-engineer-retest/{fallback,production}-{desktop,mobile-390}-{loading,empty,pending,completed,errors,unavailable}.pngAll 24 were generated and inspected. The production shell and fallback surface render without horizontal overflow at 390 px; loading/empty/pending/completed/unavailable/error states are readable; controls remain usable; no provider data, contacts, signed provider URL, or raw
s3://link appears.Acceptance impact
[HUMAN]remains intentionally pending: supply the real Mailchimp configuration through the approved mechanism and verify one real private export/task attachment. Keep Automate private Mailchimp account exports and attach them to recurring work #108 open withhumanuntil that check is complete.No commit or push performed.
alexeygrigorev commentedon Jul 14, 2026
TEST PASS — independent retest
The two prior release blockers are resolved. No source file was edited, and no provider call, AWS write/apply, commit, push, or real/private export was performed during this retest. All runtime/browser evidence used synthetic data.
Commands and results
npm --prefix backend test— exit 0; 1180/1180 passed.NODE_ENV=test SKIP_AUTH=true node --import tsx --test tests/mailing-exports.test.tsfrombackend/— exit 0; 11/11 passed.npm --prefix backend run typecheck— exit 0.npm --prefix backend run build— exit 0.uv run pytest tests/infra/test_template.py— exit 0; 18/18 passed.make sam-validate— exit 0; valid SAM template.make sam-build— exit 0; build succeeded.node --check frontend/src/app.js,node --check backend/src/public/app.js,node --check backend/src/public/api.js, andgit diff --check— exit 0.npx playwright test e2e/mailing-exports.spec.js --workers=1 --reporter=listfrombackend/— exit 0; 2/2 passed. Each test covers one real surface (fallback and production), both desktop and 390 px, and the full loading/empty/pending/manual/completed/download/error/unavailable matrix.npm --prefix backend run test:e2e— exit 0; isolated full suite 342/342 passed in 2.6 minutes.node --import tsx --input-type=module -e ...privacy/integrity probe — exit 0.Former S3 leak: PASS
The independent runtime probe created one synthetic private mailing artifact and exercised the former leak paths. Structural results:
s3://absent;s3://absent;s3://absent;s3://absent;s3://absent;Focused tests also confirm list/get/replay auth, unauthenticated 401s, delayed polling, conditional concurrent idempotency, deterministic artifact/ref de-duplication, ZIP integrity/checksum, storage retry, task-link preservation, the 24-hour wait state, and provider response parsing. Source review confirms audit logs include stable config/run/status/transition/category fields only, not Authorization headers, secrets, signed provider URLs, contacts, or storage identity.
Browser matrix and screenshots: PASS
Fresh collision-safe evidence is in
.tmp/screenshots/tester-108-retest-20260714T052546Z/.There are 24 source screenshots:
{fallback,production}-{desktop,mobile-390}-{loading,empty,pending,completed,errors,unavailable}.png.Acceptance criteria
audiencesrequest, credential/server validation, async fields, and accurate operator semantics.[HUMAN]— a credentialed operator must supply the real Mailchimp configuration and verify one real private export/task attachment. Keep Automate private Mailchimp account exports and attach them to recurring work #108 open withhumanuntil complete.Dependency status
#118 is now closed after the credentialed CloudFormation apply and source/live reconciliation completed
IN_SYNC; the prior deploy-role blocker is resolved. This Tester verdict does not claim the remaining real-provider[HUMAN]check.The agent-verifiable implementation is approved for PM acceptance.
alexeygrigorev commentedon Jul 14, 2026
REJECTED — Product Manager final acceptance
The Tester evidence is complete and clean, #118 is closed, and I accept the implementation's account-wide Mailchimp semantics, 24-hour/concurrency handling, pending/retry and safe failure copy, authenticated controlled download, response privacy boundary, infrastructure/privacy documentation, and the explicit remaining
[HUMAN]real-provider check.One release-blocking operator-flow defect remains on both portal surfaces:
run.runKeyfrom that completed run (frontend/src/app.jsandbackend/src/public/app.js). The fresh completed-state fixture demonstrates the mismatch: the displayed completed run is keyed2026-07-13while the tested current day is2026-07-14. Clicking the control therefore replays the already-completed durable result instead of starting/advancing today's eligible run. The operator receives no indication that nothing new was requested.Required fix and retest:
The 24 fresh screenshots under
.tmp/screenshots/tester-108-retest-20260714T052546Z/otherwise pass PM visual review: loading, empty, pending, completed/download, all eight error categories, and unavailable states are readable and privacy-safe at desktop and exactly 390 px, with no overlap, horizontal overflow, raw S3 URI, provider URL, contact data, or broken shell.The remaining real Mailchimp secret/configuration and one real private export/task attachment stay correctly outside agent acceptance as
[HUMAN]. No provider or AWS action should be taken as part of this fix.alexeygrigorev commentedon Jul 14, 2026
SOFTWARE ENGINEER — PM FIX APPLIED — READY FOR RETEST
Addressed the final-acceptance rejection: #108 (comment)
Operator-flow fix
completed→ a fresh, stable current UTC-day key;requested,pending, orfailed→ the existing persisted run key, so advance/retry resumes the same durable run.frontend/src/app.js; the fallback implementation is inbackend/src/public/app.js.Browser regression coverage
backend/e2e/mailing-exports.spec.jsnow inspects the actual POST JSON body on both portal surfaces at desktop and exactly 390 px:2026-07-13submits today's key rather than replaying2026-07-13;2026-07-12preserves2026-07-12on retry;Screenshot evidence
Fresh synthetic captures remain under the ignored directory
.tmp/screenshots/issue-108-engineer-retest/.The affected before/after matrix was recaptured and inspected:
{fallback,production}-{desktop,mobile-390}-completed.png{fallback,production}-{desktop,mobile-390}-completed-started.pngAll eight images are readable and privacy-safe with no overlap or horizontal overflow. The completed view offers the existing controlled archive download and Start daily export; after starting, the view shows today's pending run, safe
provider-concurrencycopy, and the earliest retry time. No S3 URI, provider URL, contact data, or real account data appears.Verification
All successful commands exited 0:
npm --prefix backend test— 1180/1180 passednpm --prefix backend run typecheck— passednpm --prefix backend run build— passednpx playwright test e2e/mailing-exports.spec.js --workers=1 --reporter=dotfrombackend/— 2/2 passednpx playwright test --reporter=dotfrombackend/, run alone after SAM build — 342/342 passed in 2.7muv run pytest tests/infra/test_template.py— 18/18 passedmake sam-validate— valid SAM templatemake sam-build— build succeededgit diff --check— passedNo provider call, AWS write/apply, commit, or push was performed. The real Mailchimp configuration/export remains the explicit
[HUMAN]acceptance item.alexeygrigorev commentedon Jul 14, 2026
TEST PASS — PM run-key fix retest
The completed-run replay defect is fixed on both portal surfaces. No source file was edited, and no provider call, AWS write/apply, commit, push, or real/private export was performed. All evidence is synthetic.
Commands and results
npm --prefix backend test— exit 0; 1180/1180 passed.NODE_ENV=test SKIP_AUTH=true node --import tsx --test tests/mailing-exports.test.tsfrombackend/— exit 0; 11/11 passed.npm --prefix backend run typecheck— exit 0.npm --prefix backend run build— exit 0.git diff --check— exit 0.npx playwright test e2e/mailing-exports.spec.js --workers=1 --reporter=listfrombackend/— exit 0; 2/2 passed.npm --prefix backend run test:e2e— exit 0; isolated full suite 342/342 passed in 2.6 minutes..tmpPlaywright probe with a deliberately stale pending key across fallback/production × 1280/390 — exit 0; 4/4 preserved the exact existing key.An initial version of the optional
.tmpprobe timed out because its Tester-authored assertion incorrectly depended ondocument.activeElementafter DOM replacement. It did not reveal a product failure; I corrected only the ignored probe assertion and reran it successfully as recorded above.Infrastructure/SAM tests were not repeated for this app-only follow-up: the immediately preceding independent #108 retest already passed 18/18 infrastructure tests plus SAM validate/build, and this fix changes only portal run-key selection and Playwright coverage.
Submitted-body matrix: PASS
The focused test inspects the actual JSON sent to
/api/mailing-exports/runfor both the fallback and real production portals at desktop and exactly 390 px:new Date().toISOString().slice(0, 10));2026-07-13→ current UTC day, not2026-07-13;2026-07-12→ exactly2026-07-12on retry;2026-07-11→ exactly2026-07-11in all four surface/viewport combinations.Every action was keyboard-triggered, disabled while in flight, and produced one POST per activation. After starting from the completed state, both portals rendered the returned current-day pending run with safe provider 24-hour-window copy and earliest retry guidance.
Screenshots: PASS
Fresh collision-safe evidence:
.tmp/screenshots/tester-108-runkey-20260714T054508Z/.Eight images were inspected:
{fallback,production}-{desktop,mobile-390}-completed.png{fallback,production}-{desktop,mobile-390}-completed-started.pngThe before state clearly offers controlled download plus Start daily export; the after state shows the new pending run,
provider-concurrencyexplanation, retry time, and Advance / retry. All are readable, controls are intact, mobile images are exactly 390 px wide with no horizontal overflow, and there is no 404/error shell, overlap, raw S3 URI, provider signed URL, contact data, or real account data.Privacy regression: PASS
The focused 11-test mailing suite remains green, including generic artifact PUT/attach/task/bundle response sanitization, persisted/legacy reference redaction at the HTTP edge, authenticated five-minute controlled download, unauthenticated 401s, signed-provider-URL redaction, concurrent idempotency, and checksum/integrity behavior. The run-key change does not alter the established storage/privacy boundary.
All agent-verifiable #108 criteria now pass. The real Mailchimp configuration and one real private export/task attachment remain the explicit
[HUMAN]item; keep #108 open withhumanuntil that check completes.Approved for PM re-acceptance.
alexeygrigorev commentedon Jul 14, 2026
ACCEPTED — Product Manager final acceptance
The completed-run replay defect is resolved on both the production and fallback portal surfaces.
PM verification:
2026-07-13run correctly submits the current2026-07-14key instead of replaying the old result.provider-concurrencyexplanation, earliest retry time, and Advance / retry action..tmp/screenshots/tester-108-runkey-20260714T054508Z/pass visual review. Completed/download and completed-started/wait states are readable on both surfaces and viewports, with intact controls, no overlap or horizontal overflow, and no raw S3 URI, provider signed URL, contact data, real account data, or broken shell.audiencessemantics; one-at-a-time and 24-hour handling; deterministic idempotency and polling; private retained storage/artifact/task linkage; authenticated five-minute downloads; sanitized API/log/error behavior; responsive portal states; and placeholder-only extension, configuration, disable, and rollback documentation.All agent-verifiable acceptance criteria pass. The only remaining boundary is the issue's explicit
[HUMAN]check: a credentialed operator must supply the real Mailchimp configuration through the approved mechanism and verify one real private export reaches DataOps storage and its intended recurring task. No provider or AWS action belongs in this acceptance stage. Keep #108 open withhumanafter shipping until that real-provider check is completed.No edits, commit, push, provider call, or AWS write were performed during PM acceptance.
alexeygrigorev commentedon Jul 14, 2026
ENGINEERING COMMIT COMPLETE —
[HUMAN]PRODUCTION VERIFICATION CHECKLISTCommitted the accepted agent-verifiable implementation as
e527164429e60c573cd14162a3e9020bd3184d16(Refs #108). The issue remains open and now has thehumanlabel. Nothing was pushed and no provider/AWS action was performed.A credentialed operator should complete the following checklist after this commit is pushed and the normal GitHub Actions OIDC deployment has successfully updated the DataOps stack. Do not manually deploy the application and do not paste any real value into this public issue, task content, logs, or screenshots.
1. Credential and private configuration
{ "apiKey": "<real-key>", "server": "<matching-prefix>" }in an AWS Secrets Manager secret.servermay be omitted when the API-key suffix is authoritative. Record the secret ARN privately.MAILCHIMP_SECRET_ARNto that ARN through the approved GitHub/AWS operator path.MAILING_EXPORTS_CONFIGvariable to one enabled configuration with a non-sensitive configuration ID/account label,provider: "mailchimp",scopeLabel: "All audiences (account export)", the intendedtaskId, andsecretNameresolving to the same authorized secret. Do not include contacts, audience members, the API key, or signed URLs.2. Real export
pendingwith the same provider export/run identity and a wait/advance action. Refresh or advance the same run later; do not create a new key to bypass the one-export/24-hour restriction.completedwith a ZIP filename, nonzero size,application/zip, SHA-256 checksum, artifact ID, requested/completed timestamps, and no providerdownload_urlin the API, page, task, or logs.3. Task attachment
s3://URI or browser-accessible provider URL.4. Controlled download
s3://URI or Mailchimp signeddownload_url..tmp/on a shared host, Google Drive, or another public/unmanaged location.401/403and cannot infer account/export contents.5. Logs, legacy-flow shutdown, and revocation
enabledtofalseand redeploy via CI. Preserve the retained bucket/artifact history, keep the legacy flow active, rotate/revoke any exposed or suspect key, and record only the safe failure category in this issue.When every item passes, post a redacted confirmation containing only the run/configuration IDs, completion time, artifact ID, intended task ID/link status, download-expiry result, log-review result, and legacy credential revocation result. Do not post account contacts, archive contents, bucket/object URI, secret identifiers, keys, or signed URLs.
feat: automate private mailing list exports
alexeygrigorev commentedon Jul 14, 2026
ON-CALL DEPLOYMENT STATUS — commit
e527164The mailing-export implementation is contained in current
mainand in the latest successfully deployed artifact.UPDATE_COMPLETE, and the backend smoke passed.GET /api/mailing-exportsreturns the expected non-revealing401JSON response.This confirms deployment and the public authorization boundary only. No provider call, export, artifact creation, task attachment, download, secret rotation, or legacy-flow shutdown was performed. Keep the issue open with
humanuntil its credentialed provider checklist is completed.ON-CALL DONE: #108 code/configuration path is deployed; real provider verification remains human-owned.
alexeygrigorev commentedon Jul 31, 2026
PM TRACKER RECONCILIATION
The issue body now reflects shipped state rather than reopening implementation:
e527164, and successful On-Call deployment evidence.credentialId, with exact-table/leading-key-constrainedGetItemand no Mailchimp Secrets Manager grant. Read Dapier-managed Mailchimp credential from DynamoDB #120 commit0267050passed its full lifecycle and deployment.humanlabel remains. No credential was inspected, no provider call was made, and no HUMAN criterion is claimed passed.Current blocker: #120 last reported the Dapier-managed
mailchimpitem empty. Resume only after a credentialed operator posts sanitized confirmation that the item is populated and the deployed mailing-export configuration references its non-secretcredentialId; then complete the unchecked real export, task attachment, controlled download, privacy/log, and legacy-flow checks.Evidence: Tester pass, PM acceptance, commit handoff, #108 On-Call, #120 On-Call.
alexeygrigorev commentedon Aug 13, 2026
PM runtime-acceptance reconciliation complete.
Decision: #108 remains open/blocked as the single HUMAN Mailchimp runtime tracker. Agent/source work is complete.
Dependencies are now exact:
Exact next owners:
mailchimprecord is populated and authorize one acceptance run—without exposing its value or storage identity.credentialId: "mailchimp"and the intended final recurring Task after reset/seeding.The public evidence contract now forbids exact production run/config/Artifact/Task IDs, account labels, table/bucket/object identifiers, contacts, archive data, signed URLs, credentials, headers, and private screenshots. A safe result is enough.
No second export is needed for #120, no one-off test/import/export/restore command is part of acceptance, and no source commit/deploy is needed to close #108 after the HUMAN pass.
No repository file, test, AWS/provider call, credential read/write, data mutation, import/export/restore, deployment, commit, or push was performed.
feat: automate private mailing list exports
alexeygrigorev commentedon Oct 5, 2026
Superseded by #246. Dapier now owns Mailchimp mailing-list export; DataOps shipped the complete deletion of this capability on
f38578e.