007
無料Security audit, hardening, threat modeling (STRIDE/PASTA), Red/Blue Team, OWASP checks, code review, incident response, and infrastructure security for any project.
日本語の概要は準備中です。原文の説明を表示しています。
Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing SKAdNetwork with AdAttributionKit for ad measurement.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Privacy-preserving ad attribution for iOS 17.4+ / Swift 6.3. AdAttributionKit lets ad networks measure conversions (installs and re-engagements) without exposing user-level data. It supports the App Store and alternative marketplaces, and interoperates with SKAdNetwork.
Three roles exist in the attribution flow: the ad network (signs impressions, receives postbacks), the publisher app (displays ads), and the advertised app (the app being promoted).
AdAttributionKit preserves user privacy through several mechanisms:
The system evaluates impressions from both AdAttributionKit and SKAdNetwork together when determining attribution winners. Only one impression wins per conversion. Click-through ads always take precedence over view-through ads, with recency as the tiebreaker within each group.
A publisher app displays ads from registered ad networks. Add each ad network's ID to the app's Info.plist so its impressions qualify for install validation.
<key>AdNetworkIdentifiers</key>
<array>
<string>example123.adattributionkit</string>
<string>another456.adattributionkit</string>
</array>
Ad network IDs must be lowercase. SKAdNetwork IDs (ending in .skadnetwork)
are also accepted -- the frameworks share IDs.
For click-through custom-rendered ads, overlay a UIEventAttributionView on
the ad content. The system requires a tap on this view before handleTap()
succeeds.
import UIKit
let attributionView = UIEventAttributionView()
attributionView.frame = adContentView.bounds
attributionView.isUserInteractionEnabled = true
adContentView.addSubview(attributionView)
The advertised app is the app someone installs or re-engages with after seeing an ad. It must call a conversion value update at least once to begin the postback conversion window.
Add the AttributionCopyEndpoint key to Info.plist so the device sends a copy
of the winning postback to your server:
<key>AdAttributionKit</key>
<dict>
<key>AttributionCopyEndpoint</key>
<string>https://example.com</string>
</dict>
The system generates a well-known path from the domain:
https://example.com/.well-known/appattribution/report-attribution/
Configure your server to accept HTTPS POST requests at that path. The domain must have a valid SSL certificate.
Add a second key to also receive copies of winning re-engagement postbacks:
<key>AdAttributionKit</key>
<dict>
<key>AttributionCopyEndpoint</key>
<string>https://example.com</string>
<key>OptInForReengagementPostbackCopies</key>
<true/>
</dict>
Call a conversion value update as early as possible after first launch to begin the conversion window:
import AdAttributionKit
func applicationDidFinishLaunching() async {
do {
try await Postback.updateConversionValue(0, lockPostback: false)
} catch {
print("Failed to set initial conversion value: \(error)")
}
}
Ad networks create signed impressions using JWS (JSON Web Signature). The
publisher app uses AppImpression to register and handle those impressions.
import AdAttributionKit
let impression = try await AppImpression(compactJWS: signedJWSString)
The JWS contains the ad network ID, advertised item ID, publisher item ID, source identifier, timestamp, and optional re-engagement eligibility flag. See references/adattributionkit-patterns.md for JWS generation details.
guard AppImpression.isSupported else {
// Fall back to alternative ad display
return
}
Record a view impression when the ad content has been displayed and dismissed:
func handleAdViewed(impression: AppImpression) async {
do {
try await impression.handleView()
} catch {
print("Failed to record view-through impression: \(error)")
}
}
For long-lived ad views, use beginView() and endView() to track view
duration:
try await impression.beginView()
// ... ad remains visible ...
try await impression.endView()
Respond to ad taps by calling handleTap(). If the advertised app is not
installed, the system opens its App Store or marketplace page. If installed,
the system launches it directly.
func handleAdTapped(impression: AppImpression) async {
do {
try await impression.handleTap()
} catch {
print("Failed to record click-through impression: \(error)")
}
}
A UIEventAttributionView must overlay the ad for handleTap() to succeed.
Pass the impression to StoreKit overlay or product view controller APIs. StoreKit automatically records view-through impressions after 2 seconds of display and click-through impressions on tap.
import StoreKit
let config = SKOverlay.AppConfiguration(appIdentifier: "1234567890",
position: .bottom)
config.appImpression = impression
Postbacks are attribution reports the device sends to ad networks (and optionally to the advertised app developer) after a conversion event.
Three windows produce up to three postbacks for winning attributions:
| Window | Duration | Postback delay |
|---|---|---|
| 1st | Days 0-2 | 24-48 hours |
| 2nd | Days 3-7 | 24-144 hours |
| 3rd | Days 8-35 | 24-144 hours |
Tier 0 postbacks only produce the first postback. Nonwinning attributions produce only one postback.
| Event | Time limit |
|---|---|
| View-through to install | 24 hours (configurable up to 7 days) |
| Click-through to install | 30 days (configurable down to 1 day) |
| Install to first update | 60 days |
| Re-engagement to first update | 2 days |
Lock the postback to finalize a conversion value before the window ends and receive the postback sooner:
try await Postback.updateConversionValue(
42,
coarseConversionValue: .high,
lockPostback: true
)
After locking, the system ignores further updates in that conversion window.
| Field | Tier 0 | Tier 1 | Tier 2 | Tier 3 |
|---|---|---|---|---|
source-identifier digits | 2 | 2 | 2-4 | 2-4 |
conversion-value (fine) | -- | -- | 1st only | 1st only |
coarse-conversion-value | -- | 1st only | 2nd/3rd | 2nd/3rd |
publisher-item-identifier | -- | -- | -- | Yes |
country-code | -- | -- | -- | Conditional |
An integer from 0-63 (6 bits). Available only in the first postback and only at Tier 2 or higher:
try await Postback.updateConversionValue(
35,
coarseConversionValue: .medium,
lockPostback: false
)
Three levels for lower tiers and second/third postbacks:
// CoarseConversionValue cases: .low, .medium, .high
try await Postback.updateConversionValue(
10,
coarseConversionValue: .high,
lockPostback: false
)
Separate conversion values for install vs. re-engagement postbacks:
let installUpdate = PostbackUpdate(
fineConversionValue: 20,
lockPostback: false,
conversionTypes: [.install]
)
try await Postback.updateConversionValue(installUpdate)
let reengagementUpdate = PostbackUpdate(
fineConversionValue: 12,
lockPostback: false,
conversionTypes: [.reengagement]
)
try await Postback.updateConversionValue(reengagementUpdate)
Use conversion tags to selectively update specific postbacks when overlapping conversion windows exist:
let update = PostbackUpdate(
fineConversionValue: 15,
lockPostback: false,
conversionTag: savedConversionTag,
conversionTypes: [.reengagement]
)
try await Postback.updateConversionValue(update)
The system delivers the conversion tag through the re-engagement URL's
AdAttributionKitReengagementOpen query parameter.
Re-engagement tracks users who already have the advertised app installed and interact with an ad to return to it.
Set eligible-for-re-engagement to true in the JWS payload when generating
the impression.
Pass a universal link that the system opens in the advertised app:
let reengagementURL = URL(string: "https://example.com/promo/summer")!
try await impression.handleTap(reengagementURL: reengagementURL)
The system appends AdAttributionKitReengagementOpen as a query parameter. The
advertised app checks for this parameter to detect AdAttributionKit-driven
opens:
func handleUniversalLink(_ url: URL) {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
let isReengagement = components?.queryItems?.contains(where: {
$0.name == Postback.reengagementOpenURLParameter
}) ?? false
if isReengagement {
// AdAttributionKit opened this app via a re-engagement ad
}
}
AdAttributionKitReengagementOpen parameter is always present on the
URL, even when the system does not create a postback.// DON'T -- never updating the conversion value
func appDidLaunch() {
// No conversion value update; postback window never starts
}
// DO -- update conversion value on first launch
func appDidLaunch() async {
try? await Postback.updateConversionValue(0, lockPostback: false)
}
<!-- DON'T -->
<string>Example123.AdAttributionKit</string>
<!-- DO -->
<string>example123.adattributionkit</string>
// DON'T -- tap without attribution view overlay
try await impression.handleTap()
// Throws AdAttributionKitError.missingAttributionView
// DO -- ensure UIEventAttributionView covers the ad
let attributionView = UIEventAttributionView()
attributionView.frame = adView.bounds
adView.addSubview(attributionView)
// Then handle the tap after the user taps the attribution view
try await impression.handleTap()
// DON'T
try? await impression.handleTap()
// DO -- handle specific errors
do {
try await impression.handleTap()
} catch let error as AdAttributionKitError {
switch error {
case .impressionExpired:
// Impression older than 30 days
refreshAdImpression()
case .missingAttributionView:
// UIEventAttributionView not present
break
default:
print("Attribution error: \(error)")
}
}
// DON'T -- silently dropping the request
// The device retries up to 9 times over 9 days on HTTP 500
// DO -- respond with 200 OK immediately
// Server handler:
func handlePostback(request: Request) -> Response {
// Process asynchronously, respond immediately
Task { await processPostback(request.body) }
return Response(status: .ok)
}
AdNetworkIdentifiers
(lowercase)kidUIEventAttributionView overlays ad content for click-through adsupdateConversionValue on first launchpostback-identifierAppImpression.isSupported checked before attempting impression APIsまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Security audit, hardening, threat modeling (STRIDE/PASTA), Red/Blue Team, OWASP checks, code review, incident response, and infrastructure security for any project.
日本語の概要は準備中です。原文の説明を表示しています。
Guides the creation of agile user stories and Gherkin feature files. Use when the user wants to create a user story, write acceptance criteria, define Gherkin scenarios, or author BDD feature files. This should trigger for requests such as Create a user story; Write a user story; I need to write a user story. Part of cursor-rules-java project
日本語の概要は準備中です。原文の説明を表示しています。
Facilitates conversational discovery to create Architectural Decision Records (ADRs) for non-functional requirements using the ISO/IEC 25010:2023 quality model. Use when the user wants to document quality attributes, NFR decisions, security/performance/scalability architecture, or design systems with measurable quality criteria. This should trigger for requests such as Create ADR for Non-functional requirements; Document Non-functional requirements; Capture Non-functional requirements; Generate Non-functional requirements in an ADR. Part of cursor-rules-java project
日本語の概要は準備中です。原文の説明を表示しています。
Run a health check on an existing project: dependency audit, security scan, test runner detection, CI/CD evaluation, and missing configuration analysis. Maps the three execution gates (pre/in/post) from /10x-bootstrapper to an assessment framework for existing codebases. Reads optional context/foundation/stack-assessment.md from /10x-stack-assess to focus checks on identified gaps. Writes context/foundation/health-check.md with findings, prioritized fixes, and an agent-readiness verdict. Use when the user has an existing project and wants to verify its health before working with an agent. Trigger phrases: "health check", "check my project", "audit my project", "is my project healthy", "sprawdź projekt", "audyt projektu", "health-check", "project health". Use AFTER /10x-stack-assess (brownfield chain), BEFORE agent onboarding (m1-l4).
日本語の概要は準備中です。原文の説明を表示しています。
You MUST use this when building projects end-to-end. Orchestrates all 12 team roles — automatically switches between CTO, architect, PM, engineers, SRE, security, DBA, QA, and EM based on the current phase of work. Starts with brainstorming before any implementation.
日本語の概要は準備中です。原文の説明を表示しています。
Use when you need to add or configure Maven plugins in your pom.xml — including quality tools (enforcer, surefire, failsafe, jacoco, pitest, spotbugs, pmd), security scanning (OWASP), code formatting (Spotless), version management, container image build (Jib), build information tracking, and benchmarking (JMH) — through a consultative, modular step-by-step approach that only adds what you actually need. This should trigger for requests such as Add Maven plugins in pom.xml; Improve Maven plugins in pom.xml. Part of cursor-rules-java project
日本語の概要は準備中です。原文の説明を表示しています。