Problem

After an operator has investigated an audit-history discontinuity, normal logging needs a clearly identified continuation without rewriting retained records or declaring the original history valid. A prefix seal is not a substitute for documenting an unresolved continuity exception.

Proposed resolution

Add an explicit, privileged successor-segment workflow backed by a signed recovery record. Preserve existing rows, hashes and seals. Keep default whole-history verification unchanged.

  • Bind the recovery record to the reviewed historical snapshot, its verification result, source identity, incident reference, operator approval and new segment boundary.
  • Serialize creation with normal appends; reject stale snapshots and unavailable signing keys. Make retries idempotent and preserve rollback behavior.
  • Verify the retained historical anchor and recovery signature when checking a successor.
  • Show successor health and historical exceptions separately in monitoring and exports. Never present partial success as a healthy complete history.
  • Protect retained evidence from automatic pruning while no verifiable archival boundary exists.

Validation

Use synthetic histories to test forks, changed or missing historical records, stale approval, key rotation and loss, cross-environment copies, concurrent appends, rollback and retries. Test supported Drupal versions and database drivers. Add operator and consumer upgrade documentation.

This feature does not reconstruct lost chronology or retroactively authenticate unsigned history.

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Version: 1.x-dev » 1.8.0
Status: Active » Fixed

Implemented and released in Audit Chain 1.8.0.

Successor activation requires an exact reviewed snapshot, runtime instance identity, available signing key and explicit operator context. Historical rows, seals and the failed whole-history verdict remain unchanged. Verification, dashboard status and recovery export distinguish the successor from the historical exception.

Destructive per-channel pruning is refused until archival can preserve verification. The supported Drupal matrix and PostgreSQL/MySQL tests cover concurrency, rollback, stale approval, altered evidence, key rotation and cross-instance refusal. Run database updates and read the recovery procedure before activation. An upgrade does not activate recovery.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

jmcerda’s picture

Status: Fixed » Active

Follow-up found in 1.8.0: `drush audit-chain:recovery-activate --help` and activation fail with `An option named "yes" already exists.` RecoveryCommands declares --yes even though Drush already defines it globally. Preparation and the recovery service API are unaffected; this refusal occurs before successor activation. Proposed fix: remove the duplicate option and route confirmation through DrushStyle::confirm(), which already honours global --yes and --no. Adding an actual installed-site CLI regression for discovery, refusal, activation, retry, verification and export. No site-specific data is needed to reproduce this.

  • jmcerda committed f35f07dc on 1.x
    fix: #3623864 use global Drush recovery confirmation
    

  • jmcerda committed 2164f5ae on 1.x
    fix: #3623864 apply global confirmation to prefix sealing
    
jmcerda’s picture

Status: Active » Fixed

The CLI follow-up is fixed in Audit Chain 1.8.2: https://www.drupal.org/project/audit_chain/releases/1.8.2 . Recovery activation and the older prefix-sealing command now use Drush’s global confirmation options. The installed-site CLI tests cover help/discovery, explicit refusal without persisted recovery or seal state, confirmed activation with parseable JSON, identical retry, verification, export and refusal to reseal frozen successor history. All supported Drupal matrix legs and the PostgreSQL/MySQL suites passed. Signing, storage, prefix eligibility and the historical failed-verdict contract are unchanged. The earlier 1.8.1 tag remains immutable; use 1.8.2 for both command fixes.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.