NARSSA Transfer Plugin — User Guide
Plugin: ahgNARSSAPlugin v0.1.0
Platform: AtoM Heratio (AtoM 2.10 + AHG Framework v2.8.2)
Author: The Archive and Heritage Group (Pty) Ltd
Last updated: May 2026
What this guide covers
How a records officer uses the AtoM Heratio NARSSA Transfer plugin to:
- Identify which records are due for transfer
- Produce a standards-compliant transfer package
- Hand the package to the National Archives
- Record the NARSSA receipt and close out the transfer
1. Prerequisites
Before you run any transfer:
- The records must have a retention assignment (an entry in
retention_assignmentlinking the record to its File-Plan schedule) - The schedule's
disposal_actionmust betransfer_narssa - The disposal workflow must have completed: records officer + legal counsel + executive sign-off (per the schedule's required-signoff flags), and the disposal_action status must be
approved - You must have shell access to the AtoM Heratio server (the transfer is a CLI command)
2. Surfacing what's due
Open Admin → Reports → New report → Records Management Compliance: Retention Status & Lifecycle.
The "Approved transfers awaiting NARSSA package" table lists every record that:
- Has an
approveddisposal_action - With
action_type = transfer_narssa - Whose
transfer_manifest_pathis still NULL (no package yet)
You can also run the SQL directly:
SELECT da.id, da.information_object_id, da.proposed_at, da.executive_signed_at
FROM disposal_action da
WHERE da.action_type = 'transfer_narssa'
AND da.status = 'approved'
AND da.transfer_manifest_path IS NULL
ORDER BY da.proposed_at;
3. Building the package
Option A — Package every approved transfer
cd /usr/share/nginx/archive
php symfony narssa:transfer-package
This is the production-typical path. The plugin:
- Finds every
disposal_actionrow matching the criteria above - Allocates a transfer reference (
NARSSA-2026-001, incrementing) - Generates one tar.gz containing all of them
- Stamps every disposal_action with the resulting
transfer_manifest_path - Writes one row to
narssa_transfer(statuspackaged) - Writes one row to
narssa_transfer_itemper record
Option B — Package an explicit list
php symfony narssa:transfer-package \
--io-ids=553,635,886 \
--user-id=1 \
--title="Q1 2027 Cabinet briefings transfer"
Useful for ad-hoc requests, back-fills, or when packaging records that don't have a disposal workflow yet (e.g. legacy hand-arranged transfers).
What you get
The CLI prints:
>> narssa Packaged transfer #N (NARSSA-2026-NNN): N items, NNN bytes, package=/usr/share/nginx/archive/uploads/narssa/NARSSA-2026-NNN.tar.gz
SHA-256: <full hash>
Inspect the package:
tar -tzf /usr/share/nginx/archive/uploads/narssa/NARSSA-2026-001.tar.gz
You should see:
NARSSA-2026-001/
NARSSA-2026-001/manifest.csv
NARSSA-2026-001/transfer.xml
NARSSA-2026-001/items/
NARSSA-2026-001/items/<archival_ref>/
NARSSA-2026-001/items/<archival_ref>/description.xml
NARSSA-2026-001/items/<archival_ref>/digital_objects/
NARSSA-2026-001/items/<archival_ref>/checksums.sha256
4. Transmitting to NARSSA
The plugin does not transmit the package — that's an operator step because NARSSA's submission channel (SFTP credentials, portal logins) varies and lives outside the application.
Once you've uploaded the tar.gz to NARSSA, update the transfer record:
UPDATE narssa_transfer
SET status = 'transmitted', transmitted_at = NOW()
WHERE id = N;
Or use the admin UI (Admin → NARSSA Transfers → Edit).
5. Recording the acceptance
When NARSSA acknowledges receipt and issues a reference number:
UPDATE narssa_transfer
SET status = 'accepted',
accepted_at = NOW(),
narssa_receipt_reference = 'NARS-2027-XXXXX'
WHERE id = N;
After acceptance the source records can be securely destroyed (the disposal_action.action_type was transfer_narssa, but the record itself remains locally until you explicitly run the final destruction step).
6. Auditing
Every action is logged. To see the full audit chain for a transfer:
SELECT action, user_id, created_at,
JSON_UNQUOTE(JSON_EXTRACT(new_values, '$.reference')) AS reference,
JSON_UNQUOTE(JSON_EXTRACT(new_values, '$.package_sha')) AS sha
FROM ahg_audit_log
WHERE entity_type = 'narssa_transfer'
ORDER BY created_at;
The action codes:
narssa_transfer_packaged— package generatednarssa_transfer_transmitted— package sent to NARSSAnarssa_transfer_accepted— NARSSA confirmed receiptnarssa_transfer_rejected— NARSSA rejected (rare — usually triggers a re-package)
7. Troubleshooting
"No approved transfer_narssa disposals to package."
Verify the disposal workflow has actually reached approved status. Check:
SELECT id, status, action_type, transfer_manifest_path
FROM disposal_action
WHERE action_type = 'transfer_narssa'
ORDER BY id DESC LIMIT 10;
If the record is stuck at officer_signed or legal_signed, the next required signoff hasn't been captured yet.
Package has 0 bytes / 0 digital objects
The information_object has no attached digital_object rows. The descriptive metadata still ships in description.xml; only the binary files are missing. NARSSA still accepts text-only descriptive transfers — this is correct behaviour for purely-descriptive records.
Package SHA-256 doesn't match what NARSSA computed
Most common cause: the tar.gz was unpacked and re-packed locally (changes the byte ordering of the tar headers). Always transmit the original .tar.gz file directly.
Part of the AtoM AHG Framework v2.8.2+