Milestone 0.5 test runbook¶
Use this runbook to test the 0.5.1a0 milestone features end to end. Run each feature independently and capture the command, output, generated files, and any redacted configuration snippets when reporting bugs.
Scope¶
This runbook covers:
- the
enterprise.activationroot configuration contract; - Enterprise activation readiness checks for hosted control plane onboarding;
- text and JSON output from
datamuru enterprise activation check; - redacted handoff bundle export from
datamuru enterprise activation export; - redacted purchase and license activation request export from
datamuru enterprise activation purchase-request; - offline approval/rejection evidence from
datamuru enterprise activation fulfill; - redacted audit evidence export from
datamuru enterprise activation evidence; - single-directory redacted handoff packages from
datamuru enterprise activation package; - deterministic redacted tenant entitlement records from
datamuru enterprise control-plane tenant-record; - hosted control plane reference architecture export from
datamuru enterprise control-plane architecture; - redacted hosted handoff contracts from
datamuru enterprise control-plane contract; - local and remote backend readiness output from
datamuru state inspect; - license key environment-variable detection without secret disclosure;
- Python API activation report generation;
- documentation and schema coverage for the activation contract.
The OSS CLI does not provision an Enterprise tenant or call a license server. This milestone verifies the local readiness contract that a hosted Enterprise control plane or support workflow can consume later.
Before you start¶
Use a sandbox copy of a DataMuru project. Do not run these checks against a production configuration unless secrets are stored outside YAML and outputs are reviewed before sharing.
python -m pip install -e ".[dev,docs]"
python -m datamuru.cli.main --no-banner validate --config datamuru.yml --strict
python -m datamuru.cli.main --no-banner enterprise activation check --config datamuru.yml
For an open-source project, the final command should fail. That failure is the expected baseline because activation requires Enterprise edition settings.
Capture:
- DataMuru version or commit SHA;
- Python version;
- operating system;
- redacted
datamuru.yml; - exact command and full output;
- whether the command was run from an installed package or editable checkout.
Do not paste license keys, provider tokens, private keys, customer data, or raw state files.
1. Open-source blocking baseline¶
Run against an unchanged OSS project:
python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml
Expected result:
- command exits nonzero;
- output says Enterprise activation is
blocked; - output includes
project.editionguidance; - output includes
features.hosted_control_planeguidance; - output includes
enterprise.activationguidance.
Bug evidence to capture:
- command output;
- redacted
project.editionandfeatures.hosted_control_planevalues.
2. Enterprise activation config shape¶
In a sandbox project, configure Enterprise activation intent:
project:
edition: enterprise
features:
hosted_control_plane: true
identity_management: true
enterprise:
activation:
organization: Acme Data
contact_email: platform@acme.example
control_plane_url: https://control.datamuru.example
tenant_id: acme-prod
deployment_region: us-east-1
license_key_env: DATAMURU_LICENSE_KEY
purchase_reference: PO-12345
support_plan: enterprise
Validate the project:
python -m datamuru.cli.main --no-banner validate --config datamuru.yml --strict
Expected result:
- validation accepts the
enterprise.activationblock; - no schema or Pydantic error reports
enterpriseas an unknown root key; - no license key value is stored in YAML.
Bug evidence to capture:
- validation output;
- redacted
enterprise.activationblock.
3. Missing license environment variable¶
Run with the activation block present, but without the configured license environment variable:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml
Expected result:
- command exits nonzero;
- output says Enterprise activation is
blocked; - output names
enterprise.activation.license_key_env; - output says
DATAMURU_LICENSE_KEYis not set; - output does not ask the user to put the license key in YAML.
Bug evidence to capture:
- command output;
- shell environment variable name only, not the secret value.
4. Successful text preflight¶
Set a non-production test license value in the environment:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml
Expected result:
- command exits successfully;
- output says Enterprise activation is
ready; - output names the project and provider;
- output says the activation payload is ready for onboarding;
- output does not print
test-license-value.
Bug evidence to capture:
- command output;
- confirmation that the literal license value is absent from output.
5. Successful JSON preflight¶
Run the JSON form for automation:
python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml `
--output json
Expected result:
- stdout is valid JSON;
- top-level
readyistrue; payload.schema_versionisdatamuru.enterprise_activation.v1;payload.activation.license_key_envisDATAMURU_LICENSE_KEY;payload.activation.license_key_presentistrue;- the literal license value is absent from stdout;
checksis an empty list.
Optional parser check:
$json = python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml `
--output json | ConvertFrom-Json
$json.ready
$json.payload.activation.license_key_present
$json.checks.Count
Expected parser values:
True;True;0.
6. Invalid contact email¶
Change only contact_email to an invalid value:
enterprise:
activation:
contact_email: platform-contact
Run:
python -m datamuru.cli.main --no-banner enterprise activation check `
--config datamuru.yml
Expected result:
- command exits nonzero;
- output names
enterprise.activation.contact_email; - output explains that the value must be an email address.
Restore a valid email before continuing.
7. Activation handoff bundle export¶
Run the export command with a ready activation config:
python -m datamuru.cli.main --no-banner enterprise activation export `
--config datamuru.yml `
--out .\.datamuru\activation\enterprise-activation.json `
--output json
Expected result:
- command exits successfully;
.datamuru/activation/enterprise-activation.jsonexists;- JSON command output includes
ready: true; - bundle
schema_versionisdatamuru.enterprise_activation_bundle.v1; - bundle
statusisready; - bundle embeds the redacted activation report;
- the literal license value is absent from the bundle.
Blocked export check:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise activation export `
--config datamuru.yml `
--out .\.datamuru\activation\blocked.json
Expected result:
- command exits nonzero;
blocked.jsonis not written;- output explains which checks failed.
Use this diagnostic path only when support requests a blocked bundle:
python -m datamuru.cli.main --no-banner enterprise activation export `
--config datamuru.yml `
--out .\.datamuru\activation\blocked.json `
--allow-blocked
Expected result:
- command exits successfully;
- bundle
statusisblocked; - failed checks are present;
- no secret value is present.
8. Purchase and license activation request¶
Run the purchase-request command with a ready activation config:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise activation purchase-request `
--config datamuru.yml `
--out .\.datamuru\activation\purchase-request.json `
--output json
Expected result:
- command exits successfully;
.datamuru/activation/purchase-request.jsonexists;- JSON command output includes
ready: true; - request
schema_versionisdatamuru.enterprise_purchase_request.v1; - request
statusisready; - request includes
commercial.purchase_referenceandcommercial.support_plan; - request includes requested entitlements such as
hosted_control_plane; - request
fulfillment.offlineistrue; - request
fulfillment.provisions_tenantisfalse; - request
fulfillment.calls_license_serverisfalse; - request
license.secret_values_includedisfalse; - the literal license value is absent from stdout and the file.
Blocked request check:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise activation purchase-request `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-purchase-request.json
Expected result:
- command exits nonzero;
blocked-purchase-request.jsonis not written;- output explains which activation checks failed.
Use this diagnostic path only when support requests a blocked purchase request:
python -m datamuru.cli.main --no-banner enterprise activation purchase-request `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-purchase-request.json `
--allow-blocked `
--output json
Expected result:
- command exits successfully;
- request
statusisblocked; - failed activation checks are present;
- license metadata still says no secret values are included.
8A. Offline fulfillment decision¶
Use the ready purchase request from section 8. Fulfillment is a post-decision workflow, so write it outside the pre-fulfillment handoff package.
Approve the request:
$fulfillmentOut = ".\.datamuru\activation\fulfillment-approved"
python -m datamuru.cli.main --no-banner enterprise activation fulfill `
--request .\.datamuru\activation\purchase-request.json `
--decision approve `
--operator licensing@datamuru.com `
--decision-reference CRM-1234 `
--out $fulfillmentOut `
--output json
Expected result:
- command exits successfully;
fulfillment-decision.jsonusesdatamuru.enterprise_fulfillment_decision.v1;activation-receipt.jsonusesdatamuru.enterprise_activation_receipt.v1;- both files share the purchase-request fingerprint and decision identity;
- security fields say
offline: trueand every payment, signing, license-server, and provisioning flag isfalse; - neither file contains a license value, provider token, or raw request body.
Reject the same request into a different directory:
$rejectionOut = ".\.datamuru\activation\fulfillment-rejected"
python -m datamuru.cli.main --no-banner enterprise activation fulfill `
--request .\.datamuru\activation\purchase-request.json `
--decision reject `
--operator licensing@datamuru.com `
--decision-reference CRM-1235 `
--notes "Commercial review did not approve fulfillment." `
--out $rejectionOut `
--output json
Expected result:
- only
fulfillment-decision.jsonis written; - the decision is
reject; - requested entitlements appear under
rejectedand none appear underapproved; - no activation receipt exists.
Verify stable identities across separate runs:
$secondOut = ".\.datamuru\activation\fulfillment-approved-second"
python -m datamuru.cli.main --no-banner enterprise activation fulfill `
--request .\.datamuru\activation\purchase-request.json `
--decision approve `
--operator licensing@datamuru.com `
--decision-reference CRM-1234 `
--notes "Second evidence generation." `
--out $secondOut `
--output json | Out-Null
$firstDecision = Get-Content "$fulfillmentOut\fulfillment-decision.json" | ConvertFrom-Json
$secondDecision = Get-Content "$secondOut\fulfillment-decision.json" | ConvertFrom-Json
$firstReceipt = Get-Content "$fulfillmentOut\activation-receipt.json" | ConvertFrom-Json
$secondReceipt = Get-Content "$secondOut\activation-receipt.json" | ConvertFrom-Json
$firstDecision.decision_id -eq $secondDecision.decision_id
$firstDecision.decision_fingerprint -ne $secondDecision.decision_fingerprint
$firstReceipt.receipt_id -eq $secondReceipt.receipt_id
$firstReceipt.decision_fingerprint -ne $secondReceipt.decision_fingerprint
All four comparisons must return True. The stable IDs prove the same request,
decision, operator, and decision reference were used. The changed note and
generation time produce a different decision fingerprint because the
fingerprint binds the full decision record. The receipt carries that updated
decision fingerprint while retaining its stable receipt identity.
Run a tamper test without displaying the planted value:
$tampered = Get-Content .\.datamuru\activation\purchase-request.json | ConvertFrom-Json
$tampered.report | Add-Member -NotePropertyName Authorization -NotePropertyValue "test-secret-sentinel"
$tampered | ConvertTo-Json -Depth 30 | Set-Content .\.datamuru\activation\tampered-request.json
$tamperOutput = python -m datamuru.cli.main --no-banner enterprise activation fulfill `
--request .\.datamuru\activation\tampered-request.json `
--decision approve `
--operator licensing@datamuru.com `
--decision-reference CRM-TAMPER `
--out .\.datamuru\activation\tampered-output 2>&1
$LASTEXITCODE
Test-Path .\.datamuru\activation\tampered-output
$tamperOutput -match "test-secret-sentinel"
Expected values are nonzero, False, and False. The error names a
credential-bearing field without echoing its value.
Verify conflict protection by modifying a copy of an existing decision, then targeting that directory again. The command must exit nonzero and must not change either existing artifact.
Finally, scan every generated fulfillment file for test secrets:
$secretPatterns = "test-license-value|test-secret-sentinel|DATABRICKS_TOKEN|SNOWFLAKE_TOKEN"
$matches = Get-ChildItem .\.datamuru\activation\fulfillment-* -Recurse -File |
Select-String -Pattern $secretPatterns
$matches.Count
Expected value: 0.
The activation receipt is not a signed license, proof of payment, or proof of tenant provisioning. Cryptographic signing and hosted provisioning remain future private control-plane responsibilities.
Bug evidence to capture:
- approve/reject command and redacted output;
- both decision records and the approval receipt;
- stable identity comparison results;
- tamper and conflict exit codes;
- recursive secret-scan count.
9. Activation audit evidence export¶
Run the evidence export command with a ready activation config:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise activation evidence `
--config datamuru.yml `
--out .\.datamuru\activation\activation-evidence.json `
--output json
Expected result:
- command exits successfully;
.datamuru/activation/activation-evidence.jsonexists;- JSON command output includes
ready: true; - evidence
schema_versionisdatamuru.enterprise_activation_evidence.v1; - evidence
statusisready; - evidence embeds the redacted activation readiness report;
- evidence embeds the hosted control plane contract;
- evidence
audit.offlineistrue; - evidence
audit.mutates_providerisfalse; - evidence
audit.mutates_stateisfalse; - evidence
audit.secret_values_includedisfalse; - the literal license value is absent from stdout and the file.
Blocked evidence check:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise activation evidence `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-evidence.json
Expected result:
- command exits nonzero;
blocked-evidence.jsonis not written;- output explains which checks failed.
Use this diagnostic path only when support requests blocked audit evidence:
python -m datamuru.cli.main --no-banner enterprise activation evidence `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-evidence.json `
--allow-blocked `
--output json
Expected result:
- command exits successfully;
- evidence
statusisblocked; - failed activation checks are present;
- audit metadata still says no provider mutation, no state mutation, and no secret values included.
10. Python API activation report¶
Run this from a sandbox DataMuru project root or an environment where DataMuru is installed:
python -c "import os, json; from datamuru.api import DataMuru; os.environ['DATAMURU_LICENSE_KEY']='test-license-value'; report=DataMuru('datamuru.yml').enterprise_activation_report(); print(json.dumps(report.to_dict(), indent=2))"
Expected result:
- JSON output matches the CLI payload structure;
readyistrue;checksis empty;- the literal license value is absent from output.
Bug evidence to capture:
- command output;
- whether the API behavior differs from CLI behavior.
Also verify the purchase request API:
python -c "import os, json; from datamuru.api import DataMuru; os.environ['DATAMURU_LICENSE_KEY']='test-license-value'; request=DataMuru('datamuru.yml').enterprise_activation_purchase_request(); print(json.dumps(request.to_dict(), indent=2))"
Expected result:
schema_versionisdatamuru.enterprise_purchase_request.v1;statusisready;- the literal license value is absent from output.
11. Hosted control plane reference architecture¶
Run the architecture export command:
python -m datamuru.cli.main --no-banner enterprise control-plane architecture `
--config datamuru.yml `
--out .\.datamuru\control-plane\architecture.json `
--output json
Expected result:
- command exits successfully;
- stdout is valid JSON;
.datamuru/control-plane/architecture.jsonexists;schema_versionisdatamuru.hosted_control_plane_architecture.v1;statusisreference-architecture;componentsincludesoss_cli_and_python_api,hosted_control_plane_api,job_runner,state_extension, andaudit_evidence_store;decisionsincludesHCP-001,HCP-002,HCP-003, andHCP-004;implementation_backlogincludesHCP-B3for the remote state extension;non_goalsstate that secret values must not be stored in project YAML.
Optional parser check:
$json = python -m datamuru.cli.main --no-banner enterprise control-plane architecture `
--config datamuru.yml `
--output json | ConvertFrom-Json
$json.schema_version
$json.status
$json.components.Count
$json.implementation_backlog.Count
Expected parser values:
datamuru.hosted_control_plane_architecture.v1;reference-architecture;- at least
5; - at least
5.
Bug evidence to capture:
- command output;
- generated architecture file;
- whether any generated architecture field conflicts with the current hosted control plane product direction.
12. Hosted control plane handoff contract¶
Run the contract command with a ready Enterprise activation config:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise control-plane contract `
--config datamuru.yml `
--out .\.datamuru\activation\control-plane-contract.json `
--output json
Expected result:
- command exits successfully;
- stdout is valid JSON;
.datamuru/activation/control-plane-contract.jsonexists;schema_versionisdatamuru.hosted_control_plane_contract.v1;- top-level
readyistrue; activation.readyistrue;integration.tenant_idmatchesenterprise.activation.tenant_id;integration.license_key_envisDATAMURU_LICENSE_KEY;integration.license_key_presentistrue;state.backendmatches the configured state backend;- the literal
test-license-valueis absent from stdout and the file.
Optional parser check:
$json = python -m datamuru.cli.main --no-banner enterprise control-plane contract `
--config datamuru.yml `
--output json | ConvertFrom-Json
$json.schema_version
$json.ready
$json.integration.tenant_id
$json.integration.license_key_present
$json.state.backend
Expected parser values:
datamuru.hosted_control_plane_contract.v1;True;- the configured tenant id;
True;- the configured state backend.
Review warning checks:
control_plane.state.local_single_useris expected for local state;control_plane.state.remote_extension_requiredis expected for recognized remote state contracts such ass3;- warnings do not block a handoff contract when activation has passed.
Bug evidence to capture:
- command output;
- generated contract file with secrets redacted;
- redacted
enterprise.activationandstateblocks; - confirmation that no tenant provisioning, license-server call, or cloud state access occurred.
13. Activation handoff package¶
Run the package command with a ready Enterprise activation config:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise activation package `
--config datamuru.yml `
--out .\.datamuru\activation\handoff-package `
--output json
Expected result:
- command exits successfully;
- stdout is valid JSON;
.datamuru/activation/handoff-package/manifest.jsonexists;- package
readyistrue; - manifest
schema_versionisdatamuru.enterprise_activation_handoff_package.v1; - package contains
enterprise-activation.json; - package contains
purchase-request.json; - package contains
activation-evidence.json; - package contains
control-plane-contract.json; - package contains
control-plane-architecture.json; - package contains
tenant-entitlement-record.json; - manifest lists six artifacts and their schema versions;
- manifest
redaction.secret_values_includedisfalse; - the literal
test-license-valueis absent from stdout and every generated file.
Optional parser check:
$json = python -m datamuru.cli.main --no-banner enterprise activation package `
--config datamuru.yml `
--out .\.datamuru\activation\handoff-package `
--output json | ConvertFrom-Json
$manifest = Get-Content .\.datamuru\activation\handoff-package\manifest.json | ConvertFrom-Json
$json.ready
$manifest.schema_version
$manifest.artifacts.Count
$manifest.redaction.secret_values_included
Expected parser values:
True;datamuru.enterprise_activation_handoff_package.v1;6;False.
Blocked package check:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise activation package `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-package
Expected result:
- command exits nonzero;
blocked-packageis not written;- output explains the package was not written because activation is blocked.
Use this diagnostic path only when support requests a blocked package:
python -m datamuru.cli.main --no-banner enterprise activation package `
--config datamuru.yml `
--out .\.datamuru\activation\blocked-package `
--allow-blocked `
--output json
Expected result:
- command exits successfully;
- manifest
statusisblocked; - failed activation checks are present in the package artifacts;
- redaction metadata still says no secret values are included.
Bug evidence to capture:
- command output;
- generated manifest;
- list of files in the package directory;
- confirmation that no tenant provisioning, license-server call, provider mutation, state mutation, or secret disclosure occurred.
14. Tenant entitlement record¶
Set a clearly fake license value and export a ready record:
$env:DATAMURU_LICENSE_KEY="test-license-value"
python -m datamuru.cli.main --no-banner enterprise control-plane tenant-record `
--config datamuru.yml `
--out .\.datamuru\activation\tenant-entitlement-record.json `
--output json
Expected result:
- command exits successfully;
- stdout is valid JSON and matches the written file;
schema_versionisdatamuru.tenant_entitlement_record.v1;statusisreadyandreadyistrue;record_idstarts withter_and has 24 characters;- tenant and entitlement fields match the activation config;
security.offlineistrue;- every mutation and provisioning security flag is
false; security.secret_values_includedisfalse.
Inspect the contract:
$record = Get-Content .\.datamuru\activation\tenant-entitlement-record.json | ConvertFrom-Json
$record.schema_version
$record.record_id
$record.tenant.tenant_id
$record.entitlement.enabled_features
$record.entitlement.license_key_env
$record.entitlement.license_key_present
$record.security
Expected parser values include the configured tenant, enabled Enterprise
features, DATAMURU_LICENSE_KEY, True for license availability, and the
offline non-mutation security contract.
Verify deterministic identity across generation times:
Start-Sleep -Seconds 1
python -m datamuru.cli.main --no-banner enterprise control-plane tenant-record `
--config datamuru.yml `
--out .\.datamuru\activation\tenant-entitlement-record-rerun.json `
--output json | Out-Null
$first = Get-Content .\.datamuru\activation\tenant-entitlement-record.json | ConvertFrom-Json
$second = Get-Content .\.datamuru\activation\tenant-entitlement-record-rerun.json | ConvertFrom-Json
$first.generated_at -ne $second.generated_at
$first.record_id -eq $second.record_id
Expected results are True and True.
Verify that license availability does not change tenant identity:
Remove-Item Env:DATAMURU_LICENSE_KEY -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise control-plane tenant-record `
--config datamuru.yml `
--out .\.datamuru\activation\tenant-entitlement-record-no-license.json `
--allow-blocked `
--output json | Out-Null
$withoutLicense = Get-Content .\.datamuru\activation\tenant-entitlement-record-no-license.json | ConvertFrom-Json
$withoutLicense.status
$withoutLicense.entitlement.license_key_present
$first.record_id -eq $withoutLicense.record_id
Expected values are blocked, False, and True. The diagnostic record has
an activation check for the missing environment variable.
Verify redaction and local-path exclusion:
$serialized = Get-Content .\.datamuru\activation\tenant-entitlement-record.json -Raw
$serialized.Contains("test-license-value")
$serialized.Contains((Resolve-Path .).Path)
Both values must be False.
Verify the default blocked guard writes nothing:
$blockedPath = ".\.datamuru\activation\tenant-entitlement-record-blocked.json"
Remove-Item $blockedPath -ErrorAction SilentlyContinue
python -m datamuru.cli.main --no-banner enterprise control-plane tenant-record `
--config datamuru.yml `
--out $blockedPath
Test-Path $blockedPath
Expected result:
- command exits nonzero;
- output says the record was not written because activation is blocked;
Test-PathreturnsFalse.
Confirm activation package integration:
$manifest = Get-Content .\.datamuru\activation\handoff-package\manifest.json | ConvertFrom-Json
$manifest.artifacts.Count
$manifest.artifacts.name -contains "tenant_entitlement_record"
Test-Path .\.datamuru\activation\handoff-package\tenant-entitlement-record.json
Expected values are 6, True, and True.
Bug evidence to capture:
- ready and blocked command output;
- both redacted record files;
- the two record IDs and generation timestamps;
- the package manifest artifact entry;
- results of both redaction checks;
- confirmation that no network call, tenant provisioning, provider mutation, or state mutation occurred.
15. State backend readiness inspection¶
Run the local backend inspection from a sandbox project:
python -m datamuru.cli.main --no-banner state inspect `
--config datamuru.yml `
--output json
Expected result:
- stdout is valid JSON;
- command exits successfully;
backendislocal;remoteisfalse;runtime_supportedistrue;modeisread-write;successistrue;- checks include
state.local.supported.
Optional parser check:
$json = python -m datamuru.cli.main --no-banner state inspect `
--config datamuru.yml `
--output json | ConvertFrom-Json
$json.backend
$json.runtime_supported
$json.mode
$json.success
Expected parser values:
local;True;read-write;True.
In the sandbox copy, change only the state backend to a remote contract:
state:
backend: s3
path: s3://acme-datamuru-state/prod/datamuru-state.json
Run:
python -m datamuru.cli.main --no-banner state inspect `
--config datamuru.yml `
--output json
Expected result:
- command exits nonzero;
- stdout is still valid JSON;
backendiss3;remoteistrue;runtime_supportedisfalse;modeiscontract-only;successisfalse;- checks include
state.s3.not_implemented; - the command does not require AWS credentials and does not perform a cloud network call.
Restore state.backend: local before running plan, apply, adoption, or
destructive tests in the OSS runtime.
Bug evidence to capture:
- local and remote command output;
- redacted
stateblock; - whether any provider credential prompt or cloud access occurred.
16. Databricks to Snowflake and Snowflake to Databricks mapping drafts¶
Use separate live-readonly DataMuru projects for each source provider. Keep
all credentials in the current shell or an approved secret store.
From the Databricks source project, generate the existing forward draft:
python -m datamuru.cli.main --no-banner import map-snowflake `
--config datamuru.yml `
--catalog <catalog_name> `
--target-account snowflake-target `
--target-workspace snowflake-live-readonly `
--out .\.datamuru\mappings\databricks-to-snowflake.yml
Expected result:
- source provider is
databricks; - target provider is
snowflake; - review status is
draft; - the command performs no Snowflake mutation or data movement.
From the Snowflake source project, generate the reverse draft:
python -m datamuru.cli.main --no-banner import map-databricks `
--config datamuru.yml `
--database <database_name> `
--target-workspace databricks-live-readonly `
--target-cloud azure `
--catalog-prefix sf `
--identifier-case lower `
--out .\.datamuru\mappings\snowflake-to-databricks.yml
Expected result:
- source provider is
snowflake; - target provider is
databricks; - database maps to a catalog and schemas map to schemas;
- review status is
draft; - the command performs no Databricks mutation or data movement.
Collision test:
- Use a fixture or sandbox inventory containing names that normalize to the
same target, such as
FINANCE-RAWandFINANCE_RAW. - Run
map-databrickswith--identifier-case lower. - Confirm the command returns a validation error and does not write the output file.
For shared test evidence, record only provider direction, success state, review status, and aggregate mapping counts. Do not record tokens, hosts, usernames, workspace names, database names, catalog names, or mapping YAML.
17. Documentation and schema coverage¶
Confirm the milestone docs are discoverable:
python -m pytest tests\unit\test_documentation.py -q
$env:NO_MKDOCS_2_WARNING = "1"
python -m mkdocs build --strict
Expected result:
- MkDocs nav includes this runbook;
- links in activation docs resolve;
- docs build strictly;
- the Material for MkDocs upstream warning, if present, is not a DataMuru docs failure.
Review these pages manually:
docs/guides/enterprise-activation.md;docs/reference/cli.md;docs/reference/python-api.md;docs/reference/capabilities.md;docs/reference/root-config.md;docs/operations/milestone-0-5-test-runbook.md.
18. Local quality gate¶
Run this before reporting the milestone as tested:
python -m ruff check datamuru tests
python -m pytest -q --basetemp .datamuru\pytest-tmp -p no:cacheprovider
$env:NO_MKDOCS_2_WARNING = "1"
python -m mkdocs build --strict
Expected result:
- lint passes;
- unit and e2e tests pass;
- documentation builds strictly.
If pytest cannot create temp files under the default Windows temp directory,
use the --basetemp .datamuru\pytest-tmp -p no:cacheprovider form shown
above.
Bug report template¶
When a test fails, capture:
- feature under test;
- exact command;
- full output;
- expected result from this runbook;
- actual result;
- redacted
datamuru.ymlsnippet; - whether
DATAMURU_LICENSE_KEYwas set; - whether the literal secret appeared in output;
- whether any evidence file was written when the command was expected to block;
- whether the failure is reproducible on a second run.
Do not include provider tokens, license keys, private keys, customer data, or raw state files.