> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase28-session06-lifecycle-multiplier-and-named-contributions/spec.md).

# Session Specification

**Session ID**: `phase28-session06-lifecycle-multiplier-and-named-contributions` **Phase**: 28 - Trend Finder Trends-Finderz Adoption **Status**: Not Started **Created**: 2026-06-14

***

## 1. Session Overview

This session makes post-factor score adjustments explicit. Phase 28 has already landed confidence dampening, topic noise downrank, visibility bands, signal aging, and refined saturation. The remaining Tier 2 gap is that score movement after the six-factor weighted sum can be hard to audit: confidence and noise are stored as separate fields, while lifecycle still does not affect ranking at all.

The session adds a bounded lifecycle and aging multiplier that nudges final ranking without changing the six-factor core weights. The multiplier is narrow, clamped, and keyed to existing Trend Finder lifecycle labels plus Session 05 signal-aging status. Trends-Finderz lifecycle labels are calibration fixtures only; Trend Finder must keep the Phase 27 lifecycle taxonomy as the only payload vocabulary.

The session also establishes the named-contribution convention requested by the phase PRD. Confidence dampener, lifecycle multiplier, and topic noise downrank must all render as labeled adjustment rows in the schema, score breakdown UI, and Engine Replay scoring proof. This keeps the gap between raw weighted score and final score visible, browser-safe, and testable before Session 08 builds action verdicts on top of these adjusted scores.

***

## 2. Objectives

1. Add a bounded lifecycle and signal-aging score multiplier with clamps, calibrated against Trend Finder score scales and Trends-Finderz fixtures.
2. Add a legacy-safe `scoreAdjustments` array using `{label, delta, kind}` plus bounded metadata needed to explain post-factor changes.
3. Migrate confidence dampener and topic noise downrank into named contribution rows without removing their existing compatibility fields.
4. Render score adjustments in Trend Finder score breakdown and Engine Replay scoring proof with accessible, bounded labels and deterministic ordering.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase28-session03-calibration-version-and-confidence-dampener` - provides `SCORING_VERSION`, `rawOpportunityScore`, `sampleConfidence`, and confidence dampener fields to migrate into named rows.
* [x] `phase28-session04-topic-noise-gate-and-visibility-bands` - provides the topic noise downrank and visibility context to surface as named rows.
* [x] `phase28-session05-signal-aging-half-lives-and-saturation-refinement` - provides `signalAging` status and refined saturation inputs consumed by the lifecycle multiplier.
* [x] `phase27-session06-lifecycle-stage-taxonomy` - provides the current Trend Finder lifecycle taxonomy that this session consumes but does not replace.

### Required Tools/Knowledge

* Bun 1.3.14 package/runtime commands.
* TypeScript, Zod, Vitest, React 19, Tailwind CSS 4, and existing AI OS path aliases.
* Existing Trend Finder scoring, lifecycle, signal-aging, schema, view-model, score breakdown, Engine Replay, fixture, and documentation patterns.
* Trends-Finderz reference files: `EXAMPLES/trends-finderz/lib/trends/lifecycle.ts`, `EXAMPLES/trends-finderz/lib/product/intelligence-scoring.ts`, and `EXAMPLES/trends-finderz/lib/trends/scoring-transparency.ts`.

### Environment Requirements

* Run commands from the repository root.
* Keep generated private runtime data, cache files, screenshots, and source dumps out of commits.
* Do not add new source adapters, network calls, storage paths, third-party dependencies, analyst calls, credential flows, or a second lifecycle taxonomy.

***

## 4. Scope

### In Scope (MVP)

* Trend Finder can compute a narrow lifecycle and aging score multiplier keyed to existing lifecycle stage plus `signalAging.status`, clamped to the approved starter band of roughly 0.85-1.05.
* Trend Finder can publish named score contribution rows for confidence dampener, lifecycle multiplier, and topic noise downrank with additive schema defaults and a deterministic order.
* Trend Finder keeps the six-factor `scoreBreakdown` weights unchanged and keeps `rawOpportunityScore`, `sampleConfidence`, `confidenceDampenerDelta`, and `topicNoiseDownrank` as compatibility fields.
* Trend Finder recalculates final score from raw weighted score plus visible named adjustments so the raw-to-final gap is fully explained.
* Trend Finder score breakdown UI renders adjustment rows below the factor, velocity, and confidence context with bounded labels, delta values, tones, and accessible group labels.
* Engine Replay scoring proof renders adjustment rows alongside score factors without exposing prompts, raw source payloads, private paths, or unbounded strings.
* Tests cover multiplier bounds, adjustment recording, final-score reconciliation, Engine Replay counts, legacy parsing, and calibration fixtures proving no Trends-Finderz lifecycle vocabulary leaks into the payload.

### Out of Scope (Deferred)

* A new lifecycle taxonomy - *Reason: Phase 27 owns Trend Finder lifecycle stages; this session consumes existing labels only.*
* New weighted score factors or weight changes - *Reason: this session adds post-factor adjustments, not a seventh factor.*
* Free-text positive/negative driver narratives - *Reason: the MVP uses bounded labels and deltas only.*
* Research-only risk flag or cache retention - *Reason: Session 07 owns those derived-layer items.*
* Action verdicts, action consistency QA, or Action Queue UI - *Reason: Sessions 08-09 consume this session's named score adjustments.*
* New source collection, persistence, analyst calls, or third-party dependencies - *Reason: all work is deterministic over existing payload fields.*

***

## 5. Technical Approach

### Architecture

Add pure score-adjustment helpers in `scripts/lib/ai-runtime/scoring.ts`. Introduce a small internal representation for post-factor adjustments and a public score-adjustment payload row. The row should be additive, bounded, and safe for browser rendering. Recommended shape is an enum-backed schema with fields such as `key`, `label`, `delta`, `kind`, `detail`, and optional `multiplier`; the required PRD contract `{label, delta, kind}` must be present.

Score calculation should keep `rawScore = calculateOpportunityScore(breakdown)` as the six-factor weighted sum. Apply confidence dampening as a named adjustment, then lifecycle multiplier, then topic noise downrank, preserving the existing noise fallback caps. Compute the final score through a helper that also returns the ordered adjustment rows. The helper should reconcile the sum of deltas against the final score and clamp at each score boundary.

The lifecycle multiplier should use existing `lifecycle.stage` and `signalAging.status`. Suggested starting band is 0.85-1.05, with values calibrated against Trend Finder normalized scores rather than copied from Trends-Finderz. Positive pressure should be limited to fresh/active accelerating or building signals. Negative pressure should be limited to stale, saturated, or dormant-like combinations represented by existing Trend Finder labels and Session 05 aging status. The payload must not include `Emerging`, `Dormant`, or other Trends-Finderz lifecycle labels.

Add schema defaults in `src/extensions/trend-finder/schema.ts` with Zod `.default()` and `.catch()` behavior so old generated data parses to an empty adjustment list. Update `view-model.ts`, `score-breakdown.tsx`, and `engine-replay-model.ts` / `engine-score-panel.tsx` so adjustment rows are projected before rendering. Existing compatibility fields can continue to drive old labels until the UI is switched to the adjustment projection.

### Design Patterns

* Pure function, then tests, then wire: multiplier and adjustment reconciliation should be independently testable.
* Zod additive defaults: old generated payloads and fixtures parse without a migration.
* Browser-safe projection: expose bounded labels, deltas, enum kinds, and optional multiplier values only.
* Compatibility fields remain: keep existing dampener and noise fields for older consumers while making named rows the source of display truth.
* Deterministic order: confidence dampener, lifecycle multiplier, topic noise downrank, then future additive rows.

### Technology Stack

* Bun 1.3.14 for scripts and test execution.
* TypeScript for application and script code.
* Zod for payload parsing and legacy defaults.
* React 19 and Tailwind CSS 4 for UI changes.
* Vitest for script, schema, view-model, and component coverage.

***

## 6. Deliverables

### Files to Create

| File                                                         | Purpose                                                                                                    | Est. Lines |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | ---------- |
| `scripts/lib/ai-runtime/__tests__/score-adjustments.test.ts` | Unit tests for lifecycle multiplier bounds, adjustment ordering, reconciliation, and no vocabulary leakage | \~260      |

### Files to Modify

| File                                                                                                        | Changes                                                                                                              | Est. Lines |
| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------- |
| `scripts/lib/ai-runtime/scoring.ts`                                                                         | Add score-adjustment helpers, lifecycle multiplier, named rows, final-score reconciliation, and scoring version bump | \~260      |
| `scripts/lib/ai-runtime/__tests__/scoring.test.ts`                                                          | Cover scoring integration, ranking impact, final-score gap explanation, and unchanged six-factor weights             | \~180      |
| `scripts/lib/ai-runtime/__tests__/scoring-calibration.test.ts`                                              | Cover compatibility fields, dampener migration, multiplier clamps, and calibration version expectations              | \~160      |
| `src/extensions/trend-finder/schema.ts`                                                                     | Add score-adjustment enums, bounded row schema, defaults, parsed topic fields, and legacy-safe empty list            | \~180      |
| `src/lib/__tests__/trend-finder-schema.test.ts`                                                             | Cover legacy parsing, invalid adjustment fallback, row bounds, and default empty adjustments                         | \~100      |
| `src/extensions/trend-finder/view-model.ts`                                                                 | Add score-adjustment view models, labels, tones, delta formatting, and score reconciliation projection               | \~180      |
| `src/extensions/trend-finder/__tests__/view-model.test.ts`                                                  | Cover adjustment labels, ordering, tones, raw-to-final summary, and no unbounded text                                | \~120      |
| `src/extensions/trend-finder/components/score-breakdown.tsx`                                                | Render adjustment rows with accessible group labels while preserving compact layout and visibility controls          | \~120      |
| `src/extensions/trend-finder/components/__tests__/score-breakdown.test.tsx`                                 | Cover adjustment rendering, deltas, accessibility, compact mode, and legacy empty state                              | \~100      |
| `src/extensions/trend-finder/engine-replay-model.ts`                                                        | Add adjustment rows to Engine Replay score panel view model and trace-only fallback handling                         | \~140      |
| `src/extensions/trend-finder/components/engine-score-panel.tsx`                                             | Render Engine Replay adjustment rows with bounded labels and tones                                                   | \~100      |
| `src/lib/__tests__/trend-finder-engine-replay.test.tsx`                                                     | Cover Engine Replay named contributions and sanitized score proof output                                             | \~120      |
| `src/extensions/trend-finder/fixtures.ts`                                                                   | Add representative confidence, lifecycle, and noise adjustment fixture rows                                          | \~80       |
| `docs/extensions/trend-finder-scoring.md`                                                                   | Document shipped lifecycle multiplier, named contributions, compatibility fields, and non-goals                      | \~90       |
| `.spec_system/specs/phase28-session06-lifecycle-multiplier-and-named-contributions/implementation-notes.md` | Record decisions, multiplier constants, validation commands, and residual risks during implementation                | \~80       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] A fresh accelerating topic can receive a small bounded lifecycle boost, while a stale or dormant-like topic can receive a bounded penalty.
* [ ] Lifecycle multiplier output stays within the approved starter band and is clamped even for malformed or missing lifecycle and aging inputs.
* [ ] Every post-factor adjustment appears as a named row with `{label, delta, kind}` in the parsed payload.
* [ ] Confidence dampener, lifecycle multiplier, and topic noise downrank explain the full gap between raw weighted score and final score.
* [ ] The six-factor core weights and factor keys are unchanged.
* [ ] Score breakdown and Engine Replay render adjustment rows with bounded labels, delta values, tones, and accessible group labels.
* [ ] Trends-Finderz lifecycle labels do not appear in Trend Finder payloads, fixtures, or UI.
* [ ] Legacy payloads parse with an empty adjustment list and existing compatibility fields remain available.

### Testing Requirements

* [ ] Unit tests written and passing for lifecycle multiplier bounds, malformed inputs, adjustment ordering, and final-score reconciliation.
* [ ] Scoring integration tests cover ranking impact, dampener/noise migration, unchanged weights, and calibration-version bump.
* [ ] Schema tests cover legacy defaults, invalid row fallback, bounded labels, bounded deltas, and empty arrays.
* [ ] View-model and component tests cover adjustment projection, compact UI, accessibility labels, and empty adjustment states.
* [ ] Engine Replay tests cover named contribution rendering and sanitized browser-safe output.
* [ ] Manual testing completed for Trend cards and Engine Replay scoring proof.

### Non-Functional Requirements

* [ ] No new dependencies, source adapters, storage paths, external calls, analyst calls, credential flows, or admin write surfaces are introduced.
* [ ] Browser-visible adjustment rows stay bounded and do not expose raw evidence payloads, private paths, prompts, logs, billing, or provider responses.
* [ ] Existing generated payload and fixture parsing remains backwards compatible.
* [ ] The shared Trend Finder payload remains within the existing 1 MB release budget.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Focused Vitest suites pass.
* [ ] Documentation describes shipped behavior only.

***

## 8. Implementation Notes

### Key Considerations

* `SCORING_VERSION` is currently `trend-finder-scoring-v28.5`; this score math change should bump it so movement and retro comparisons can flag cross-version comparisons.
* Existing compatibility fields should remain because current UI, docs, and tests already reference `rawOpportunityScore`, `sampleConfidence`, `confidenceDampenerDelta`, and `topicNoiseDownrank`.
* The score-adjustment list should be the display source for new UI while compatibility fields keep old payloads safe.
* Noise fallback caps in fallback mode must still apply after named adjustment recording.

### Potential Challenges

* Lifecycle is currently derived after final score. Mitigation: derive the lifecycle from the pre-lifecycle adjusted score or make lifecycle independent enough to avoid a feedback loop, then document that order in implementation notes.
* Multiplier deltas are percentage based while other adjustments are additive. Mitigation: store the realized delta in `delta` and optional multiplier metadata for display.
* Final score reconciliation can drift due to rounding and clamps. Mitigation: use one helper to compute score and rows, and test rounded deltas against the final raw-to-score gap.

### Relevant Considerations

* \[P01] **Extract pure functions, then test, then wire**: Apply this to the lifecycle multiplier and adjustment reconciliation before UI work.
* \[P02] **Extension payloads and labels stay bounded**: Keep adjustment arrays, labels, detail strings, and deltas bounded.
* \[P05] **Script-only runtime boundary**: Scoring math stays in `scripts/lib/ai-runtime/`; browser code consumes validated fields only.
* \[P24] **Browser-safe export and triage boundaries**: Adjustment display must not expose raw evidence or private runtime material.
* \[P27] **Trend Finder payload growth needs release checks**: Keep adjustment row count small and include payload-size awareness in validation.
* \[P27] **Reference manuals track shipped behavior only**: Documentation updates must describe implemented multiplier and contribution rows, not future action verdicts.
* \[P27] **Deterministic fallback before AI enrichment**: All contribution rows are deterministic and require no new AI calls.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Score adjustments could silently diverge from final score if rows and score are computed in separate places.
* Missing or legacy lifecycle and signal-aging fields could produce inflated scores unless defaults are neutral.
* UI rows could imply unbounded precision or hide negative adjustments in compact layouts.

***

## 9. Testing Strategy

### Unit Tests

* Test lifecycle multiplier bounds for fresh/active/rising, stale/cooling, saturated, missing lifecycle, missing signal aging, and malformed inputs.
* Test adjustment row ordering, label bounds, delta rounding, kind enum values, and raw-to-final reconciliation.
* Test no Trends-Finderz lifecycle labels appear in payload rows or fixtures.

### Integration Tests

* Test `scoreTrendTopics()` publishes named rows for confidence dampener, lifecycle multiplier, and topic noise downrank.
* Test a stale topic no longer outranks a fresh accelerating topic purely on stale weighted sum when comparable raw scores are present.
* Test legacy payload parsing and fixture compatibility through schema tests.
* Test Engine Replay model and component rendering of adjustment rows.

### Manual Testing

* Run focused Vitest suites for scoring, schema, view-model, score breakdown, and Engine Replay.
* Inspect Trend card score breakdown and Engine Replay scoring proof with a fixture topic that has all three adjustment types.
* Confirm compact layout does not overflow and negative/positive deltas remain visible.

### Edge Cases

* Empty adjustment list on legacy payloads.
* A neutral lifecycle multiplier of 1.0 should not create noisy zero rows unless the row is useful for full reconciliation.
* Multiple clamps in one score path should not produce a final score outside 0-100.
* Fallback-mode noise caps must still hold after named adjustment recording.
* Missing signal aging or lifecycle data must yield a neutral multiplier.

***

## 10. Dependencies

### External Libraries

* None.

### Other Sessions

* **Depends on**: `phase28-session03-calibration-version-and-confidence-dampener`, `phase28-session04-topic-noise-gate-and-visibility-bands`, `phase28-session05-signal-aging-half-lives-and-saturation-refinement`, and `phase27-session06-lifecycle-stage-taxonomy`.
* **Depended by**: `phase28-session07-research-only-calibration-and-cache-retention` for continued Tier 2 derived-layer quality, `phase28-session08-action-verdicts-and-consistency-qa` for adjusted-score inputs, and `phase28-session15-documentation-validation-and-release` for final documentation and release validation.

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase28-session06-lifecycle-multiplier-and-named-contributions/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
