diff --git a/.agents/skills/prepare-package-release/SKILL.md b/.agents/skills/prepare-package-release/SKILL.md new file mode 100644 index 0000000..4a84985 --- /dev/null +++ b/.agents/skills/prepare-package-release/SKILL.md @@ -0,0 +1,114 @@ +--- +name: prepare-package-release +description: Prepare and validate Rudder plugin version bumps, including synchronized package/plugin manifests and a CodeAlmanac wiki refresh. Use whenever changing the version in package.json, package-lock.json, .codex-plugin/plugin.json, .claude-plugin/plugin.json, or .claude-plugin/marketplace.json; when asked to bump, cut, or prepare a Rudder release; or when reviewing a branch that already contains a version bump. +--- + +# Prepare Package Release + +Keep the release version synchronized, update the repository wiki from the +complete release diff, and leave tag and artifact creation to the publish +workflow. + +## Follow the workflow + +1. Inspect `git status`, the branch diff against `origin/main`, `package.json`, + the plugin manifests, and the current release guidance: + + ```bash + git fetch origin main --tags + git diff --stat origin/main...HEAD + codealmanac show guides/release/prepare-package-release + ``` + +2. Confirm the intended semantic version. + Treat `package.json` as the release version source of truth. + Ask the user if the task does not establish the bump level. + +3. Run npm's version command without creating a commit or tag: + + ```bash + npm version --no-git-tag-version + ``` + + Synchronize that exact version in: + + - `package-lock.json` at the root `version` and `packages[""].version`; + - `.codex-plugin/plugin.json`; + - `.claude-plugin/plugin.json`; + - `.claude-plugin/marketplace.json` at both the plugin version and npm source + version. + + Do not create or push a release tag. + The publish workflow creates the tag and GitHub Release after merge. + +4. Find the previous release tag after the manifests are synchronized: + + ```bash + previous_release_tag="$( + git describe --tags --match 'rudder-plugin-v*' --abbrev=0 + )" + release_range="${previous_release_tag}..HEAD" + ``` + + Stop and ask the user if no previous release tag exists. + Do not use `origin/main` as the source boundary. + Merged changes since the previous tag still belong to the release. + +5. Run CodeAlmanac Ingest for every version bump. + Give it the complete committed release range plus staged and unstaged edits: + + ```bash + guidance="Update durable release knowledge and version claims." + guidance+=" A no-op is valid." + codealmanac ingest "git:range:${release_range}" git:diff \ + --title "Document Rudder release " \ + --guidance "$guidance" + ``` + + Wait for the ingest job to finish. + Use `codealmanac jobs attach ` if the command returns early. + +6. Run Garden after Ingest. + Ingest defines the release source boundary. + Garden reconciles that knowledge with the rest of the wiki: + + ```bash + codealmanac garden \ + --title "Garden after Rudder release " \ + --guidance "Reconcile the wiki after ingesting ${release_range}." + ``` + + Wait for the Garden job to finish or attach to its run ID. + Review all resulting `almanac/**/*.md` and `almanac/topics.yaml` changes. + Accept a no-op when the release adds no durable knowledge. + Do not manufacture a wiki edit solely to record a version number. + +7. Validate the wiki and package: + + ```bash + codealmanac validate + npm run typecheck + npm test + npm run build + ``` + + Also run `npm run format:markdown:check` when CodeAlmanac changed Markdown. + +8. Review the complete diff: + + ```bash + git diff --check + git diff --stat origin/main...HEAD + git diff + ``` + + Confirm all version-bearing manifests match `package.json`, CodeAlmanac + completed successfully or explicitly made a valid no-op, no local release + tag was created, and generated `dist/` output is not included. + +## Report the result + +State the old and new versions, list synchronized manifests, summarize the +CodeAlmanac outcome and any wiki pages changed, report wiki/package validation, +and note that publishing, tagging, and GitHub Release creation occur after +merge. diff --git a/.agents/skills/prepare-package-release/agents/openai.yaml b/.agents/skills/prepare-package-release/agents/openai.yaml new file mode 100644 index 0000000..e474400 --- /dev/null +++ b/.agents/skills/prepare-package-release/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Prepare Package Release" + short_description: "Bump package versions and refresh Almanac docs" + default_prompt: "Use $prepare-package-release to prepare this version bump and refresh the CodeAlmanac wiki." diff --git a/almanac/architecture/automation/contributor-automation.md b/almanac/architecture/automation/contributor-automation.md index c005bbd..5c736dd 100644 --- a/almanac/architecture/automation/contributor-automation.md +++ b/almanac/architecture/automation/contributor-automation.md @@ -12,6 +12,9 @@ sources: - id: comments-skill type: file path: .agents/skills/address-pr-comments/SKILL.md + - id: release-skill + type: file + path: .agents/skills/prepare-package-release/SKILL.md - id: package type: file path: package.json @@ -26,7 +29,7 @@ sources: path: dangerfile.ts --- -Rudder's contributor automation is a set of local and CI gates for a repository that currently has one root plugin package and centralized agent workflows. `.agents/skills/` is the only reusable-workflow source, with `.claude/skills` and `.codex/skills` as compatibility symlinks [@agents-readme]. The `check-changed-folders` skill compares the branch with `origin/main`, verifies the centralized agent-instruction layout, verifies agent attribution, runs the package checks, and then invokes PR-comment remediation when a PR exists [@check-skill]. GitHub Actions repeats package validation on branch pushes, while the Danger workflow enforces protected paths and inline agent guards for agent-authored pull requests [@test-workflow] [@danger-workflow] [@dangerfile]. +Rudder's contributor automation is a set of local and CI gates for a repository that currently has one root plugin package and centralized agent workflows. `.agents/skills/` is the only reusable-workflow source, with `.claude/skills` and `.codex/skills` as compatibility symlinks [@agents-readme]. The `check-changed-folders` skill validates branches, verifies layout and attribution, runs local package checks, and delegates PR-comment remediation when a PR exists [@check-skill]. The `prepare-package-release` skill synchronizes package and plugin versions, ingests the complete range since the previous release, Gardens the whole CodeAlmanac wiki, and validates the prepared release [@release-skill]. GitHub Actions repeats package validation on branch pushes, while the Danger workflow enforces protected paths and inline agent guards for agent-authored pull requests [@test-workflow] [@danger-workflow] [@dangerfile]. ## Local Check Surface @@ -38,7 +41,7 @@ Before package checks, the local flow also checks that each coding agent represe ## Package Checks -After layout and attribution checks, the local flow installs dependencies with `npm install` only when `node_modules/` is missing, then runs `npm run typecheck`, `npm test`, and `npm run build` [@check-skill]. The Test workflow uses the CI equivalent plus layout and Markdown checks: checkout, Node 24 setup, `npm ci`, `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm test`, and `npm run build` on Ubuntu [@test-workflow]. The exact command meanings are listed in [Package Scripts](../../reference/tooling/package-scripts), while [GitHub Workflows](../../reference/automation/github-workflows) records CI triggers and permissions. +After layout and attribution checks, the local flow installs dependencies with `npm install` only when `node_modules/` is missing, then runs `npm run typecheck`, `npm test`, and `npm run build` [@check-skill]. The Test workflow adds the CI coverage boundary: it checks out full history, sets up Node 24, runs `npm ci`, checks agent layout and Markdown, typechecks, runs `npm run test:coverage` with a 90% changed-line threshold, and rebuilds on Ubuntu [@test-workflow] [@package]. The exact command meanings are listed in [Package Scripts](../../reference/tooling/package-scripts), while [GitHub Workflows](../../reference/automation/github-workflows) records CI triggers and permissions. ## PR Comment Remediation @@ -46,6 +49,12 @@ The check flow delegates open PR feedback to a separate `address-pr-comments` sk That remediation flow has its own validation boundary. If it applies any fixes, it reruns `npm run typecheck`, `npm test`, and `npm run build`, but it does not invoke the full check flow again because that would re-enter the PR-comment workflow [@comments-skill]. The [Address PR Comments](../../guides/contributor/address-pr-comments) guide gives the operational procedure without duplicating the architecture here. +## Release Preparation + +Release preparation has a dedicated workflow because one package version is repeated across the npm package, lockfile, Codex and Claude plugin manifests, and Claude marketplace metadata [@release-skill]. The skill treats `package.json` as authoritative, uses npm's no-tag version command, copies the exact result into every version-bearing manifest, and leaves tag creation to post-merge release automation [@release-skill]. + +The workflow finds the previous `rudder-plugin-v*` tag and uses the range from that tag through `HEAD` as Ingest's committed source boundary, alongside staged and unstaged changes [@release-skill]. This includes already-merged work that an `origin/main` branch diff would omit. Garden then reconciles the ingested release knowledge across the whole wiki [@release-skill]. Either job may validly produce no wiki changes when the release contains no durable knowledge. The prepared release is complete only after both the package checks and `codealmanac validate` pass [@release-skill]. The [Prepare Package Release](../../guides/release/prepare-package-release) guide provides the operational sequence. + ## Agent Guards `dangerfile.ts` protects `README.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `LICENSE`, `CLAUDE.md`, `docs/**`, `assets/**`, `.claude/**`, `.codex/**`, and `.cursor/**` from agent-authored pull request changes [@dangerfile]. It detects agent authorship from the PR author, commit author names and emails, and `Co-authored-by` trailers [@dangerfile]. The Danger workflow runs `npm run danger:ci` on pull requests to `main` after installing dependencies on Node 24 [@danger-workflow] [@package]. diff --git a/almanac/architecture/release/release-automation.md b/almanac/architecture/release/release-automation.md index c7766b5..72fcf29 100644 --- a/almanac/architecture/release/release-automation.md +++ b/almanac/architecture/release/release-automation.md @@ -28,7 +28,7 @@ The publish workflow runs on pushes to `main` and on manual dispatch, with a sin Those checks create separate flags for each artifact. A missing npmjs.org version enables npm publishing, a missing tag enables tag creation, and a missing GitHub Release enables release creation [@publish-workflow]. When any artifact is missing, the job upgrades npm, installs dependencies with `npm ci`, writes release telemetry defaults into `src/telemetry-build-config.ts`, validates the plugin package with `DO_NOT_TRACK=1`, publishes to npmjs.org when needed with Trusted Publishing, pushes the plugin tag when needed, and creates the GitHub Release with generated notes when needed [@publish-workflow]. -The package scripts are part of that path because the publish workflow validates with `npm run check:agent-layout`, `npm run typecheck`, `npm test`, `npm run build`, and `npm pack --dry-run`, while `npm publish` also uses the package lifecycle in `package.json` [@publish-workflow] [@package-json]. The GitHub Release title is `Rudder v` even though the tag remains `rudder-plugin-v` [@publish-workflow]. The exact scripts are listed in [Package Scripts](../../reference/tooling/package-scripts). +The package scripts are part of that path because the publish workflow validates with `npm run check:agent-layout`, `npm run typecheck`, `npm run test:coverage`, `npm run build`, and `npm pack --dry-run`, while `npm publish` also uses the package lifecycle in `package.json` [@publish-workflow] [@package-json]. `test:coverage` runs the full suite and requires 90% coverage on changed and untracked source lines before any release artifact is created [@package-json] [@publish-workflow]. The GitHub Release title is `Rudder v` even though the tag remains `rudder-plugin-v` [@publish-workflow]. The exact scripts are listed in [Package Scripts](../../reference/tooling/package-scripts). ## Release Alert Job diff --git a/almanac/architecture/runtime/local-state.md b/almanac/architecture/runtime/local-state.md index 27ddf16..9e2caeb 100644 --- a/almanac/architecture/runtime/local-state.md +++ b/almanac/architecture/runtime/local-state.md @@ -1,6 +1,6 @@ --- title: "Local State" -summary: "Rudder keeps runtime state in a user-scoped home directory that owns the SQLite database, telemetry identity, update-check cache, backups, and dashboard port defaults." +summary: "Rudder keeps runtime state in a user-scoped home directory that owns the SQLite database, telemetry identity, update-check cache, backups, and exported port defaults." topics: [architecture, runtime, local-state, sqlite, prompt-capture] sources: - id: db-client @@ -34,10 +34,10 @@ The source tree does not carry a repo-local state directory convention. The repo Migration application is deliberately part of the open flow. `openDb()` derives the migration directory from `RUDDER_MIGRATIONS_PATH` when that variable is set, otherwise it resolves the repository `drizzle/` directory relative to `src/db/client.ts`; it closes the raw SQLite handle if migration application fails [@db-client]. That means code using the [Prompt Branch Store](prompt-branch-store) can call `rudderDb()` without running a separate migration command first; `rudderDb()` opens the database if the Drizzle singleton is still missing [@db-client]. -## Dashboard Port +## Port Helper -`rudderPort()` is a small local-state helper for the dashboard daemon. It converts `RUDDER_PORT` with `Number()`, accepts only integer ports greater than zero and less than `65536`, and falls back to `41789` for unset, non-numeric, fractional, zero, negative, or out-of-range values [@db-client]. The exact environment contract is listed in [Environment Variables](../../reference/configuration/environment-variables). +`rudderPort()` is a small exported local-state helper for a future or host-owned port consumer. It converts `RUDDER_PORT` with `Number()`, accepts only integer ports greater than zero and less than `65536`, and falls back to `41789` for unset, non-numeric, fractional, zero, negative, or out-of-range values [@db-client]. The exact environment contract is listed in [Environment Variables](../../reference/configuration/environment-variables). ## Shared Boundary -Local state currently covers the SQLite database path, the telemetry identity file, the update-check cache, skill backup directories, and the dashboard port default. Telemetry builds `identity.json` under `rudderHome()`, reads an existing `{ id }` value when present, and writes a generated UUID there on a best-effort basis when it needs a new anonymous installation identity [@telemetry]. The update helper writes `update-state.json` atomically through a temporary file with mode `0600` after creating the Rudder home with mode `0700` [@update-script]. The important invariant is that runtime code should derive persistent paths from `rudderHome()` instead of inventing new repository-local locations. That keeps [Telemetry](telemetry), [Prompt Branch Store](prompt-branch-store), the update helper, and the environment-variable reference aligned around the same state root [@db-client] [@telemetry] [@update-script]. +Local state currently covers the SQLite database path, the telemetry identity file, the update-check cache, skill backup directories, and the exported port default. Telemetry builds `identity.json` under `rudderHome()`, preserves an existing anonymous UUID, and adds a random local-only pseudonymization key when either field is missing [@telemetry]. It creates the state root with mode `0700`, writes the identity file with mode `0600`, reapplies those permissions when an existing complete identity is loaded, and treats all persistence and permission changes as best-effort [@telemetry]. The update helper writes `update-state.json` atomically through a temporary file with mode `0600` after creating the Rudder home with mode `0700` [@update-script]. The important invariant is that runtime code should derive persistent paths from `rudderHome()` instead of inventing new repository-local locations. That keeps [Telemetry](telemetry), [Prompt Branch Store](prompt-branch-store), the update helper, and the environment-variable reference aligned around the same state root [@db-client] [@telemetry] [@update-script]. diff --git a/almanac/architecture/runtime/rudder-skill-runtime.md b/almanac/architecture/runtime/rudder-skill-runtime.md index c3a83cc..fee038b 100644 --- a/almanac/architecture/runtime/rudder-skill-runtime.md +++ b/almanac/architecture/runtime/rudder-skill-runtime.md @@ -1,6 +1,6 @@ --- title: "Rudder Skill Runtime" -summary: "The Rudder skill uses local helper scripts for update checks, context gathering, exact-path test backups, and prompt-data deletion while the host coding agent follows the test-generation workflow." +summary: "The Rudder skill combines deterministic context, backup, update, data-control, and telemetry helpers with a prompt-backed TDD workflow, bounded rewrite batches, and per-prompt test reports." topics: [architecture, runtime, plugin, prompt-capture, test-generation-intent] sources: - id: skill @@ -15,6 +15,9 @@ sources: - id: data-script type: file path: skills/rudder/scripts/manage-data.mjs + - id: telemetry-script + type: file + path: skills/rudder/scripts/telemetry.mjs - id: update-script type: file path: skills/rudder/scripts/update.mjs @@ -28,7 +31,7 @@ sources: # Rudder Skill Runtime -The Rudder skill runtime is the local helper layer behind the installed `$rudder` workflow. `skills/rudder/SKILL.md` tells the current coding agent to derive tests and minimal production changes from captured intent, while executable scripts handle update checks, deterministic context, exact-path backups, and prompt-data deletion [@skill] [@update-script] [@context-script] [@backup-script] [@data-script]. This preserves the [BYOK Skill Workflow](../../decisions/product/byok-skill-workflow): the user's current agent reasons about behavior and writes code, while local scripts do repeatable filesystem, Git, SQLite, and plugin-update work [@skill]. +The Rudder skill runtime is the local helper layer behind the installed `$rudder` workflow. `skills/rudder/SKILL.md` tells the current coding agent to derive tests and minimal production changes from captured intent, coordinate bounded rewrite batches, and prepare a per-prompt test report, while executable scripts handle update checks, deterministic context, exact-path backups, prompt-data deletion, and metadata-only run telemetry [@skill] [@update-script] [@context-script] [@backup-script] [@data-script] [@telemetry-script]. This preserves the [BYOK Skill Workflow](../../decisions/product/byok-skill-workflow): the user's current agent owns behavioral judgment and code changes, while local scripts do repeatable filesystem, Git, SQLite, update, measurement, and dispatch work [@skill]. ## Update Helper @@ -38,13 +41,13 @@ When a user accepts an update notice, the skill runs `scripts/update.mjs apply - ## Context Helper -`scripts/context.mjs` resolves the repository root from `--cwd`, requires an attached Git branch, chooses a base ref from `--base` or common `origin/main` and `master` fallbacks, calculates the merge base, and returns changed tracked and untracked paths as JSON [@context-script]. It classifies likely test paths using directory and filename conventions, leaves all other changed paths in `otherPaths`, normalizes the repository key from the active branch remote or a hashed local Git common directory, and reads matching prompts from `prompt_branches` in the local Rudder database when that table exists [@context-script]. The prompt objects returned to the skill include identifiers, prompt text, and timestamps; they do not currently include stored previous agent output [@context-script]. +`scripts/context.mjs` resolves the repository root from `--cwd`, requires an attached Git branch, chooses a base ref from `--base` or common `origin/main` and `master` fallbacks, calculates the merge base, and returns changed tracked and untracked paths as JSON [@context-script]. It classifies likely test paths using directory and filename conventions, leaves all other changed paths in `otherPaths`, counts changed test lines from the merge base, normalizes the repository key from the active branch remote or a hashed local Git common directory, and reads matching prompts from `prompt_branches` in the local Rudder database when that table exists [@context-script]. Prompt objects include identifiers, exact prompt text, previous agent output, submission time, and reconciliation time [@context-script]. -The skill treats this JSON as input, not as final judgment. It instructs the agent to inspect the merge base, changed paths, captured prompts, repository instructions, production diff, existing tests, and native test/coverage configuration before deciding which test changes matter [@skill]. +The first call uses `--phase start`, creates a UUID `rudderRunId`, and returns the resolved `baseRef`; later calls use `--phase refresh` with that same run ID and base [@context-script] [@skill]. Both phases best-effort dispatch bounded run/context telemetry without changing the JSON contract or waiting for delivery [@context-script]. The skill treats the returned classifications as input rather than final judgment and requires the agent to inspect repository instructions, diffs, tests, prompts, and native tooling before deciding which test changes matter [@skill]. ## Backup Helper And Test Reset -`scripts/backup-tests.mjs` creates recoverable backups for explicit test paths before any reset. It requires `--cwd`, verifies the base ref, computes the merge base, requires at least one `--path`, normalizes each path to stay inside the repository, writes a binary-capable patch for tracked changes, copies listed untracked paths into the backup directory, and emits backup metadata as JSON [@backup-script]. +`scripts/backup-tests.mjs` creates recoverable backups for explicit test paths before any reset. It requires `--cwd` and the active `--run-id`, verifies the base ref, computes the merge base, requires at least one `--path`, normalizes each path to stay inside the repository, writes a binary-capable patch for tracked changes, copies listed untracked paths into the backup directory, and emits backup metadata as JSON [@backup-script]. Only after the recovery metadata exists does it best-effort record approved and copied path counts for that run [@backup-script] [@telemetry-script]. The skill boundary is stricter than the helper's write behavior. The skill requires the agent to show the exact tracked and untracked test paths, inspect confirmed paths for immediately preceding Rudder source-intent tags, get explicit confirmation, run the backup helper for only those paths, verify the reported patch and untracked copies, and then restore only the confirmed test paths to the merge-base state [@skill]. After the reset, the agent attempts to restore only recorded tagged test cases plus the smallest required imports, fixtures, or helpers; untagged tests and whole-file restoration stay in the backup unless they can be isolated safely [@skill]. @@ -52,7 +55,25 @@ The skill boundary is stricter than the helper's write behavior. The skill requi The skill now treats coverage as loop control rather than a source of test intent. It can generate or expand a test only when a captured user prompt or answer explicitly requires the expectation, and after the first green suite it must ask one concrete question for an uncovered behavior before writing more tests [@skill]. Each generated or rewritten test case gets a language-appropriate source-intent comment immediately above the test case in `//` form, using identifiers returned by `scripts/context.mjs` [@skill]. -Production edits are allowed only inside a red-green cycle backed by captured intent. For each new or changed expectation, the skill writes the tagged test first, runs the narrowest test to observe the expected failure, makes the smallest production change required to satisfy that expectation, reruns the narrow test, and measures coverage only after the suite is green [@skill]. The package tests enforce that this prompt-backed production cycle replaced the older blanket instruction that generation must not change production code [@skill-tests]. +Production edits are allowed only inside a red-green cycle backed by captured intent. For each new or changed expectation, the skill writes the tagged test first, runs the narrowest test to observe the expected failure, makes the smallest production change required to satisfy that expectation, reruns the narrow test, and measures coverage only after the suite is green [@skill]. + +## Bounded Rewrite Batches + +The main agent is the only participant allowed to ask the user questions and remains responsible for intent interpretation, queue ownership, integration, and coverage [@skill]. After a captured answer authorizes an expectation, the main agent may dispatch a bounded rewrite task to a subagent with the exact source tag, disjoint test and production paths, relevant repository instructions, and a narrow test command [@skill]. + +At most three rewrite subagents may run at once, and no more than three tasks may be dispatched between coverage measurements [@skill]. Each owns one red-green cycle and may not ask questions, spawn more agents, run coverage, commit, or edit outside its assigned paths [@skill]. The main agent must join the entire batch, inspect the combined diff and tags, repair invalid results serially, run related and full tests, and measure coverage only after the joined suite is green [@skill]. Conflicting ownership or hosts without subagent support fall back to serial execution [@skill]. + +## Run Telemetry + +`scripts/telemetry.mjs` supplies two explicit CLI operations around the run identity returned by the context helper [@telemetry-script]. `question-asked` validates a positive question ordinal and dispatches no question or answer text; `complete` validates bounded completion, test, and coverage states, derives final changed-path and test-line counts from Git, counts recognized Rudder source-tag lines in changed test files, and records the total number of questions [@telemetry-script]. The skill invokes completion only after its final report is ready and sets statuses from observed results, but telemetry remains best-effort and cannot change the workflow outcome [@skill] [@telemetry-script]. + +The telemetry helper launches the bundled hook as a detached child and ignores missing bundles, serialization failures, spawn failures, and receiver delays [@telemetry-script]. [Telemetry Architecture](telemetry) documents the event schemas, pseudonymization, and opt-out boundary. + +## Per-Prompt Test Report + +Every normal or intentionally stopped test-generation run ends with a temporary Markdown report after all rewrites have joined and final test results are known [@skill]. The agent refreshes context, inspects final affected test paths, includes only test cases with an immediately preceding Rudder source tag, and matches each exact `//` tag back to the captured prompt record instead of relying on memory or file proximity [@skill] [@context-script]. + +The report groups tests once per prompt, copies `promptText` exactly, represents `previousAgentOutput` concisely or as `N/A`, and links human-readable test titles to their repository-relative path and starting line when local links are supported [@skill]. It is written to a unique operating-system temporary file outside the worktree, is never staged, and uses an explicit no-tests message when no final prompt-backed tests exist [@skill]. A failure to create this report is a blocked run rather than a reason to omit the provenance handoff [@skill]. ## Data Controls @@ -62,4 +83,4 @@ The skill handles data-control requests separately from test generation. It inst ## Validation Contract -`test/skill-runtime.test.ts` exercises the helper boundaries together: legacy capture-disable markers do not block prompt writes, the context helper returns branch changes plus captured prompt identifiers and text, the update helper caches registry state and retries nonblocking updates, the backup helper backs up only explicit test paths, and the data helper requires confirmation before deleting prompt rows [@skill-tests]. The OpenAI surface file gives Codex a display name, short description, and default prompt for the same skill package [@openai-surface]. +`test/skill-runtime.test.ts` exercises the helper boundaries together: legacy capture-disable markers do not block prompt writes, the context helper returns run identity, changed test-line counts, prompt identifiers, text, and previous output, the update helper caches registry state and retries nonblocking updates, the backup helper backs up only explicit test paths, telemetry dispatch does not wait for an unresponsive receiver, question and completion commands return bounded JSON, and the data helper requires confirmation before deleting prompt rows [@skill-tests]. The OpenAI surface file gives Codex a display name, short description, and default prompt for the same skill package [@openai-surface]. diff --git a/almanac/architecture/runtime/telemetry.md b/almanac/architecture/runtime/telemetry.md index c4daed5..0328c4f 100644 --- a/almanac/architecture/runtime/telemetry.md +++ b/almanac/architecture/runtime/telemetry.md @@ -1,41 +1,73 @@ --- title: "Telemetry Architecture" -summary: "Rudder telemetry is a PostHog client with release-build token injection, local anonymous installation identity, environment-controlled opt-out, and explicit shutdown." +summary: "Rudder telemetry uses a release-configured PostHog client, protected local identity, installation-scoped pseudonyms, and metadata-only prompt and run events with best-effort dispatch." topics: [architecture, runtime, telemetry, configuration] sources: - id: telemetry type: file path: src/telemetry.ts + - id: rudder-telemetry + type: file + path: src/rudder-telemetry.ts - id: telemetry-build-config type: file path: src/telemetry-build-config.ts - id: publish-workflow type: file path: .github/workflows/publish.yml - - id: db-client + - id: prompt-hook + type: file + path: src/prompt-hook.ts + - id: hook-bin + type: file + path: bin/rudder-prompt-hook.ts + - id: skill-telemetry + type: file + path: skills/rudder/scripts/telemetry.mjs + - id: context-script + type: file + path: skills/rudder/scripts/context.mjs + - id: backup-script type: file - path: src/db/client.ts + path: skills/rudder/scripts/backup-tests.mjs - id: package-json type: file path: package.json --- -Rudder telemetry is runtime infrastructure around `posthog-node`. The module creates a PostHog client only when a project token is available and `DO_NOT_TRACK` is not set to `1`; otherwise capture calls are no-ops through optional chaining [@telemetry]. Source builds keep the built-in token empty, while the publish workflow rewrites `src/telemetry-build-config.ts` in the release workspace before bundling so published hooks can carry release telemetry defaults without requiring user environment variables [@telemetry-build-config] [@publish-workflow]. When enabled, events use a stable anonymous installation id stored as `identity.json` under the same Rudder home directory used by [Local State](local-state) [@telemetry] [@db-client]. The package lists `posthog-node` in development dependencies and bundles the hook output, so the published plugin still contains telemetry code without declaring a runtime `dependencies` field [@package-json]. The telemetry module owns the client lifecycle through capture helpers and an async `shutdown()` function [@telemetry]. +Rudder telemetry is a metadata-only runtime path built around `posthog-node`. `src/telemetry.ts` owns enablement, local identity, common event properties, installation-scoped pseudonymization, capture, exception reporting, and shutdown; `src/rudder-telemetry.ts` validates and translates Rudder run events; prompt hooks and skill helpers supply only the bounded inputs those layers accept [@telemetry] [@rudder-telemetry] [@prompt-hook] [@skill-telemetry]. Source builds keep the built-in token and host empty, while the publish workflow rewrites `src/telemetry-build-config.ts` in the release workspace before bundling so published hooks can carry release telemetry defaults [@telemetry-build-config] [@publish-workflow]. The package keeps `posthog-node` as a development dependency because esbuild includes it in the bundled hook rather than exposing a runtime dependency [@package-json]. ## Enablement Boundary -Telemetry enablement is decided before a client is constructed. The module chooses the project token from `POSTHOG_PROJECT_TOKEN`, then `POSTHOG_API_KEY`, then `BUILT_IN_POSTHOG_PROJECT_TOKEN`; it chooses the host from `POSTHOG_HOST`, then `BUILT_IN_POSTHOG_HOST`, then `https://us.i.posthog.com` [@telemetry] [@telemetry-build-config]. `telemetryDisabled()` is the `DO_NOT_TRACK === '1'` check [@telemetry]. The internal `client()` function returns `null` when the selected token is empty or telemetry is disabled, so `capture()` and `captureException()` can safely call it without requiring callers to branch on configuration [@telemetry]. +Telemetry enablement is decided before a client or event-property factory is used. The module chooses the project token from `POSTHOG_PROJECT_TOKEN` and then `BUILT_IN_POSTHOG_PROJECT_TOKEN`; it no longer reads `POSTHOG_API_KEY` [@telemetry]. It chooses the host from `POSTHOG_HOST`, then `BUILT_IN_POSTHOG_HOST`, then `https://us.i.posthog.com` [@telemetry] [@telemetry-build-config]. `telemetryDisabled()` checks exactly `DO_NOT_TRACK === '1'` [@telemetry]. The internal `client()` returns `null` when the selected token is empty or telemetry is disabled, so capture calls remain no-ops and do not evaluate their lazy property factories on a disabled path [@telemetry]. When a client is created, it is cached in `_client` and configured with the selected host, `flushAt: 1`, `flushInterval: 0`, and exception autocapture enabled [@telemetry]. The flush settings fit short-lived CLI invocations because each event is sent immediately instead of waiting for a larger batch [@telemetry]. -## Anonymous Identity +## Identity And Pseudonyms + +Telemetry does not use a user account identity. `identity.json` under `rudderHome()` stores a stable anonymous UUID plus a local-only random pseudonymization key [@telemetry]. The loader preserves an existing non-empty `id`, fills either missing field, and upgrades the older `{ id }` shape by adding `pseudonymization_key` [@telemetry]. Persistence is best-effort, but when supported the Rudder home is restricted to mode `0700` and the identity file to mode `0600` [@telemetry]. + +Repository, branch, and run identifiers are not sent raw. `pseudonymize()` uses HMAC-SHA256 over a namespace, a null separator, and the source value with the installation's local key [@telemetry]. Repository pseudonyms are stable only within one installation, branch pseudonyms include the repository and branch, and run pseudonyms include repository, branch, and run ID [@rudder-telemetry]. That keeps events joinable for one installation without making private identifiers readable or correlatable across installations. + +Every ordinary event receives `telemetry_schema_version` and the current `rudder_version`; exception events receive those common properties as well [@telemetry]. The version is read from `package.json` at runtime and falls back to `unknown` if the manifest cannot be read [@telemetry]. + +## Event Boundary + +Prompt lifecycle events are emitted directly by `src/prompt-hook.ts`, while Rudder workflow events pass through the strict schemas in `src/rudder-telemetry.ts` [@prompt-hook] [@rudder-telemetry]. -Telemetry does not use a user account identity. `distinctId()` lazily loads or creates a stable anonymous id and caches it in `_distinctId` [@telemetry]. `loadDistinctId()` looks for `identity.json` under `rudderHome()`, parses the file, and reuses `obj.id` when it is a non-empty string [@telemetry]. If the file is missing, malformed, or unusable, the function generates a UUID with `randomUUID()` [@telemetry]. +| Event | Bounded properties | +| --- | --- | +| `rudder prompt captured` | Agent source, whether this is the first captured prompt in the session, the session's captured-prompt count, and whether previous agent output was stored [@prompt-hook]. | +| `rudder prompt reconciled` | Agent source and whether the repository branch changed across the prompt turn [@prompt-hook]. | +| `rudder run started` / `rudder context refreshed` | Host, installation-scoped repository/branch/run pseudonyms, local-repository flag, captured and reconciled prompt counts, prompt-source counts, changed-path counts, untracked-path count, and test-line additions/deletions from the merge base [@rudder-telemetry] [@context-script]. | +| `rudder test backup created` | Run pseudonyms, host, approved test-path count, and copied untracked test-path count [@rudder-telemetry] [@backup-script]. | +| `rudder question asked` | Run pseudonyms, host, and a positive question ordinal [@rudder-telemetry] [@skill-telemetry]. | +| `rudder run finished` | Run pseudonyms, host, bounded completion/test/coverage states, final changed-path counts, recognized Rudder source-tag count in changed test paths, test-line additions/deletions, and total questions asked [@rudder-telemetry] [@skill-telemetry]. | -Persistence is best-effort. The loader creates the Rudder home directory and writes `{"id": ""}` when it can, but write failures fall through and the generated id remains usable in memory for that process [@telemetry]. Because `rudderHome()` itself is controlled by `RUDDER_HOME` or defaults to `~/.rudder`, telemetry identity follows the same state-root override as the database [@db-client] [@telemetry]. +These schemas omit raw prompt and answer text, previous agent output, raw repository, branch, and run identifiers, model and token usage, tool activity, and cost [@prompt-hook] [@rudder-telemetry]. The question helper receives only the run ID and ordinal, and the completion helper derives path, tag, and line counts from Git and the worktree instead of accepting arbitrary analytics properties [@skill-telemetry]. -## Capture And Shutdown +## Dispatch And Failure Boundary -`capture(event, properties)` sends a PostHog event with the anonymous distinct id, event name, and optional properties only when `client()` returns a client [@telemetry]. `captureException(err, extra)` uses the same distinct id and passes optional extra properties to PostHog's exception capture API [@telemetry]. Both helpers are intentionally small, so product code can report events without knowing the API-key, opt-out, or identity-file rules. +The installed skill does not import PostHog directly. `skills/rudder/scripts/telemetry.mjs` serializes a bounded payload and starts the bundled `dist/rudder-prompt-hook.mjs` with `--rudder-event ` as a detached, unreferenced child whose stdio is ignored [@skill-telemetry]. Missing bundles, serialization failures, spawn errors, and an unresponsive telemetry receiver do not block the Rudder workflow [@skill-telemetry]. The context helper emits start or refresh events, the backup helper emits its event after recovery metadata exists, and the telemetry CLI records question ordinals and final run outcomes [@context-script] [@backup-script] [@skill-telemetry]. -`shutdown()` is the lifecycle close point. It awaits `_client.shutdown()` when a client exists and then clears the cached client reference [@telemetry]. Code that adds longer-running commands should preserve that explicit shutdown path so pending telemetry work is flushed before process exit. The exact environment-variable behavior is listed in [Environment Variables](../../reference/configuration/environment-variables). +The bundled hook selects either Rudder-event mode or ordinary prompt-capture mode from its arguments, parses one JSON payload from stdin, and uses the same telemetry shutdown path for both [@hook-bin]. All top-level hook failures are caught; exception capture, database close, and telemetry shutdown are each best-effort so neither prompt capture nor product telemetry interrupts the host coding agent [@hook-bin]. `shutdown()` awaits the cached PostHog client's close and clears the client reference [@telemetry]. The exact environment-variable behavior is listed in [Environment Variables](../../reference/configuration/environment-variables). diff --git a/almanac/architecture/tooling/package-baseline.md b/almanac/architecture/tooling/package-baseline.md index 31fcbfc..0687f94 100644 --- a/almanac/architecture/tooling/package-baseline.md +++ b/almanac/architecture/tooling/package-baseline.md @@ -20,7 +20,7 @@ sources: path: .gitignore --- -Rudder's package baseline is the repo's build and distribution frame for the plugin. The package is published as `@ruddercode/rudder-plugin`, uses ESM, requires Node `>=24.0.0`, bundles the prompt hook to `dist/rudder-prompt-hook.mjs`, copies generated Drizzle migrations into `dist/drizzle`, and includes plugin manifests, assets, docs, hooks, skills, `dist`, and `LICENSE` in the npm file allowlist [@package-json]. That baseline connects runtime, plugin, and tooling work to [Contributor Automation](../automation/contributor-automation), because the package scripts define the command set those pages reuse [@package-json]. +Rudder's package baseline is the repo's build and distribution frame for the plugin. The package is published as `@ruddercode/rudder-plugin`, uses ESM, requires Node `>=24.0.0`, bundles the prompt-capture and telemetry entrypoint to `dist/rudder-prompt-hook.mjs`, copies generated Drizzle migrations into `dist/drizzle`, and includes plugin manifests, assets, docs, hooks, skills, `dist`, and `LICENSE` in the npm file allowlist [@package-json] [@hook-bin]. That baseline connects runtime, plugin, and tooling work to [Contributor Automation](../automation/contributor-automation), because the package scripts define the command set those pages reuse [@package-json]. ## Package Contract @@ -32,16 +32,16 @@ The package file allowlist keeps distribution narrow but plugin-complete. `.clau The TypeScript configuration targets `ES2023`, uses `NodeNext` module and module-resolution behavior, enables `strict`, sets Node types, and includes `bin/**/*.ts`, `dangerfile.ts`, and `src/**/*.ts` [@tsconfig]. The configuration uses `noEmit: true`; package build output comes from esbuild, not from a separate TypeScript emit overlay [@tsconfig] [@package-json]. -The bundled hook imports repository runtime modules from `bin/rudder-prompt-hook.ts`, and the `build` script bundles that entrypoint for Node ESM output at `dist/rudder-prompt-hook.mjs` [@hook-bin] [@package-json]. The companion [TypeScript build reference](../../reference/tooling/typescript-build) records the exact compiler and bundle contract as lookup material. +The bundled hook imports repository runtime modules from `bin/rudder-prompt-hook.ts`, selects prompt-capture or internal Rudder-event mode from its arguments, and is bundled for Node ESM output at `dist/rudder-prompt-hook.mjs` [@hook-bin] [@package-json]. The companion [TypeScript build reference](../../reference/tooling/typescript-build) records the exact compiler and bundle contract as lookup material. ## Scripts And Validation -The baseline includes scripts for migration generation, markdown formatting, Danger, agent-layout validation, typechecking, hook bundling, tests, packing, and publishing [@package-json]. `typecheck` runs `tsc --noEmit`, `test` runs Node's built-in test runner, `pretest` rebuilds the hook bundle, `build` clears `dist`, runs esbuild, and copies `drizzle/`, and `prepack` rebuilds before npm packing [@package-json]. The package-level script contract is described in [Package Scripts](../../reference/tooling/package-scripts). +The baseline includes scripts for migration generation, markdown formatting, Danger, agent-layout validation, typechecking, hook bundling, tests, changed-line coverage, packing, and publishing [@package-json]. `typecheck` runs `tsc --noEmit`, `test` runs Node's built-in test runner, `test:coverage` builds and runs that suite under c8 before requiring 90% coverage on changed and untracked lines with `diff-cover`, `pretest` rebuilds the hook bundle, `build` clears `dist`, runs esbuild, and copies `drizzle/`, and `prepack` rebuilds before npm packing [@package-json]. The package-level script contract is described in [Package Scripts](../../reference/tooling/package-scripts). This structure makes the package baseline small but not inert. Future runtime or hook code must fit the existing NodeNext TypeScript model, keep the esbuild output under `dist`, keep generated migrations available to installed hook code, and keep the validation scripts green before package publication [@tsconfig] [@package-json]. ## Dependency Boundary -The root package currently lists Drizzle ORM, PostHog's Node client, esbuild, Danger, rumdl, TypeScript, Drizzle Kit, and Node type definitions as development dependencies, with Drizzle ORM and Drizzle Kit pinned to `1.0.0-rc.4` [@package-json]. Because the hook bundle is self-contained and `package.json` has no runtime `dependencies` field, changing dependency scope should be treated as a package-contract change and checked against [Rudder Plugin Package](plugin-package) [@package-json] [@plugin-tests]. +The root package currently lists Drizzle ORM, PostHog's Node client, c8, diff-cover, esbuild, Danger, rumdl, TypeScript, Drizzle Kit, and Node type definitions as development dependencies, with Drizzle ORM and Drizzle Kit pinned to `1.0.0-rc.4` [@package-json]. c8 produces LCOV for all configured TypeScript and skill-script sources, while diff-cover compares that report with Git changes [@package-json]. Because the hook bundle is self-contained and `package.json` has no runtime `dependencies` field, changing dependency scope should be treated as a package-contract change and checked against [Rudder Plugin Package](plugin-package) [@package-json] [@plugin-tests]. Package changes should be read together with [contributor automation](../automation/contributor-automation). That page explains how local check surfaces and GitHub Actions reuse the `typecheck`, `test`, and `build` scripts documented here. diff --git a/almanac/architecture/tooling/plugin-package.md b/almanac/architecture/tooling/plugin-package.md index 001d650..6eb233a 100644 --- a/almanac/architecture/tooling/plugin-package.md +++ b/almanac/architecture/tooling/plugin-package.md @@ -1,6 +1,6 @@ --- title: "Rudder Plugin Package" -summary: "The root npm package distributes Rudder as one Claude Code and Codex plugin with manifests, hooks, skill files, docs, assets, and a bundled prompt-capture hook." +summary: "The root npm package distributes Rudder as one Claude Code and Codex plugin with manifests, hooks, skill files, docs, assets, and a bundled prompt-capture and telemetry runtime." topics: [architecture, tooling, package, plugin, prompt-capture, release] sources: - id: package-json @@ -24,6 +24,12 @@ sources: - id: skill type: file path: skills/rudder/SKILL.md + - id: skill-telemetry + type: file + path: skills/rudder/scripts/telemetry.mjs + - id: rudder-telemetry + type: file + path: src/rudder-telemetry.ts - id: plugin-tests type: file path: test/plugin-package.test.ts @@ -37,7 +43,7 @@ sources: # Rudder Plugin Package -The repository root is the publishable Rudder plugin package. `package.json` names the package `@ruddercode/rudder-plugin`, requires Node `>=24.0.0`, and includes plugin-specific artifacts such as `.claude-plugin`, `.codex-plugin`, `assets`, `docs`, `hooks`, `skills`, and `dist` in the npm file allowlist [@package-json]. The package carries both Claude Code and Codex plugin manifests, a public marketplace catalog that points at the npm package, the Rudder skill, and a bundled prompt-capture hook [@claude-manifest] [@codex-manifest] [@marketplace] [@hooks] [@skill]. +The repository root is the publishable Rudder plugin package. `package.json` names the package `@ruddercode/rudder-plugin`, requires Node `>=24.0.0`, and includes plugin-specific artifacts such as `.claude-plugin`, `.codex-plugin`, `assets`, `docs`, `hooks`, `skills`, and `dist` in the npm file allowlist [@package-json]. The package carries both Claude Code and Codex plugin manifests, a public marketplace catalog that points at the npm package, the Rudder skill and helper scripts, and one bundled runtime used for prompt capture and bounded product telemetry [@claude-manifest] [@codex-manifest] [@marketplace] [@hooks] [@skill] [@skill-telemetry] [@rudder-telemetry]. ## Distribution Shape @@ -47,10 +53,12 @@ The marketplace catalog under `.claude-plugin/marketplace.json` lists one plugin ## Bundled Hook -`hooks/hooks.json` registers command hooks for `UserPromptSubmit` and `Stop` [@hooks]. Each command executes Node with `--input-type=module`, resolves the plugin root from `PLUGIN_ROOT` or `CLAUDE_PLUGIN_ROOT`, and imports `dist/rudder-prompt-hook.mjs` from that root [@hooks]. The source executable reads JSON hook payloads from stdin, infers Codex from `PLUGIN_ROOT`, infers Claude Code from `CLAUDE_PLUGIN_ROOT`, sets `RUDDER_MIGRATIONS_PATH` to the installed `dist/drizzle` folder, records the prompt hook event, catches failures, reports hook exceptions through telemetry best-effort, closes the database handle, and shuts down telemetry without printing model-visible output [@hook-bin]. +`hooks/hooks.json` registers command hooks for `UserPromptSubmit` and `Stop` [@hooks]. Each command executes Node with `--input-type=module`, resolves the plugin root from `PLUGIN_ROOT` or `CLAUDE_PLUGIN_ROOT`, and imports `dist/rudder-prompt-hook.mjs` from that root [@hooks]. In ordinary hook mode, the source executable reads JSON from stdin, infers Codex from `PLUGIN_ROOT` or Claude Code from `CLAUDE_PLUGIN_ROOT`, sets `RUDDER_MIGRATIONS_PATH` to the installed `dist/drizzle` folder, and records the prompt lifecycle event [@hook-bin]. + +The same executable has an internal `--rudder-event` mode for the five validated events in `src/rudder-telemetry.ts` [@hook-bin] [@rudder-telemetry]. `skills/rudder/scripts/telemetry.mjs` launches that bundled artifact as a detached best-effort child for run, context, backup, question, and completion metadata without exposing PostHog to the skill process [@skill-telemetry]. Both modes catch top-level failures, report exceptions best-effort, close any database handle, shut down telemetry, and avoid model-visible output [@hook-bin]. -The `build` script creates the installed hook artifact by bundling `bin/rudder-prompt-hook.ts` with esbuild for Node ESM output at `dist/rudder-prompt-hook.mjs`, then copying committed Drizzle migrations into `dist/drizzle` [@package-json]. `pretest` and `prepack` both run the build, so tests and packed artifacts use a freshly generated bundle [@package-json]. Plugin package tests enforce matching Claude/Codex metadata, required package file entries, marketplace npm source fields, hook command shape, and silent prompt-hook execution for both `PLUGIN_ROOT` and `CLAUDE_PLUGIN_ROOT` environments [@plugin-tests]. +The `build` script creates the installed runtime artifact by bundling `bin/rudder-prompt-hook.ts` with esbuild for Node ESM output at `dist/rudder-prompt-hook.mjs`, then copying committed Drizzle migrations into `dist/drizzle` [@package-json]. `pretest`, `test:coverage`, and `prepack` build before their downstream work, so tests, coverage, and packed artifacts use a fresh bundle [@package-json]. Plugin package tests enforce matching Claude/Codex metadata, required package file entries including the skill telemetry helper, marketplace npm source fields, hook command shape, and silent prompt-hook execution for both `PLUGIN_ROOT` and `CLAUDE_PLUGIN_ROOT` environments [@plugin-tests]. ## Release Boundary -The publish workflow expects the root package name to be exactly `@ruddercode/rudder-plugin`, checks npmjs.org for the version, creates plugin tags in the `rudder-plugin-v` form, and validates the package with agent layout, typecheck, tests, build, and `npm pack --dry-run` before publishing [@publish-workflow]. The release behavior is covered in [Release Automation](../release/release-automation), and the command surface is listed in [Package Scripts](../../reference/tooling/package-scripts). +The publish workflow expects the root package name to be exactly `@ruddercode/rudder-plugin`, checks npmjs.org for the version, creates plugin tags in the `rudder-plugin-v` form, and validates the package with agent layout, typecheck, 90% changed-line coverage, build, and `npm pack --dry-run` before publishing [@publish-workflow] [@package-json]. The release behavior is covered in [Release Automation](../release/release-automation), and the command surface is listed in [Package Scripts](../../reference/tooling/package-scripts). diff --git a/almanac/concepts/product/intent-driven-test-generation.md b/almanac/concepts/product/intent-driven-test-generation.md index e518063..9a2b970 100644 --- a/almanac/concepts/product/intent-driven-test-generation.md +++ b/almanac/concepts/product/intent-driven-test-generation.md @@ -31,10 +31,12 @@ Worktree changes provide the other input. `scripts/context.mjs` resolves a merge Rudder starts from a controlled test reset before generation. The installed skill requires the agent to show exact tracked and untracked test paths, get explicit confirmation, create a recoverable backup, and then restore only the confirmed test paths to the merge-base state [@skill]. When a confirmed path already contains Rudder source-intent tags, the agent records those tagged test cases before the reset and attempts to restore only those cases plus the smallest required supporting code afterward [@skill]. The linked [Test Intent Standards](test-intent-standards) page explains the direct-intent and source-tag rules that decide which expectations can be generated or restored. -After the reset, every generated or rewritten test case must carry an immediately preceding source-intent comment in `//` form, using identifiers from captured prompt records rather than prompt text [@skill]. Coverage is loop control rather than a source of new expectations: when coverage is below target after a green first pass, the agent asks one concrete question about an uncovered behavior and waits for a captured answer before writing the next test [@skill]. +After the reset, every generated or rewritten test case must carry an immediately preceding source-intent comment in `//` form, using identifiers from captured prompt records rather than prompt text [@skill]. Coverage is loop control rather than a source of new expectations: when coverage is below target after a green first pass, the main agent asks one concrete question about an uncovered behavior and waits for a captured answer before writing the next test [@skill]. + +Captured answers can be implemented in bounded rewrite batches. The main agent may dispatch at most three disjoint red-green tasks between coverage runs, joins and verifies the whole batch, runs the combined test suites, and only then measures coverage again [@skill]. Every run ends with a temporary report that groups final adjacent-tagged tests by their exact captured prompt, preserves prompt text, summarizes prior agent context, and links test titles to source locations [@skill] [@context-script]. ## Generation Ownership The local version is bring-your-own-agent. Rudder does not choose a model or make a separate model API call; the user's current coding agent generates tests with the model and credentials already configured for that agent [@readme] [@skill]. The product is therefore a skill-guided workflow backed by deterministic local context and worktree tools, not a provider-specific test generator [@readme] [@skill]. [BYOK Skill Workflow](../../decisions/product/byok-skill-workflow) records that product decision. -This ownership model keeps the feedback loop inside the coding session that produced the implementation. Production changes are now allowed only inside a prompt-backed red-green cycle: write the tagged test first, observe the expected failure, make the smallest implementation change, rerun the narrow test, and measure coverage only after the suite is green [@skill]. +This ownership model keeps the feedback loop inside the coding session that produced the implementation. Production changes are allowed only inside a prompt-backed red-green cycle: write the tagged test first, observe the expected failure, make the smallest implementation change, rerun the narrow test, and measure coverage only after the suite is green [@skill]. Subagents may own isolated rewrites, but the current host agent remains the only question asker and owns intent interpretation, integration, coverage, and the final prompt report [@skill]. diff --git a/almanac/concepts/product/test-intent-standards.md b/almanac/concepts/product/test-intent-standards.md index 1225dd4..d4e6fd2 100644 --- a/almanac/concepts/product/test-intent-standards.md +++ b/almanac/concepts/product/test-intent-standards.md @@ -1,6 +1,6 @@ --- title: "Test Intent Standards" -summary: "Test intent standards define how Rudder ties generated tests, restored test cases, and coverage questions to captured user intent." +summary: "Test intent standards define how Rudder ties generated tests, restored test cases, coverage questions, rewrite batches, and final reports to captured user intent." topics: [concepts, product-intent, test-generation-intent] sources: - id: skill @@ -9,11 +9,14 @@ sources: - id: backup-script type: file path: skills/rudder/scripts/backup-tests.mjs + - id: context-script + type: file + path: skills/rudder/scripts/context.mjs --- # Test Intent Standards -Test intent standards are the rules that keep Rudder's generated unit tests grounded in what the user directly intended during a coding session. They require generated or rewritten test cases to be traceable to captured prompt records, reset confirmed test paths through a recoverable backup, preserve only Rudder-tagged generated tests after that reset when they can be isolated, and use narrow questions to resolve uncovered behavior [@skill]. These standards sit inside [Intent-Driven Test Generation](intent-driven-test-generation) and constrain the [BYOK Skill Workflow](../../decisions/product/byok-skill-workflow). +Test intent standards are the rules that keep Rudder's generated unit tests grounded in what the user directly intended during a coding session. They require generated or rewritten test cases to be traceable to captured prompt records, reset confirmed test paths through a recoverable backup, preserve only Rudder-tagged generated tests after that reset when they can be isolated, use narrow questions to resolve uncovered behavior, isolate parallel rewrites, and produce a final test-to-prompt report [@skill]. These standards sit inside [Intent-Driven Test Generation](intent-driven-test-generation) and constrain the [BYOK Skill Workflow](../../decisions/product/byok-skill-workflow). ## Direct Intent @@ -38,3 +41,15 @@ The tag is a traceability contract, not a decoration. It identifies which captur Rudder should ask questions only when they resolve an ambiguity that changes a test expectation. After the first green test pass, if coverage is below target, the skill requires the agent to stop editing tests, select one uncovered behavior, ask one concrete question, and wait for the user's answer before writing the next test [@skill]. Coverage is the loop control, not the source of intent. The skill requires a captured prompt record for each follow-up answer before adding the expectation that answer authorizes, and it stops below target when the answer is missing, declined, or not captured [@skill]. Contributors use [Run Checks](../../guides/contributor/run-checks) for the repository's validation procedure outside this product-generation loop. + +## Rewrite Ownership + +Only the main agent may ask questions or interpret a follow-up answer [@skill]. It can queue at most three independent rewrite tasks between coverage runs and at most three concurrent subagents, with each task carrying one authorized expectation, its exact source-intent tag, disjoint file ownership, repository instructions, and a narrow test command [@skill]. Rewrite workers may perform only their assigned red-green cycle; they may not ask questions, spawn agents, run coverage, commit, or cross their assigned path boundary [@skill]. + +Coverage cannot be measured while any rewrite is pending. The main agent joins the batch, verifies tags and ownership in the combined diff, repairs failures serially, and reruns related and full suites before another coverage snapshot [@skill]. When work cannot be divided safely, the same authorized expectations run serially rather than weakening the ownership boundary [@skill]. + +## Report Provenance + +The final report uses the source tag as a relational key rather than treating nearby prompts or agent memory as provenance [@skill]. After refreshing `scripts/context.mjs`, the agent matches each final generated, rewritten, or restored tagged test to the exact captured record identified by `//`, groups tests once per prompt, and omits prompts with no final tagged tests [@skill] [@context-script]. + +The report must preserve `promptText` exactly, reduce `previousAgentOutput` to a concise faithful representation or `N/A`, and identify tests by human-readable title plus path and starting line rather than copying test bodies [@skill]. It lives in a unique temporary file outside the repository and is produced for completed and intentionally stopped runs, keeping user-facing provenance separate from the committed test source [@skill]. diff --git a/almanac/concepts/runtime/prompt-history.md b/almanac/concepts/runtime/prompt-history.md index d08f34b..5941699 100644 --- a/almanac/concepts/runtime/prompt-history.md +++ b/almanac/concepts/runtime/prompt-history.md @@ -18,6 +18,9 @@ sources: - id: context-script type: file path: skills/rudder/scripts/context.mjs + - id: skill + type: file + path: skills/rudder/SKILL.md - id: readme type: file path: README.md @@ -31,7 +34,7 @@ Prompt history is Rudder's local record of prompt context that can explain user The README describes Rudder as running inside the same coding-agent session where the feature was built, using that session context plus worktree changes to create tests for new production code [@readme]. In that product model, prompt history is behavioral evidence: it carries the user's stated expectations and the answers to later clarification questions [@readme]. -The current implementation gives the [Rudder Skill Runtime](../../architecture/runtime/rudder-skill-runtime) local prompt context for that model. The skill still asks the host coding agent to reason about behavior, inspect tests, generate new tests, and interpret coverage; prompt history is evidence for those steps, not an automatic test oracle [@context-script]. +The current implementation gives the [Rudder Skill Runtime](../../architecture/runtime/rudder-skill-runtime) local prompt context for that model. The skill still asks the host coding agent to reason about behavior, inspect tests, generate new tests, and interpret coverage; prompt history is evidence for those steps, not an automatic test oracle [@context-script]. At the end of a Rudder run, the same history supplies exact prompt text and prior agent context for the per-prompt test report, with source-intent tags providing the join key from each final test back to one prompt record [@skill] [@context-script]. ## Capture Model @@ -41,4 +44,4 @@ Prompt capture starts from coding-agent hooks. `recordPromptHookEvent()` normali ## Working Implication -When updating the product workflow, treat prompt history as local and branch-scoped. `skills/rudder/scripts/context.mjs` reads prompt identifiers, text, and timestamps for the resolved repository and branch from `prompt_branches` and returns them beside the branch diff, so the skill can combine implementation changes with user-stated intent [@context-script]. The table can store `previous_agent_output`, but the current context helper does not include that field in the skill JSON; using previous agent output in `$rudder` requires changing the helper and its tests, not just reading the stored rows [@schema] [@context-script]. Use [Prompt Branch Store](../../architecture/runtime/prompt-branch-store), [Prompt Branches Schema](../../reference/database/prompt-branches-schema), and [Use Prompt Capture](../../guides/runtime/use-prompt-capture) for current implementation work. +When updating the product workflow, treat prompt history as local and branch-scoped. `skills/rudder/scripts/context.mjs` reads prompt identifiers, exact text, previous agent output, submission time, and reconciliation time for the resolved repository and branch from `prompt_branches` and returns them beside the branch diff [@context-script]. The skill uses identifiers to authorize and tag expectations, copies exact `promptText` into the final report, and uses only a concise faithful representation of `previousAgentOutput`; it does not infer either value from the implementation or model memory [@skill]. Use [Prompt Branch Store](../../architecture/runtime/prompt-branch-store), [Prompt Branches Schema](../../reference/database/prompt-branches-schema), and [Use Prompt Capture](../../guides/runtime/use-prompt-capture) for current implementation work. diff --git a/almanac/decisions/product/byok-skill-workflow.md b/almanac/decisions/product/byok-skill-workflow.md index 656c9b6..eced858 100644 --- a/almanac/decisions/product/byok-skill-workflow.md +++ b/almanac/decisions/product/byok-skill-workflow.md @@ -18,9 +18,12 @@ sources: - id: backup-script type: file path: skills/rudder/scripts/backup-tests.mjs + - id: telemetry-script + type: file + path: skills/rudder/scripts/telemetry.mjs --- -Rudder's BYOK skill workflow decision is that test generation and prompt-backed production edits happen inside the user's existing coding-agent session, using that agent's configured model access and credentials, rather than through a separate Rudder-owned model call [@product-readme] [@skill]. The root plugin package ships the Rudder skill and deterministic helper scripts; the skill gathers local prompt intent, inspects the worktree, checks for plugin updates, confirms and backs up test resets, directs the agent through tagged tests and red-green implementation changes, runs repository tooling, measures coverage, and asks follow-up questions in the same session [@plugin-package] [@skill]. This decision ties [intent-driven test generation](../../concepts/product/intent-driven-test-generation), [test intent standards](../../concepts/product/test-intent-standards), and [prompt history](../../concepts/runtime/prompt-history) into one local workflow. +Rudder's BYOK skill workflow decision is that test generation and prompt-backed production edits happen inside the user's existing coding-agent session, using that agent's configured model access and credentials, rather than through a separate Rudder-owned model call [@product-readme] [@skill]. The root plugin package ships the Rudder skill and deterministic helper scripts; the skill gathers local prompt intent, inspects the worktree, checks for plugin updates, confirms and backs up test resets, directs tagged red-green changes, coordinates bounded rewrite batches, measures coverage, and produces a per-prompt report in the same session [@plugin-package] [@skill]. This decision ties [intent-driven test generation](../../concepts/product/intent-driven-test-generation), [test intent standards](../../concepts/product/test-intent-standards), and [prompt history](../../concepts/runtime/prompt-history) into one local workflow. ## Status @@ -34,10 +37,10 @@ A separate model call would move generation away from the session that produced ## Decision -Rudder is delivered to the user's coding agent as a skill plus deterministic local helper tools. The skill defines the workflow rules for update notices, session intent, test-path review, tagged generated tests, red-green implementation cycles, native tooling, coverage measurement, and follow-up questions [@skill]. Local tools handle deterministic worktree, backup, prompt-data, and plugin-update operations, while the user's current agent handles reasoning and generation [@skill] [@context-script] [@backup-script]. +Rudder is delivered to the user's coding agent as a skill plus deterministic local helper tools. The skill defines the workflow rules for update notices, session intent, test-path review, tagged generated tests, red-green implementation cycles, bounded rewrite ownership, native tooling, coverage measurement, follow-up questions, and final reports [@skill]. Local tools handle deterministic worktree, backup, prompt-data, plugin-update, and metadata-only measurement operations, while the user's current agent handles reasoning and generation [@skill] [@context-script] [@backup-script] [@telemetry-script]. ## Consequences -The decision keeps generation repository- and provider-agnostic. The README says Rudder uses the repository's own test and coverage tools and keeps test generation with the coding agent and model the user already uses [@product-readme]. It also keeps every follow-up question in the session where the feature was implemented, so user answers become captured prompt records for later generation passes [@skill]. The implemented helper layer can supply branch changes, captured prompts, update checks, and recoverable test backups, but the host agent still owns behavioral judgment and generated edits [@context-script] [@backup-script] [@skill]. +The decision keeps generation repository- and provider-agnostic. The README says Rudder uses the repository's own test and coverage tools and keeps test generation with the coding agent and model the user already uses [@product-readme]. It also keeps every follow-up question in the session where the feature was implemented, so user answers become captured prompt records for later generation passes [@skill]. The host may use its own subagent facility for up to three isolated rewrite tasks, but the main agent still owns questions, intent interpretation, integration, coverage, and reporting; no Rudder-owned model service enters the loop [@skill]. -The tradeoff is that Rudder's local workflow must express instructions clearly enough for supported coding agents to execute. The helper scripts can provide repository context, prompt records, update commands, and recoverable backups, but they do not determine behavioral intent or generate tests [@context-script] [@backup-script] [@skill]. Future product work should preserve this boundary unless a later decision explicitly moves model selection or generation into Rudder itself. +The implemented helper layer can supply branch changes, exact prompt records including prior agent output, update commands, recoverable backups, and best-effort run measurements, but it does not determine behavioral intent or generate tests [@context-script] [@backup-script] [@telemetry-script] [@skill]. The tradeoff is that the local workflow must express batching, provenance, and failure boundaries clearly enough for supported coding agents to execute. Future product work should preserve this boundary unless a later decision explicitly moves model selection or generation into Rudder itself. diff --git a/almanac/getting-started.md b/almanac/getting-started.md index 34b89c6..e2ce309 100644 --- a/almanac/getting-started.md +++ b/almanac/getting-started.md @@ -37,7 +37,7 @@ sources: # Getting Started -Getting started is the entry point for reading Rudder's wiki as a future coding agent. Start from the current implementation and the current product intent: the repository root is the `@ruddercode/rudder-plugin` npm package, the runtime captures prompt text into a local SQLite prompt store, the installed skill uses helper scripts for context, backup, and data controls, and the README describes the intent-driven test-generation product model [@package] [@prompt-hook] [@prompt-tagger] [@skill] [@readme]. The repository instructions describe Rudder as an experimental pre-release product, so future work should not assume compatibility migrations for existing users are required [@agents]. +Getting started is the entry point for reading Rudder's wiki as a future coding agent. Start from the current implementation and the current product intent: the repository root is the `@ruddercode/rudder-plugin` npm package, the runtime captures prompt text into a local SQLite prompt store, the installed skill uses helper scripts for context, backup, data controls, updates, and run measurement, and the README describes the intent-driven test-generation product model [@package] [@prompt-hook] [@prompt-tagger] [@skill] [@readme]. The repository instructions describe Rudder as an experimental pre-release product, so future work should not assume compatibility migrations for existing users are required [@agents]. ## Start With Current Surfaces @@ -51,13 +51,13 @@ The current runtime code is small but real. `rudderHome()` resolves `RUDDER_HOME Use [Use Prompt Capture](guides/runtime/use-prompt-capture) when hook or skill code needs to record, query, or delete prompt data. The hook runtime normalizes Claude Code, Codex, and Cursor submit/stop payloads, while the skill context helper reads prompt records for the active repository branch [@prompt-hook] [@skill]. -Telemetry uses the same local-state root for its anonymous identity file. It creates a PostHog client only when a project token is available and `DO_NOT_TRACK` is not `1`, and its capture helpers become no-ops when the client is unavailable [@telemetry]. Read [Telemetry](architecture/runtime/telemetry) with [Environment Variables](reference/configuration/environment-variables) before changing event capture, opt-out behavior, identity storage, release-build telemetry defaults, or shutdown behavior. +Telemetry uses the same local-state root for its anonymous installation id and local-only pseudonymization key. It creates a PostHog client only when a project token is available and `DO_NOT_TRACK` is not `1`, adds schema and Rudder-version properties to events, and leaves capture as a no-op when the client is unavailable [@telemetry]. Read [Telemetry](architecture/runtime/telemetry) with [Environment Variables](reference/configuration/environment-variables) before changing event schemas, pseudonymization, opt-out behavior, identity storage, release-build defaults, dispatch, or shutdown. ## Plugin, Tooling, And Checks -Rudder is packaged as `@ruddercode/rudder-plugin`, uses ESM, requires Node `>=24.0.0`, ships Claude Code and Codex plugin manifests, and builds a bundled prompt hook plus copied Drizzle migrations under `dist` [@package]. [Rudder Plugin Package](architecture/tooling/plugin-package) explains the plugin distribution surface; [Package Scripts](reference/tooling/package-scripts) and [TypeScript And Bundle Build](reference/tooling/typescript-build) give the exact command and compiler references. +Rudder is packaged as `@ruddercode/rudder-plugin`, uses ESM, requires Node `>=24.0.0`, ships Claude Code and Codex plugin manifests, and builds one bundled prompt-capture and telemetry runtime plus copied Drizzle migrations under `dist` [@package]. [Rudder Plugin Package](architecture/tooling/plugin-package) explains the plugin distribution surface; [Package Scripts](reference/tooling/package-scripts) and [TypeScript And Bundle Build](reference/tooling/typescript-build) give the exact command and compiler references. -For branch validation, start with [Run Checks](guides/contributor/run-checks). The local check flow verifies the centralized `.agents/skills` layout and agent attribution before running package commands, and the GitHub test workflow runs Node 24, `npm ci`, `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm test`, and `npm run build` on pushes and manual dispatch [@test-workflow]. [Contributor Automation](architecture/automation/contributor-automation), [Address PR Comments](guides/contributor/address-pr-comments), and [GitHub Workflows](reference/automation/github-workflows) cover the surrounding PR and automation surfaces. +For branch validation, start with [Run Checks](guides/contributor/run-checks). The local check flow verifies the centralized `.agents/skills` layout and agent attribution before running package commands, and the GitHub test workflow checks out full history, uses Node 24, runs `npm ci`, checks agent layout and Markdown, typechecks, enforces changed-line coverage through `npm run test:coverage`, and rebuilds on pushes and manual dispatch [@test-workflow]. [Contributor Automation](architecture/automation/contributor-automation), [Address PR Comments](guides/contributor/address-pr-comments), and [GitHub Workflows](reference/automation/github-workflows) cover the surrounding PR and automation surfaces. ## Releases diff --git a/almanac/guides/contributor/change-shared-infrastructure.md b/almanac/guides/contributor/change-shared-infrastructure.md index 043fdc3..dff3240 100644 --- a/almanac/guides/contributor/change-shared-infrastructure.md +++ b/almanac/guides/contributor/change-shared-infrastructure.md @@ -61,4 +61,4 @@ npm test npm run build ``` -Those commands map to `tsc --noEmit`, `node --test`, and a clean esbuild bundle plus migration copy to `dist`; the Test workflow runs the same sequence after layout and Markdown checks on Node 24 [@package] [@test-workflow]. If validation fails, keep the fix inside the same shared surface when possible. If the failure points to a protected path, use [Protected Paths](../../reference/contributor/protected-paths) instead of working around the rule. +Those commands map to `tsc --noEmit`, `node --test`, and a clean esbuild bundle plus migration copy to `dist` [@package]. CI checks out full history, runs layout and Markdown checks on Node 24, typechecks, replaces the local test command with `npm run test:coverage`, and rebuilds [@test-workflow]. The coverage script still runs the full Node suite and then requires 90% coverage for changed and untracked source lines [@package]. If validation fails, keep the fix inside the same shared surface when possible. If the failure points to a protected path, use [Protected Paths](../../reference/contributor/protected-paths) instead of working around the rule. diff --git a/almanac/guides/contributor/run-checks.md b/almanac/guides/contributor/run-checks.md index 773a9e0..a9e0c8a 100644 --- a/almanac/guides/contributor/run-checks.md +++ b/almanac/guides/contributor/run-checks.md @@ -54,7 +54,7 @@ npm test npm run build ``` -The package manifest defines `typecheck` as `tsc --noEmit`, `test` as `node --test`, and `build` as the esbuild prompt-hook bundle plus `drizzle/` copy [@package]. The CI test workflow uses Node 24, runs `npm ci`, checks agent layout and Markdown formatting, and then runs the same typecheck, test, and build sequence on every pushed branch and on manual dispatch [@test-workflow]. +The package manifest defines `typecheck` as `tsc --noEmit`, `test` as `node --test`, and `build` as the esbuild prompt-hook bundle plus `drizzle/` copy [@package]. The CI test workflow checks out full history, uses Node 24, runs `npm ci`, checks agent layout and Markdown formatting, typechecks, replaces the local `npm test` step with `npm run test:coverage`, and rebuilds on every pushed branch and on manual dispatch [@test-workflow]. That coverage script still runs the full Node suite, then requires at least 90% coverage for changed and untracked source lines through c8 LCOV plus `diff-cover` [@package]. ## Handle PR Comments diff --git a/almanac/guides/release/prepare-package-release.md b/almanac/guides/release/prepare-package-release.md index 509bb68..f457446 100644 --- a/almanac/guides/release/prepare-package-release.md +++ b/almanac/guides/release/prepare-package-release.md @@ -3,6 +3,9 @@ title: "Prepare Package Release" summary: "Prepare package release explains how to change the plugin package version so the publish and release-alert workflows ship the intended npm, tag, and GitHub Release artifacts." topics: [guides, release, package, automation, plugin] sources: + - id: release-skill + type: file + path: .agents/skills/prepare-package-release/SKILL.md - id: publish type: file path: .github/workflows/publish.yml @@ -12,21 +15,48 @@ sources: - id: package type: file path: package.json + - id: package-lock + type: file + path: package-lock.json + - id: codex-manifest + type: file + path: .codex-plugin/plugin.json + - id: claude-manifest + type: file + path: .claude-plugin/plugin.json + - id: marketplace + type: file + path: .claude-plugin/marketplace.json + - id: plugin-tests + type: file + path: test/plugin-package.test.ts --- # Prepare Package Release -Prepare a package release when a branch should publish a new `@ruddercode/rudder-plugin` version after merge to `main`. The release work is version-driven: `package.json` supplies the package name and version, the release-alert workflow tells the PR whether merge would publish the npm plugin package, create the plugin tag, or create a GitHub Release, and the publish workflow runs on `main` to create the missing artifacts [@package] [@release-alert] [@publish]. See [Release Automation](../../architecture/release/release-automation), [Artifact-Checked Plugin Publishing](../../decisions/release/artifact-checked-plugin-publishing), [Package Scripts](../../reference/tooling/package-scripts), and [GitHub Workflows](../../reference/automation/github-workflows) for the surrounding reference material. +Prepare a package release when a branch should publish a new `@ruddercode/rudder-plugin` version after merge to `main`. The centralized `prepare-package-release` skill owns the contributor procedure: it synchronizes every version-bearing manifest, ingests the complete change range since the previous release, Gardens the whole CodeAlmanac wiki, validates the package and wiki, and leaves artifact creation to the publish workflow [@release-skill]. The release work is version-driven: `package.json` supplies the package name and version, the release-alert workflow tells the PR whether merge would publish the npm plugin package, create the plugin tag, or create a GitHub Release, and the publish workflow runs on `main` to create the missing artifacts [@package] [@release-alert] [@publish]. The package version also has to stay synchronized across `package-lock.json`, the Codex and Claude plugin manifests, and both marketplace version fields because package tests enforce those values against `package.json` [@package-lock] [@codex-manifest] [@claude-manifest] [@marketplace] [@plugin-tests]. See [Release Automation](../../architecture/release/release-automation), [Artifact-Checked Plugin Publishing](../../decisions/release/artifact-checked-plugin-publishing), [Package Scripts](../../reference/tooling/package-scripts), and [GitHub Workflows](../../reference/automation/github-workflows) for the surrounding reference material. + +## Synchronize Version Inputs + +Invoke the release-preparation skill whenever a version-bearing manifest changes or a branch with a version bump needs review [@release-skill]. Begin from the complete branch and working-tree diff against `origin/main`, then confirm the intended semantic version before editing [@release-skill]. Use a package version change to signal a user-facing release; the release-alert workflow's no-release PR comment tells contributors to bump `package.json` with `npm version patch --no-git-tag-version` when they intend to ship a user-facing change [@release-alert]. + +Run `npm version --no-git-tag-version`, treating `package.json` as the release version source of truth. Synchronize the resulting exact version into the root and root-package entries in `package-lock.json`, `.codex-plugin/plugin.json`, `.claude-plugin/plugin.json`, and both the plugin version and npm source version in `.claude-plugin/marketplace.json` [@release-skill] [@package] [@package-lock] [@codex-manifest] [@claude-manifest] [@marketplace]. Do not create or push a tag: the publish workflow owns `rudder-plugin-v` after merge [@release-skill] [@publish]. + +## Refresh CodeAlmanac + +After the manifests agree, find the most recent `rudder-plugin-v*` tag and define the release range from that tag through `HEAD` [@release-skill]. Do not substitute `origin/main` for this source boundary: changes merged since the previous tag still belong to the new release. Stop and ask for direction if no previous release tag exists [@release-skill]. + +Run CodeAlmanac Ingest over that committed release range plus the staged and unstaged working-tree diff [@release-skill]. After Ingest completes, run Garden to reconcile the newly captured release knowledge with the rest of the wiki. Wait for both jobs to finish, attaching to their run IDs when they return early, then review all resulting `almanac/**/*.md` and `almanac/topics.yaml` changes [@release-skill]. A no-op is valid when the release contains no durable project knowledge; do not manufacture a version-only wiki edit [@release-skill]. ## Choose The Version The package manifest currently names the package `@ruddercode/rudder-plugin` and stores the release version in the `version` field [@package]. The publish and release-alert workflows both compute `tag="rudder-plugin-v${version}"` from that manifest value [@publish] [@release-alert]. -Use a package version change to signal a user-facing release. The release-alert workflow's no-release PR comment tells contributors to bump `package.json` with `npm version patch --no-git-tag-version` when they intend to ship a user-facing change [@release-alert]. Use the appropriate semver level for the change, and do not create the git tag locally as part of the PR because the publish workflow owns tag creation after registry publishing succeeds [@publish]. +Use the appropriate semver level for the change. Package tests compare `package-lock.json`, `.codex-plugin/plugin.json`, `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json` plugin metadata, and `.claude-plugin/marketplace.json` npm source metadata against `package.json`, so a release version bump is incomplete until all of those fields match [@plugin-tests]. ## Validate Before Merge -Run the package's publishability checks before relying on automation. `prepublishOnly` runs `npm run typecheck`, `npm test`, and `npm run build` [@package]. Those are the same checks described in [Run Checks](../contributor/run-checks), and they catch local TypeScript, test, and build failures before the release branch reaches `main`. +Run `codealmanac validate`, `npm run typecheck`, `npm test`, and `npm run build` before relying on automation; when Ingest changes Markdown, also run `npm run format:markdown:check` [@release-skill]. Run `npm run test:coverage` to exercise the same changed-line coverage boundary used by CI and release publishing [@package] [@publish]. The package's `prepublishOnly` script runs typecheck and `npm test`, whose lifecycle rebuilds the hook bundle before the test suite [@package]. The publish workflow adds the release packaging gate by running `npm run test:coverage`, `npm run build`, and `npm pack --dry-run` when a release artifact is missing [@publish]. Those commands are also described in [Run Checks](../contributor/run-checks), and they catch local TypeScript, test, build, coverage, wiki, and packaging failures before the release branch reaches `main`. Also confirm that the package name remains exactly `@ruddercode/rudder-plugin`. Both release workflows fail before release work if `package.json` contains another name [@publish] [@release-alert]. diff --git a/almanac/guides/runtime/use-prompt-capture.md b/almanac/guides/runtime/use-prompt-capture.md index 84429f3..47ec5a8 100644 --- a/almanac/guides/runtime/use-prompt-capture.md +++ b/almanac/guides/runtime/use-prompt-capture.md @@ -53,9 +53,9 @@ Use the executable path for plugin hook commands. `bin/rudder-prompt-hook.ts` re ## Query Branch Intent -Use `promptsForSession(source, sessionId)` when starting from a known agent session, and use `promptsForBranch(repository, branch)` when the skill needs all prompt intent associated with a repository branch [@prompt-tagger]. `skills/rudder/scripts/context.mjs` resolves the current repository, branch, base ref, merge base, tracked and untracked changes, test-path candidates, and prompt records for that repository/branch, then prints one JSON object for the skill to inspect [@context-script]. +Use `promptsForSession(source, sessionId)` when starting from a known agent session, and use `promptsForBranch(repository, branch)` when the skill needs all prompt intent associated with a repository branch [@prompt-tagger]. `skills/rudder/scripts/context.mjs` resolves the current repository, branch, base ref, merge base, tracked and untracked changes, test-path candidates, changed test-line counts, and prompt records for that repository/branch, then prints one JSON object for the skill to inspect [@context-script]. Each prompt object includes exact text, optional previous agent output, identifiers, and submission and reconciliation timestamps [@context-script]. -The skill treats those helper classifications as candidates. `skills/rudder/SKILL.md` tells the agent to inspect the returned merge base, changed paths, captured prompts, repository instructions, production diff, existing tests, and native test/coverage configuration before deciding what to reset or generate [@skill]. +Start a run with `--phase start`; retain its generated `rudderRunId` and resolved `baseRef`, then use both on `--phase refresh` calls after follow-up answers and before reporting [@context-script] [@skill]. The skill treats helper classifications as candidates and requires the agent to inspect the returned merge base, changed paths, captured prompts, repository instructions, production diff, existing tests, and native test/coverage configuration before deciding what to reset or generate [@skill]. ## Respect Data Controls diff --git a/almanac/reference/automation/github-workflows.md b/almanac/reference/automation/github-workflows.md index b096a11..bdb3ae1 100644 --- a/almanac/reference/automation/github-workflows.md +++ b/almanac/reference/automation/github-workflows.md @@ -18,6 +18,9 @@ sources: - id: release-alert type: file path: .github/workflows/release-alert.yml + - id: package + type: file + path: package.json --- # GitHub Workflows Reference @@ -33,7 +36,7 @@ This reference covers the four GitHub Actions workflows in Rudder: package valid ## Test -The Test workflow runs one `test` job on `ubuntu-latest` [@test-workflow]. The job checks out the repository, sets up Node 24, installs dependencies with `npm ci`, then runs `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm test`, and `npm run build` [@test-workflow]. These commands are the CI version of the package and documentation checks listed in [Package Scripts](../tooling/package-scripts). +The Test workflow runs one `test` job on `ubuntu-latest` [@test-workflow]. The job checks out full repository history with `fetch-depth: 0`, sets up Node 24, installs dependencies with `npm ci`, then runs `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm run test:coverage`, and `npm run build` [@test-workflow]. The coverage command runs the full Node suite under c8 and uses `diff-cover` to require 90% coverage for changed and untracked lines, so Git history is part of the CI input [@package] [@test-workflow]. These commands are the CI version of the package and documentation checks listed in [Package Scripts](../tooling/package-scripts). ## Enforce Agent Guards @@ -45,7 +48,7 @@ The Danger workflow runs one `danger` job on pull requests targeting `main` [@da The publish workflow serializes runs with concurrency group `publish-rudder-plugin` and does not cancel an in-progress publish [@publish-workflow]. The job checks out full history, reads `package.json` for `name` and `version`, derives `tag=rudder-plugin-v`, and fails if the package name is not exactly `@ruddercode/rudder-plugin` [@publish-workflow]. -The first step sets artifact flags. It checks npmjs.org with `npm view`, checks the plugin tag with `git rev-parse`, and checks the GitHub Release through `gh api repos/${GITHUB_REPOSITORY}/releases/tags/${tag}` [@publish-workflow]. When any artifact is missing, the workflow sets up Node 24, installs the latest npm for Trusted Publishers support, runs `npm ci`, writes release telemetry defaults from `POSTHOG_PROJECT_TOKEN` and `POSTHOG_HOST`, validates the plugin package with `DO_NOT_TRACK=1`, publishes to npmjs.org when needed, pushes the tag when needed, and creates the GitHub Release titled `Rudder v` with generated notes when missing [@publish-workflow]. +The first step sets artifact flags. It checks npmjs.org with `npm view`, checks the plugin tag with `git rev-parse`, and checks the GitHub Release through `gh api repos/${GITHUB_REPOSITORY}/releases/tags/${tag}` [@publish-workflow]. When any artifact is missing, the workflow sets up Node 24, installs the latest npm for Trusted Publishers support, runs `npm ci`, writes release telemetry defaults from `POSTHOG_PROJECT_TOKEN` and `POSTHOG_HOST`, validates agent layout, typechecking, 90% changed-line coverage, build output, and package contents with `DO_NOT_TRACK=1`, publishes to npmjs.org when needed, pushes the tag when needed, and creates the GitHub Release titled `Rudder v` with generated notes when missing [@publish-workflow]. ## Plugin Release Alert diff --git a/almanac/reference/configuration/environment-variables.md b/almanac/reference/configuration/environment-variables.md index 4a01153..ba1e5f8 100644 --- a/almanac/reference/configuration/environment-variables.md +++ b/almanac/reference/configuration/environment-variables.md @@ -1,6 +1,6 @@ --- title: "Environment Variables" -summary: "Rudder runtime configuration currently comes from environment variables covering local state, migration lookup, dashboard port selection, telemetry, and update checks." +summary: "Rudder runtime configuration currently comes from environment variables covering local state, migration lookup, exported port selection, telemetry, and update checks." topics: [reference, configuration, runtime, telemetry] sources: - id: db-client @@ -17,7 +17,7 @@ sources: path: skills/rudder/scripts/update.mjs --- -Rudder currently reads environment variables for local state location, migration lookup, dashboard port selection, telemetry configuration, and update checks. `RUDDER_HOME`, `RUDDER_MIGRATIONS_PATH`, and `RUDDER_PORT` are read by the database client module; `POSTHOG_PROJECT_TOKEN`, `POSTHOG_API_KEY`, `POSTHOG_HOST`, and `DO_NOT_TRACK` control the PostHog telemetry client and opt-out behavior; `RUDDER_DISABLE_UPDATE_CHECK` disables skill update lookup [@db-client] [@telemetry] [@update-script]. This reference lists the exact parsing and defaults used by those helpers; the surrounding runtime architecture is covered by [Local State](../../architecture/runtime/local-state), [Prompt Branch Store](../../architecture/runtime/prompt-branch-store), and [Telemetry](../../architecture/runtime/telemetry). +Rudder currently reads environment variables for local state location, migration lookup, exported port selection, telemetry configuration, and update checks. `RUDDER_HOME`, `RUDDER_MIGRATIONS_PATH`, and `RUDDER_PORT` are read by the database client module; `POSTHOG_PROJECT_TOKEN`, `POSTHOG_HOST`, and `DO_NOT_TRACK` control the PostHog telemetry client and opt-out behavior; `RUDDER_DISABLE_UPDATE_CHECK` disables skill update lookup [@db-client] [@telemetry] [@update-script]. This reference lists the exact parsing and defaults used by those helpers; the surrounding runtime architecture is covered by [Local State](../../architecture/runtime/local-state), [Prompt Branch Store](../../architecture/runtime/prompt-branch-store), and [Telemetry](../../architecture/runtime/telemetry). ## Variables @@ -26,19 +26,18 @@ Rudder currently reads environment variables for local state location, migration | `RUDDER_HOME` | `rudderHome()` | Any non-empty string path. | Empty or unset values fall back to `join(homedir(), '.rudder')` because the helper uses `process.env.RUDDER_HOME || ...` [@db-client]. | | `RUDDER_MIGRATIONS_PATH` | `migrationsFolder()` inside `openDb()` | Any string path, including an empty string. | Only `null` or `undefined` fall back to the repository `drizzle/` directory because the helper uses nullish coalescing [@db-client]. | | `RUDDER_PORT` | `rudderPort()` | A value that `Number()` converts to an integer greater than `0` and less than `65536`. | Invalid, unset, fractional, zero, negative, or out-of-range values return `41789` [@db-client]. | -| `POSTHOG_PROJECT_TOKEN` | Telemetry module constant | Any non-empty string. | Preferred telemetry token source; empty or unset values fall back to `POSTHOG_API_KEY`, then the built-in release-build token [@telemetry] [@telemetry-build-config]. | -| `POSTHOG_API_KEY` | Telemetry module constant | Any non-empty string. | Legacy telemetry token source used only when `POSTHOG_PROJECT_TOKEN` is unset or empty [@telemetry]. | +| `POSTHOG_PROJECT_TOKEN` | Telemetry module constant | Any non-empty string. | Preferred telemetry token source; empty or unset values fall back directly to the built-in release-build token [@telemetry] [@telemetry-build-config]. | | `POSTHOG_HOST` | Telemetry module constant | Any non-empty string, passed to the PostHog client as `host`. | Empty or unset values fall back to the built-in release-build host, then `https://us.i.posthog.com` [@telemetry] [@telemetry-build-config]. | | `DO_NOT_TRACK` | `telemetryDisabled()` | Exactly `1` disables telemetry. | Any other value, including unset, does not disable telemetry by itself [@telemetry]. | | `RUDDER_DISABLE_UPDATE_CHECK` | `checkForUpdate()` | Exactly `1` disables registry update lookup. | Any other value, including unset, allows `scripts/update.mjs check` to use fresh cache or query npm [@update-script]. | ## Read Timing -`RUDDER_HOME` is read each time `rudderHome()` runs, `RUDDER_MIGRATIONS_PATH` is read when `openDb()` applies migrations, and `RUDDER_PORT` is read each time `rudderPort()` runs [@db-client]. `POSTHOG_PROJECT_TOKEN`, `POSTHOG_API_KEY`, and `POSTHOG_HOST` are assigned to module-level constants when `src/telemetry.ts` is evaluated [@telemetry]. `telemetryDisabled()` defaults to `process.env` but also accepts an explicit environment object, which makes the `DO_NOT_TRACK` check callable against injected values [@telemetry]. `RUDDER_DISABLE_UPDATE_CHECK` is read when `checkForUpdate()` runs [@update-script]. +`RUDDER_HOME` is read each time `rudderHome()` runs, `RUDDER_MIGRATIONS_PATH` is read when `openDb()` applies migrations, and `RUDDER_PORT` is read each time `rudderPort()` runs [@db-client]. `POSTHOG_PROJECT_TOKEN` and `POSTHOG_HOST` are assigned to module-level constants when `src/telemetry.ts` is evaluated [@telemetry]. `telemetryDisabled()` defaults to `process.env` but also accepts an explicit environment object, which makes the `DO_NOT_TRACK` check callable against injected values [@telemetry]. `RUDDER_DISABLE_UPDATE_CHECK` is read when `checkForUpdate()` runs [@update-script]. ## State Paths -When `RUDDER_HOME` is unset, the runtime state root is `~/.rudder`; when it is set to a non-empty value, that value becomes the state root [@db-client]. The SQLite database path is always `/rudder.db` [@db-client]. Telemetry identity uses the same state root and stores the anonymous id at `/identity.json` [@telemetry]. The update helper stores its cache at `/update-state.json` [@update-script]. Developers using [Use Prompt Capture](../../guides/runtime/use-prompt-capture) should set `RUDDER_HOME` before opening the database when they need isolated local state. +When `RUDDER_HOME` is unset, the runtime state root is `~/.rudder`; when it is set to a non-empty value, that value becomes the state root [@db-client]. The SQLite database path is always `/rudder.db` [@db-client]. Telemetry uses the same state root and stores the anonymous installation id plus local-only pseudonymization key at `/identity.json` [@telemetry]. The update helper stores its cache at `/update-state.json` [@update-script]. Developers using [Use Prompt Capture](../../guides/runtime/use-prompt-capture) should set `RUDDER_HOME` before opening the database when they need isolated local state. ## Telemetry Disablement diff --git a/almanac/reference/tooling/package-scripts.md b/almanac/reference/tooling/package-scripts.md index 83c646b..08c4593 100644 --- a/almanac/reference/tooling/package-scripts.md +++ b/almanac/reference/tooling/package-scripts.md @@ -12,12 +12,15 @@ sources: - id: test-workflow type: file path: .github/workflows/test.yml + - id: publish-workflow + type: file + path: .github/workflows/publish.yml - id: check-skill type: file path: .agents/skills/check-changed-folders/SKILL.md --- -This reference lists the npm scripts defined by Rudder's package and the local or CI automation that reuses them. The scripts are the package-level command contract for typechecking, testing, building, database migration generation, and the prepublish gate [@package-json]. The [package baseline](../../architecture/tooling/package-baseline) explains how that contract fits the repository. +This reference lists the npm scripts defined by Rudder's package and the local or CI automation that reuses them. The scripts are the package-level command contract for typechecking, testing, changed-line coverage, building, database migration generation, and the prepublish gate [@package-json]. The [package baseline](../../architecture/tooling/package-baseline) explains how that contract fits the repository. ## Script Table @@ -29,18 +32,19 @@ This reference lists the npm scripts defined by Rudder's package and the local o | `danger:ci` | `danger ci --failOnErrors` | Runs Danger with failing errors for CI agent-guard enforcement [@package-json]. | | `check:agent-layout` | `test -L .claude/skills && test -L .codex/skills && test .claude/skills -ef .agents/skills && test .codex/skills -ef .agents/skills && test ! -e .claude/commands && grep -Fxq '@AGENTS.md' CLAUDE.md` | Verifies Claude/Codex skill symlinks, absence of Claude command aliases, and the `CLAUDE.md` handoff [@package-json]. | | `typecheck` | `tsc --noEmit` | Runs TypeScript checking without writing build output [@package-json]. | -| `build` | `rm -rf dist && esbuild bin/rudder-prompt-hook.ts --bundle --platform=node --format=esm --target=node24 --outfile=dist/rudder-prompt-hook.mjs && cp -R drizzle dist/drizzle` | Removes old `dist` output, bundles the prompt hook for Node ESM, then copies generated Drizzle migrations into the package build tree [@package-json]. | +| `build` | `rm -rf dist && esbuild bin/rudder-prompt-hook.ts --bundle --platform=node --format=esm --target=node24 --outfile=dist/rudder-prompt-hook.mjs && cp -R drizzle dist/drizzle` | Removes old `dist` output, bundles the prompt-capture and telemetry entrypoint for Node ESM, then copies generated Drizzle migrations into the package build tree [@package-json]. | | `pretest` | `npm run build` | Rebuilds the hook bundle before tests [@package-json]. | | `test` | `node --test` | Runs Node's built-in test runner [@package-json]. | +| `test:coverage` | `npm run build && c8 node --test && diff-cover coverage/lcov.info --fail-under=90 --show-uncovered --include-untracked` | Builds first, runs the full Node suite under c8, writes LCOV, and fails when changed or untracked source lines are below 90% coverage [@package-json]. | | `prepack` | `npm run build` | Rebuilds package artifacts before `npm pack` [@package-json]. | | `prepublishOnly` | `npm run typecheck && npm test` | Runs typecheck and the test lifecycle before publishing; `npm test` invokes `pretest`, so the bundle is rebuilt before the test suite [@package-json]. | ## Automation Consumers -The Test workflow installs dependencies with `npm ci`, then runs `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm test`, and `npm run build` in that order [@test-workflow]. The local check skill runs `npm run typecheck`, `npm test`, and `npm run build` after enforcing the centralized agent-instruction layout, verifying agent attribution, and installing dependencies when `node_modules/` is missing [@check-skill]. +The Test workflow checks out full Git history, installs dependencies with `npm ci`, then runs `npm run check:agent-layout`, `npm run format:markdown:check`, `npm run typecheck`, `npm run test:coverage`, and `npm run build` in that order [@test-workflow]. Full history is required because `diff-cover` compares LCOV results with changed lines from Git [@test-workflow] [@package-json]. The local check skill remains the faster branch gate: it runs `npm run typecheck`, `npm test`, and `npm run build` after enforcing the centralized agent-instruction layout, verifying agent attribution, and installing dependencies when `node_modules/` is missing [@check-skill]. -`prepublishOnly` relies on the npm test lifecycle for the build, and `prepack` rebuilds again before packaging [@package-json]. The `build` copy step is part of the database runtime contract because the installed prompt hook points `RUDDER_MIGRATIONS_PATH` at `dist/drizzle`; the decision is recorded in [Generated Drizzle Migrations](../../decisions/database/generated-drizzle-migrations) [@db-client]. The release workflow behavior is covered from the GitHub Actions side in the [GitHub Workflows](../automation/github-workflows) reference, release preparation is covered in [Prepare Package Release](../../guides/release/prepare-package-release), and the contributor-facing procedure is covered in [Run Checks](../../guides/contributor/run-checks). +The c8 configuration measures `bin/**/*.ts`, `skills/**/*.mjs`, and `src/**/*.ts`, excludes `dist/**` and `test/**`, enables `all`, and emits the LCOV report consumed by `diff-cover` [@package-json]. `prepublishOnly` itself relies on the ordinary npm test lifecycle for the build, and `prepack` rebuilds again before packaging [@package-json]. The publish workflow separately runs `test:coverage` before packaging, so release automation enforces the changed-line threshold even though `npm publish`'s lifecycle hook uses `npm test` [@publish-workflow] [@package-json]. The `build` copy step is part of the database runtime contract because the installed prompt hook points `RUDDER_MIGRATIONS_PATH` at `dist/drizzle`; the decision is recorded in [Generated Drizzle Migrations](../../decisions/database/generated-drizzle-migrations) [@db-client]. The release workflow behavior is covered from the GitHub Actions side in the [GitHub Workflows](../automation/github-workflows) reference, release preparation is covered in [Prepare Package Release](../../guides/release/prepare-package-release), and the contributor-facing procedure is covered in [Run Checks](../../guides/contributor/run-checks). ## Change Surface -Changes to `typecheck`, `test`, or `build` affect local checks, the Test workflow, and package publication [@package-json] [@test-workflow] [@check-skill]. Changes to `build` can also affect runtime prompt capture if packaged output no longer includes `dist/rudder-prompt-hook.mjs` or `dist/drizzle` [@package-json]. Changes to `db:generate` affect migration-generation work and should be checked against the runtime migration decision [@package-json]. +Changes to `typecheck`, `test`, or `build` affect local checks, CI, and package publication, while changes to `test:coverage` or the c8 configuration affect the CI and publish changed-line gate [@package-json] [@test-workflow] [@check-skill]. Changes to `build` can also affect runtime prompt capture and Rudder usage telemetry if packaged output no longer includes `dist/rudder-prompt-hook.mjs` or `dist/drizzle` [@package-json]. Changes to `db:generate` affect migration-generation work and should be checked against the runtime migration decision [@package-json]. diff --git a/almanac/reference/tooling/typescript-build.md b/almanac/reference/tooling/typescript-build.md index c78b32e..1564736 100644 --- a/almanac/reference/tooling/typescript-build.md +++ b/almanac/reference/tooling/typescript-build.md @@ -1,6 +1,6 @@ --- title: "TypeScript And Bundle Build" -summary: "This reference records Rudder's no-emit TypeScript checking contract and esbuild bundle output for the plugin prompt hook." +summary: "This reference records Rudder's no-emit TypeScript checking contract and esbuild bundle output for the plugin prompt-capture and telemetry runtime." topics: [reference, typescript, tooling, package, plugin] sources: - id: tsconfig @@ -12,9 +12,12 @@ sources: - id: hook-bin type: file path: bin/rudder-prompt-hook.ts + - id: publish-workflow + type: file + path: .github/workflows/publish.yml --- -This reference defines Rudder's current TypeScript and bundle contract. `tsconfig.json` is a strict, no-emit NodeNext setup for `bin/**/*.ts`, `dangerfile.ts`, and `src/**/*.ts`; `npm run build` uses esbuild to bundle `bin/rudder-prompt-hook.ts` into `dist/rudder-prompt-hook.mjs` and then copies `drizzle/` into `dist/drizzle` [@tsconfig] [@package-json] [@hook-bin]. The package manifest declares the package as ESM, requires Node `>=24.0.0`, and wires `typecheck`, `build`, `pretest`, `prepack`, and `prepublishOnly` to that contract [@package-json]. +This reference defines Rudder's current TypeScript and bundle contract. `tsconfig.json` is a strict, no-emit NodeNext setup for `bin/**/*.ts`, `dangerfile.ts`, and `src/**/*.ts`; `npm run build` uses esbuild to bundle `bin/rudder-prompt-hook.ts` into `dist/rudder-prompt-hook.mjs` and then copies `drizzle/` into `dist/drizzle` [@tsconfig] [@package-json] [@hook-bin]. The bundled entrypoint handles both host prompt hooks and internal Rudder usage events [@hook-bin]. The package manifest declares the package as ESM, requires Node `>=24.0.0`, and wires `typecheck`, `build`, `pretest`, `test:coverage`, `prepack`, and `prepublishOnly` to that contract [@package-json]. ## Package Context @@ -52,7 +55,7 @@ The NodeNext settings make the compiler follow Node's ESM-aware module rules, wh ## Bundle Output -The repository no longer has a `tsconfig.build.json` overlay. Build output is generated by esbuild from `bin/rudder-prompt-hook.ts` with `--bundle`, `--platform=node`, `--format=esm`, `--target=node24`, and `--outfile=dist/rudder-prompt-hook.mjs` [@package-json] [@hook-bin]. The build then copies `drizzle/` into `dist/drizzle` so the installed prompt hook can point migration lookup at packaged migration files [@package-json]. +The repository no longer has a `tsconfig.build.json` overlay. Build output is generated by esbuild from `bin/rudder-prompt-hook.ts` with `--bundle`, `--platform=node`, `--format=esm`, `--target=node24`, and `--outfile=dist/rudder-prompt-hook.mjs` [@package-json] [@hook-bin]. The build then copies `drizzle/` into `dist/drizzle` so the installed runtime can point prompt-capture migration lookup at packaged migration files [@package-json] [@hook-bin]. ## Included Sources @@ -68,4 +71,4 @@ No test glob is included in the TypeScript config, so package typechecking is sc ## Consuming Scripts -`typecheck` runs `tsc --noEmit`, matching the config's no-emit intent [@package-json] [@tsconfig]. `build` removes `dist`, bundles the prompt hook with esbuild, and copies `drizzle/` into `dist/drizzle` [@package-json]. `pretest` and `prepack` both run `npm run build`, while `prepublishOnly` runs `npm run typecheck && npm test`; because `npm test` triggers `pretest`, package publication depends on typecheck, a fresh bundle, and the test suite [@package-json]. +`typecheck` runs `tsc --noEmit`, matching the config's no-emit intent [@package-json] [@tsconfig]. `build` removes `dist`, bundles the runtime entrypoint with esbuild, and copies `drizzle/` into `dist/drizzle` [@package-json]. `test:coverage` also starts with a build before running the full suite under c8 and checking changed lines with `diff-cover` [@package-json]. `pretest` and `prepack` both run `npm run build`, while `prepublishOnly` runs `npm run typecheck && npm test`; because `npm test` triggers `pretest`, the npm lifecycle depends on typecheck, a fresh bundle, and the test suite, while the publish workflow adds the explicit changed-line coverage gate [@package-json] [@publish-workflow]. diff --git a/almanac/topics.yaml b/almanac/topics.yaml index b10e217..586bfe9 100644 --- a/almanac/topics.yaml +++ b/almanac/topics.yaml @@ -53,7 +53,7 @@ topics: parents: [package, product-intent] - slug: product-intent title: Product Intent - description: Proposed Rudder product behavior documented as intent rather than current runtime implementation. + description: Rudder's prompt-backed product workflow, implemented constraints, and user-intent model. parents: [concepts] - slug: prompt-capture title: Prompt Capture @@ -93,7 +93,7 @@ topics: parents: [runtime] - slug: test-generation-intent title: Test Generation Intent - description: README-backed proposed test-generation behavior and intent standards. + description: Intent-backed test-generation behavior, source tags, coverage questions, and workflow standards. parents: [product-intent] - slug: tooling title: Tooling @@ -109,5 +109,5 @@ topics: parents: [contributor-workflow, package] - slug: wiki title: Wiki - description: CodeAlmanac wiki structure, manual pages, and reference metadata. + description: CodeAlmanac wiki structure, routing pages, and maintenance reference metadata. parents: []