revrec-saas — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited revrec-saas (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You generate a production-grade revenue recognition engine. ASC 606 (Topic 606) and IFRS 15 are converged standards — same five-step model — applied differently to SaaS than to product sales. Getting it wrong is a material weakness; getting it right earns a clean audit.
The core rule: revenue is recognized when (or as) you satisfy a performance obligation, not when cash is received. A customer paying $12k for an annual subscription generates $1k/month of recognized revenue, not $12k on day one. The contract value sits in deferred revenue until performed.
============================================================ === PRE-FLIGHT === ============================================================
Verify:
Recovery:
============================================================ === PHASE 1: STEP 1 — IDENTIFY THE CONTRACT === ============================================================
ASC 606 contract criteria (must meet ALL):
Generate contract.py capturing:
@dataclass
class Contract:
id: str
customer_id: str
signed_date: date
start_date: date
end_date: date # subscription term
contract_value_committed: Decimal # MRR × months OR fixed total
payment_terms: PaymentTerms
auto_renews: bool
cancellation_terms: CancellationTerms
related_contracts: list[str] # for combined-contracts analysisContract combination rule: separate written contracts may need to be combined if (a) negotiated as a package, (b) consideration in one depends on the other, or (c) services are a single PO. Flag this on signed-date proximity (within 30 days) for human review.
VALIDATION: Contract object captures collectibility assessment. Combination candidates flagged.
============================================================ === PHASE 2: STEP 2 — IDENTIFY PERFORMANCE OBLIGATIONS === ============================================================
A performance obligation is a distinct promise. Test for distinct:
Common SaaS PO splits:
| Item | Typical PO treatment |
|---|---|
| Subscription access | Single PO — series of distinct daily services, recognized over time |
| Implementation services | If material modification of platform → bundled with subscription; if standalone capability → separate PO |
| Data migration | Usually bundled (no value without subscription) |
| Training | Often separate PO if generic; bundled if proprietary |
| Customer success / CSM | Usually subsumed into subscription (no standalone value) |
| Custom development | Separate PO if customer takes title to IP |
| Premium support tier | Separate PO (distinct value) |
| Setup fee (non-refundable) | Not a PO — material right or up-front payment → recognized over expected customer life |
Generate performance_obligations.py that takes a contract and outputs a list of PO records with recognition_pattern enum: OVER_TIME_RATABLE, OVER_TIME_USAGE, OVER_TIME_INPUT_METHOD, POINT_IN_TIME.
VALIDATION: Standard subscription = 1 PO recognized ratably. Implementation w/ standalone value = 2 POs.
============================================================ === PHASE 3: STEP 3 — DETERMINE TRANSACTION PRICE === ============================================================
Total consideration the entity expects, including:
Generate transaction_price.py with:
def determine_transaction_price(contract: Contract, usage_forecast: UsageForecast) -> Decimal:
fixed = contract.committed_value
variable = constrained_expected_value(usage_forecast)
financing_adj = discount_if_significant(contract.payment_terms)
rebates = contract.consideration_payable_to_customer
return fixed + variable - rebates + financing_adjVALIDATION: Variable consideration is constrained (not booked at gross-optimistic value).
============================================================ === PHASE 4: STEP 4 — ALLOCATE TO POs === ============================================================
If contract has multiple POs, allocate transaction price using standalone selling prices (SSP):
Generate ssp_calculator.py that pulls observed sale prices from billing platform history and computes per-item SSP. Allocation formula:
allocated_price_PO_i = transaction_price × (ssp_PO_i / sum(ssp_all_POs))VALIDATION: Allocation sums to transaction price. SSP basis documented per PO (observable / adjusted-market / cost-plus / residual).
============================================================ === PHASE 5: STEP 5 — RECOGNIZE AS POs ARE SATISFIED === ============================================================
For OVER_TIME POs (subscription), pro-rate over the service period:
revenue_per_day = allocated_price / total_service_days
recognized_revenue_period = revenue_per_day × days_in_period
deferred_revenue_remaining = allocated_price - cumulative_recognizedFor POINT_IN_TIME POs (e.g., one-time license, where customer gains control), recognize the full allocated amount when delivered/transferred.
For USAGE-BASED POs, recognize as usage is consumed.
Generate recognition_engine.py that takes contract + as-of date + previously recognized + usage data → emits new revenue and updated deferred balance per PO.
Generate journal entries (double-entry):
| Event | Dr | Cr |
|---|---|---|
| Invoice issued (annual prepaid) | A/R | Deferred revenue |
| Cash collected | Cash | A/R |
| Month-end revenue recognition (1/12 of subscription) | Deferred revenue | Subscription revenue |
| Commission paid (capitalized per ASC 340-40) | Contract acquisition cost asset | Cash |
| Commission amortization | Sales & marketing expense | Contract acquisition cost asset |
| Contract modification (mid-term upgrade) | (depends on type — see Phase 6) |
VALIDATION: Deferred revenue balance reconciles: deferred = sum(invoiced_to_date) − sum(recognized_to_date) − sum(refunds_to_date).
============================================================ === PHASE 6: CONTRACT MODIFICATIONS === ============================================================
Mid-contract changes get one of three treatments:
Common cases:
Generate modifications.py that classifies and computes the right adjustment.
VALIDATION: Each modification path tested with a fixture (upgrade, add-seats, downgrade, cancel).
============================================================ === PHASE 7: COMMISSIONS (ASC 340-40) === ============================================================
Sales commissions paid to obtain a contract are capitalized if the amortization period > 1 year (practical expedient for shorter periods). Amortize over expected customer life, not just initial contract term.
Generate commissions.py:
VALIDATION: Asset balance reconciles to expected-life amortization schedule.
============================================================ === PHASE 8: DISCLOSURES === ============================================================
ASC 606 footnote requirements:
Generate disclosures.md template with placeholders auto-filled from the engine's state.
VALIDATION: Disclosures cover all five required categories.
============================================================ === SELF-REVIEW === ============================================================
Score 1–5:
Common gap: treating non-refundable setup fees as POs. They're material-right / up-front consideration recognized over expected customer life, not at contract start.
============================================================ === LEARNINGS CAPTURE === ============================================================
Append to ~/.claude/skills/revrec-saas/LEARNINGS.md:
============================================================ === STRICT RULES === ============================================================
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.