Are EK9 dev/ test files exempt from capability enforcement?

← Package Capability Security · Ref: Q1278

Yes — code under a 'dev/' directory is EXEMPT from capability enforcement. Test files, fixtures, and development-time utilities living under dev/ may freely use any gated type without declaring the matching capability in the package's 'capabilities' list.

THE RULE

The capability check in 'CapabilityTypeReferenceOrError.checkNode' early-returns when 'symbolsAndScopes.isDevSource()' is true. Dev sources are identified by the directory structure: anything under 'dev/' is flagged as dev source and skipped during capability enforcement.

PRACTICAL EFFECT

  my.publishable.library/
    main.ek9                // publishable, subject to capability rules
    helper.ek9              // publishable, subject to capability rules
    dev/
      tests.ek9             // EXEMPT — can use Stdout, File, EnvVars freely
      testFixtures.ek9      // EXEMPT

The main.ek9 and helper.ek9 must declare every gated type they use. tests.ek9 can import, call, assert, print to stdout, read environment variables, open test files — whatever the tests need — without any of those types appearing in the capabilities list.

WHY THE EXEMPTION EXISTS

Tests naturally need access to system resources in ways that production code does not:

  - Reading fixture files from the filesystem
  - Mocking environment variables
  - Capturing stdout/stderr to verify output
  - Constructing instances of types that wrap TCP, File, or Sensitive data

If dev/ code had to declare every gated type used in test fixtures, test suites would force the production 'capabilities' list to grow to include every test-only dependency. That would defeat the purpose of the rule: the production code's capability declaration would no longer be a trustworthy claim about what the library does at runtime — it would be contaminated by test-fixture requirements.

Separating test code into 'dev/' and exempting it means:

  - Production capability declarations stay clean and accurate
  - Tests remain free to exercise edge cases without ceremony
  - Consumers auditing a library's capabilities see only what the production code needs

WHAT COUNTS AS DEV CODE

Any file whose path includes a 'dev' directory segment (at the package root or nested). The EK9 project layout convention is to keep tests under 'dev/' directly inside the package directory, alongside the main source files.

WHAT IS NOT EXEMPT

  - Files NOT under dev/ — regardless of whether they contain tests, fixtures, or development-time code. If a file is in the main source tree and the package is publishable, it goes through capability enforcement.
  - Files under dev/ in non-publishable packages — but this doesn't matter, because non-publishable packages are entirely exempt regardless of directory (see Q1275).

HOW THIS INTERACTS WITH THE TEST RUNNER

EK9's built-in test runner ('ek9 -t') discovers and executes tests in the 'dev/' directory. The test runner itself is not bound by the library's capability declarations — it operates at a higher trust level because it is explicitly invoked by the developer to exercise their own code, not by a downstream consumer pulling a dependency.

See Q1270 for the four-condition publishable rule. See Q1275 for non-publishable exemption. See Q1271 for capability declaration syntax.

Example

defines module qa.packagecapabilities.devexemption

  defines package
    version <- 1.0.0-0
    description <- "Shows main code declaring only what it uses; dev/ tests would be exempt"
    license <- "MIT"
    publicAccess <- true
    capabilities <- ["org.ek9.lang::Stdout"]

  defines function

    productionHelper()
      stdout <- Stdout()
      stdout.println("This is production code — must declare its own capabilities")
Other ways to ask this
  • Do my test files need capability declarations?
  • Can test code use Stdout and File freely without adding capabilities?
  • Why are dev/ directories treated specially for capability checks?
  • Where do I put test fixtures that use gated types?

Coming from another language?

Maven/Gradle test scope: dependencies in 'test' scope are not packaged with the production artifact but have no runtime capability implications. npm devDependencies: similar, only controls what's installed. Python dev-dependencies: same pattern. EK9: dev/ directory is a structural boundary for capability enforcement — dev code is not part of the published supply chain and is exempt from the rule.

Keywords: exemption, dev, test, fixture, development, test runner