diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8138941 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# CODEOWNERS file for managing repository permissions +# Format: path-pattern @username @org/team-name + +# Maintainers: Default owners for all files +* @roostorg/roosters + diff --git a/README.md b/README.md index b3db2f3..31ebfb1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Example [COOP](https://github.com/roostorg/coop) integration plugin. Reference r - **Integration:** `COOP_INTEGRATION_EXAMPLE` - **Signal 1 – Random Signal Selection** (`RANDOM_SIGNAL_SELECTION`): Returns `true` or `false` at random. The probability (0–100%) comes from the org’s integration config (“True percentage”). Set e.g. `70` in Org settings → Integrations; the signal returns `true` about 70% of the time. Use this to test config saving and boolean conditions. -- **Signal 2 – Random Score** (`RANDOM_SCORE`): Returns a random number between 0 and 1. No integration config needed. In the rule builder you set a **threshold** (e.g. `0.5`) and choose **above** or **below**. Use this to test numeric score conditions (e.g. “score ≥ 0.5” or “score < 0.3”). +- **Signal 2 – Random Score** (`RANDOM_SCORE`): Returns a random number from **0 up to (but not including) 100**—the same 0–100 style as “True percentage,” so thresholds feel consistent. No integration config needed. In the rule builder set a **threshold** (e.g. `50`) and choose **above** or **below**. Use this to test numeric score conditions (e.g. “score ≥ 50” or “score < 30”). ## Install @@ -61,17 +61,17 @@ Restart the COOP server so it loads the plugin. 1. **Org settings → Integrations** – you should see “COOP Integration Example”. Open it and set **True percentage (0–100)** (e.g. `70`) for Random Signal Selection. Save. 2. **Rules (routing or enforcement)** – when adding a condition: - **Random Signal Selection**: Pick that signal; the condition uses your configured percentage (true/false). - - **Random Score**: Pick “Random Score”, then set a **threshold** (e.g. `0.5`) and choose **above** or **below**. The rule compares the random score to your threshold. + - **Random Score**: Pick “Random Score”, then set a **threshold** on the 0–100 scale (e.g. `50`) and choose **above** or **below**. The rule compares the random score to your threshold. ## Contract This package implements the COOP plugin contract from `@roostorg/types`: - **Default export:** `CoopIntegrationPlugin` with `manifest` and `createSignals(context)`. -- **Manifest:** `id`, `name`, `version`, `requiresConfig`, `configurationFields`, `signalTypeIds`, `modelCard` (with required sections `modelDetails` and `technicalIntegration`). +- **Manifest:** `id`, `name`, `version`, `requiresConfig`, `configurationFields`, `signalTypeIds`, `modelCard` (must include every section id in `REQUIRED_MODEL_CARD_SECTION_IDS` from `@roostorg/types`; call `assertModelCardHasRequiredSections(modelCard)` when registering). - **createSignals:** Returns two descriptors: - `RANDOM_SIGNAL_SELECTION`: `run(input)` uses `context.getCredential(orgId)` for true percentage; returns `{ outputType: { scalarType: 'BOOLEAN' }, score: boolean }`. - - `RANDOM_SCORE`: `run()` returns `{ outputType: { scalarType: 'NUMBER' }, score: number }` in [0, 1]; no config. Threshold is set in the rule (above/below). + - `RANDOM_SCORE`: `run()` returns `{ outputType: { scalarType: 'NUMBER' }, score: number }` in **[0, 100)** (`Math.random() * 100`); no config. Threshold is set in the rule on the same scale (above/below). ## Publishing diff --git a/package-lock.json b/package-lock.json index 50e4a19..2f537f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,22 @@ { "name": "@roostorg/coop-integration-example", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@roostorg/coop-integration-example", - "version": "1.0.0", - "license": "ISC", + "version": "2.0.0", + "license": "Apache-2.0", "devDependencies": { - "@roostorg/types": "^1.1.1", + "@roostorg/types": "^2.0.0", "typescript": "^5.0.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@roostorg/types": ">=1.0.0" + "@roostorg/types": ">=2.0.0" } }, "node_modules/@babel/runtime": { @@ -30,9 +30,9 @@ } }, "node_modules/@roostorg/types": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@roostorg/types/-/types-1.1.1.tgz", - "integrity": "sha512-NhPYlG27wAQaD7AzWkL3LJHu52/QfK8lt9QMahUx7fbRtB4fYILy4fGcLQvt45gNQANoU78evW1UJftAB0B89Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@roostorg/types/-/types-2.0.0.tgz", + "integrity": "sha512-EyLecshJqiZdughsBgaJcR6nOmZ6cT5ioNeRB1Cif6b0ZrXc9LfBirXd2FPZ1qzxxIjgMUOA1HSxfFVThMRZlw==", "dev": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 6ed011c..7c4eb91 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@roostorg/coop-integration-example", - "version": "1.0.0", + "version": "2.0.0", "description": "Example package to show how a custom integration and signal can be used in COOP this is meant to be a reference repository and provide basic determination", "type": "module", "main": "dist/index.js", @@ -23,7 +23,7 @@ "example" ], "author": "Roostorg", - "license": "apache-2.0", + "license": "Apache-2.0", "repository": { "type": "git", "url": "https://github.com/roostorg/coop-integration-example.git" @@ -33,10 +33,10 @@ }, "homepage": "https://github.com/roostorg/coop-integration-example#readme", "peerDependencies": { - "@roostorg/types": ">=1.0.0" + "@roostorg/types": ">=2.0.0" }, "devDependencies": { - "@roostorg/types": "^1.1.1", + "@roostorg/types": "^2.0.0", "typescript": "^5.0.0" }, "engines": { diff --git a/src/index.ts b/src/index.ts index 2f7c9aa..bcf5684 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,16 @@ /** * Example COOP integration plugin with two signal types: * 1. Random Signal Selection – boolean, probability from org config (tests config saving). - * 2. Random Score – numeric [0, 1], threshold set in the rule (tests score vs threshold). + * 2. Random Score – numeric 0–100, threshold set in the rule (tests score vs threshold). */ -import type { - CoopIntegrationPlugin, - IntegrationManifest, - ModelCard, - PluginSignalContext, - PluginSignalDescriptor, +import { + assertModelCardHasRequiredSections, + type CoopIntegrationPlugin, + type IntegrationManifest, + type ModelCard, + type PluginSignalContext, + type PluginSignalDescriptor, } from '@roostorg/types'; const SIGNAL_TYPE_RANDOM_SELECTION = 'RANDOM_SIGNAL_SELECTION'; @@ -19,49 +20,111 @@ const DEFAULT_TRUE_PERCENTAGE = 50; const modelCard: ModelCard = { modelName: 'COOP Integration Example', - version: '1.0.0', - releaseDate: '2026', + version: '2.0.0', + releaseDate: 'March 2026', sections: [ { - id: 'modelDetails', - title: 'Model Details', + id: 'trainingData', + title: 'Training Data', fields: [ - { label: 'Model Name', value: 'COOP Integration Example' }, { - label: 'Purpose', + label: 'Overview', value: - 'Example plugin with two signals: one uses org config (boolean), one returns a numeric score so you can set a threshold in the rule (over/under).', + 'This reference integration does not use a trained model. Outputs are randomly generated for demonstration and testing of COOP rules, configuration, and UI only.', }, + ], + }, + { + id: 'policyAndTaxonomy', + title: 'Policy and Taxonomy', + fields: [ + { + label: 'Scope', + value: + 'Not a content policy engine. Signals are placeholders: boolean “coin flip” with configurable probability and a numeric random score for threshold exercises in rules.', + }, + ], + }, + { + id: 'annotationMethodology', + title: 'Annotation Methodology', + fields: [ + { + label: 'Method', + value: + 'No human or automated labeling pipeline. Values are produced with Math.random() (or equivalent logic) at evaluation time.', + }, + ], + }, + { + id: 'performanceBenchmarks', + title: 'Performance and Benchmarks', + fields: [ + { + label: 'Benchmarks', + value: + 'No precision, recall, or latency benchmarks apply. Do not use performance claims from this package in production decisions.', + }, + ], + }, + { + id: 'biasAndLimitations', + title: 'Bias and Limitations', + fields: [ + { + label: 'Limitations', + value: + 'Outputs are uncorrelated with input content. Unsuitable for safety, compliance, or moderation decisions. For integration testing and developer learning only.', + }, + ], + }, + { + id: 'implementationGuidance', + title: 'Implementation Guidance', + fields: [ { label: 'Signals', - value: `${SIGNAL_TYPE_RANDOM_SELECTION} (boolean, config-driven) and ${SIGNAL_TYPE_RANDOM_SCORE} (number 0–1, threshold in rule).`, + value: `${SIGNAL_TYPE_RANDOM_SELECTION} (boolean; org config truePercentage 0–100). ${SIGNAL_TYPE_RANDOM_SCORE} (number 0–100; set threshold and above/below in the rule).`, + }, + { + label: 'Configuration', + value: + 'Random Signal Selection requires org integration config (true percentage). Random Score requires no integration config.', + }, + { + label: 'Versioning', + value: + 'modelCard.version and manifest.version identify this integration plugin release. They are independent of the @roostorg/types dependency major version (e.g. 2.x).', }, ], }, { - id: 'technicalIntegration', - title: 'Technical Integration', + id: 'relevantLinks', + title: 'Relevant Links', fields: [ { - label: 'Signal types', - value: `${SIGNAL_TYPE_RANDOM_SELECTION}, ${SIGNAL_TYPE_RANDOM_SCORE}`, + label: 'Repository', + value: 'https://github.com/roostorg/coop-integration-example', }, { - label: 'Config', - value: 'truePercentage (0–100) for Random Signal Selection only; Random Score needs no config.', + label: 'Documentation', + value: 'https://roostorg.github.io/coop/INTEGRATIONS_PLUGIN.html', }, ], }, ], }; +assertModelCardHasRequiredSections(modelCard); + const manifest: IntegrationManifest = { id: INTEGRATION_ID, name: 'COOP Integration Example', - version: '1.0.0', + /** Same semver as modelCard.version: this plugin’s release, not @roostorg/types. */ + version: '2.0.0', description: 'Example plugin with two signals: config-driven boolean and a numeric score you compare with a threshold in the rule.', - docsUrl: 'https://github.com/roostorg/coop/tree/main/coop-integration-example', + docsUrl: 'https://roostorg.github.io/coop/INTEGRATIONS_PLUGIN.html', requiresConfig: true, configurationFields: [ { @@ -158,11 +221,11 @@ function createRandomScoreDescriptor( id: { type: SIGNAL_TYPE_RANDOM_SCORE }, displayName: 'Random Score', description: - 'Returns a random number between 0 and 1. Set a threshold in the rule (e.g. 0.5) and choose "above" or "below" to test numeric conditions.', + 'Returns a random number from 0 up to (but not including) 100. Set a threshold in the rule (e.g. 50) and choose "above" or "below" to test numeric conditions.', docsUrl: null, recommendedThresholds: { - highPrecisionThreshold: 0.5, - highRecallThreshold: 0.5, + highPrecisionThreshold: 50, + highRecallThreshold: 50, }, supportedLanguages: 'ALL', pricingStructure: { type: 'FREE' }, @@ -178,8 +241,7 @@ function createRandomScoreDescriptor( async run( _input: unknown, ): Promise<{ outputType: typeof outputType; score: number }> { - // Returns a random number between 0 and 100. - // Because outputType is { scalarType: 'NUMBER' }, Coop can take the score and compare it to a threshold in the rule. + // [0, 100) — same scale as percentages elsewhere in this plugin (e.g. truePercentage). const score = Math.random() * 100; return { outputType, score }; },