CareerVector System Stories

This catalog covers stories the system must guarantee so user stories remain true. User stories describe visible applicant and collaborator goals. System stories describe platform behavior, safety rails, orchestration, and test infrastructure that users should not need to think about.

System stories are part of the product contract. They are not implementation notes, and they are not tied to a single provider, runner, framework, or developer machine.


Boundary with user stories

Story type Describes Example
User story A person or agent-visible workspace outcome "A collaborator adds a job and the owner sees it live."
System story The product machinery that makes the outcome reliable "Every synthetic test workspace records its origin and can be cleaned up deterministically."
Efficiency story The cost, speed, quota, and budget posture of the same behavior "The default test run spends zero external provider budget."

Do not duplicate wiki/content/stories/USER-STORIES.md here. If a story starts with "As a job seeker", it belongs in user stories. If it starts with "The system must", it belongs here or in efficiency stories.


Current testing taxonomy

CareerVector testing is grouped by execution cost and release confidence, not by source directory alone.

Bucket Purpose Default budget External providers Typical trigger
free-fast Fast semantic checks for pure logic, schemas, operation contracts, and product invariants Zero Forbidden Every local loop and pull request
free-slow Slower free checks such as heavier integration suites, local worker emulation, persistence, and convergence scenarios Zero Forbidden Pull request, pre-merge, targeted local run
browser-smoke Browser proof that the app boots and critical flows render and respond Zero Forbidden unless explicitly mocked Pull request and pre-release smoke
release-gate The full release confidence gate across free suites and approved browser checks Zero by default Provider-neutral; paid calls require explicit opt-in outside the default gate Before a release candidate ships
paid-forbidden A sentinel bucket that proves tests do not accidentally call paid or quota-sensitive providers Zero Must fail on live paid-provider use Every release gate and provider-adapter change

The default posture is zero budget. A test that needs paid LLM, scraping, hosting, or API quota must be opt-in, visibly named, and excluded from the default taxonomy.


Provider-neutral quality contract

System story S1: Provider-neutral test execution

Given the product supports multiple model and infrastructure providers, when a test validates CareerVector behavior, then the test must assert the product contract rather than a provider-specific response shape unless the provider adapter itself is the unit under test.

Acceptance criteria:

  • Product tests use mocks, fixtures, fake adapters, or deterministic local providers by default.
  • Provider IDs, model names, API URLs, and billing semantics are not embedded in story text.
  • Adapter-specific tests live at the adapter boundary and still run in a zero-budget mode by default.
  • paid-forbidden catches accidental live calls from all default test buckets.

System story S2: Provider failures are normalized

Given any configured provider can fail, rate-limit, or return malformed data, when tests simulate those failures, then the system reports normalized product outcomes such as retryable failure, blocked request, clean error, or degraded result instead of coupling stories to provider-specific errors.

Acceptance criteria:

  • Failure fixtures cover malformed output, timeout, quota exhaustion, and explicit refusal.
  • The product state records enough origin to debug the failure without storing secrets.
  • The same user-visible behavior can be tested against any provider adapter.

Synthetic workspace lifecycle

System story S3: Synthetic workspace origin is explicit

Given automated tests create workspaces, when a workspace is created by a test bucket, then its origin metadata must identify it as synthetic and include enough structured context to trace the bucket, suite, and run.

Acceptance criteria:

  • Synthetic workspaces are marked as test-created, not user-created.
  • Origin metadata distinguishes at least free-fast, free-slow, browser-smoke, release-gate, and any explicitly opted-in paid run.
  • Origin metadata contains no secrets and no personal file paths.
  • Test-created records can be queried independently from real workspaces.

System story S4: Synthetic workspace cleanup is deterministic

Given tests may fail midway, when a test run exits or a cleanup job runs later, then synthetic workspaces and associated artifacts can be removed by origin metadata without touching real user data.

Acceptance criteria:

  • Cleanup is based on synthetic origin markers, not name guesses.
  • Cleanup is idempotent and safe to run repeatedly.
  • Failed test runs leave enough metadata for later cleanup.
  • Cleanup covers workspace rows, generated documents, queued process requests, browser artifacts, and provider-mock artifacts where applicable.

Quality service integration

System story S5: Quality service is a product surface

Given CareerVector needs repeatable quality gates, when quality.careervector.corbet.ch receives a quality request, then it coordinates the current testing taxonomy without becoming tied to a single code host, provider, or local environment.

Acceptance criteria:

  • The service understands bucket names as product vocabulary: free-fast, free-slow, browser-smoke, release-gate, and paid-forbidden.
  • Requests default to zero-budget execution.
  • Results report bucket, status, evidence, synthetic workspace cleanup status, and any provider opt-in that was explicitly requested.
  • The service never requires secrets in request payloads.
  • The service can reject a request that asks for paid or quota-sensitive work without explicit opt-in.

System story S6: Quality results are auditable

Given a release or change depends on quality evidence, when a quality run completes, then the result must explain what ran, what was skipped, what was blocked by budget policy, and what cleanup happened.

Acceptance criteria:

  • A passing result includes command or runner identity, bucket status, and artifact links or IDs where available.
  • A failing result preserves enough evidence to reproduce the failure.
  • A skipped paid or live-provider run is reported as skipped, not passed.
  • paid-forbidden passing means no forbidden paid-provider path was exercised.
Source: wiki/content/stories/SYSTEM-STORIES.md