Document signing
/hcm/documents (admin tab) is the DocuSign-replacement signing
surface. The pattern: HR drafts a template with field placement
(page + x + y fractional coords for resolution independence);
template activation is 4-eyes (drafter ≠ activator); on
activation the template's body + fields are SHA-256 locked.
Documents sent under a template route through a sequential
multi-counterparty chain; signer resolution supports SUBJECT,
MANAGER_OF_SUBJECT, EXPLICIT, ROLE. Every step in the lifecycle —
delivered, opened, signed, declined, reassigned — emits an audit
ledger row with IP + UA.
TL;DR — Open HCM → Documents → Templates. Draft a template; place fields. A different admin activates (4-eyes, SHA-256 lock). Send a document under the template; the platform routes counterparties in order. Each ledger event is audited.
Before you start
- Have the base document as a PDF (or a rich-text rendered to PDF on save).
- Know your signer roles — who signs first, who second, etc. Some templates use SUBJECT + MANAGER_OF_SUBJECT; others use EXPLICIT specific people; others use ROLE (e.g. "any HR partner").
- Decide whether decline terminates the chain or routes back for redraft.
Drafting a template
Click "+ New template"
Opens the template editor.
Upload the base PDF
The PDF renders in the canvas.
Place fields
Drag field types (signature, initial, date, checkbox, text) onto pages. Each field has page + fractional x + y coords (0..1) for resolution-independent placement.
Assign fields to signers
Each field belongs to one signer in the chain. Required vs optional per field.
Configure the signing chain
Add signer roles in order. SUBJECT / MANAGER_OF_SUBJECT / EXPLICIT / ROLE. Per-step deadline (in business days).
Save draft
Audit log records
HCM_DOC_TEMPLATE_DRAFTED.
Activate (4-eyes + SHA-256 lock)
A different admin opens the draft
Drafter can't activate. The activate button is hidden for drafter.
Review
Activator reads through the template + field placement.
Click "Activate"
The template's body + field placement is hashed (SHA-256). The hash is recorded on the activation event; future signers receive the hashed version.
Activated
Audit log records
HCM_DOC_TEMPLATE_ACTIVATED. The template is now LEGALLY BINDING for new signers. Existing in-flight chains continue on their own (immutable) version.
SHA-256 lock + ESIGN / UETA
The hash locks the template's content at activation. Every signer receives a document with the exact bytes the activator approved; tampering would change the hash + invalidate signatures. The audit trail meets ESIGN / UETA defensibility requirements.
Signer resolution
| Field | What it does | Accepted values / default |
|---|---|---|
| SUBJECT | The employee the document is about. | Resolved per-instance when the document is sent. |
| MANAGER_OF_SUBJECT | The subject's primary (solid-line) manager at send time. | Resolved from the org graph at instance-send time. |
| EXPLICIT | A specific named user. | Set at instance-send time; cannot be the subject themself. |
| ROLE | Any user holding the named role. | First responder claims the step; others are notified that the step is claimed. |
Signing chain mechanics
Send a document under the template
Pick the subject; resolve EXPLICIT signers if applicable. Audit log records
HCM_DOC_SIGNING_ROUND_DELIVERED(signer 1).Signer 1 receives + opens
Email / Slack notification per their preferences. On open:
HCM_DOC_SIGNING_OPENEDrecorded with IP + UA.Signer 1 signs
Signature applied to all signer-1 fields.
HCM_DOC_SIGNING_SIGNEDrecorded. The document routes to signer 2.Repeat for each signer
Same pattern.
All signers complete
Document is fully signed; final PDF generated + delivered to every party.
Decline + reassign
| Field | What it does | Accepted values / default |
|---|---|---|
| Decline | Signer refuses to sign. | Per template policy, chain terminates OR routes back for redraft. Audit log records `HCM_DOC_SIGNING_DECLINED`. |
| Reassign | Signer routes the step to a different person. | ROLE-based signers can claim / reassign; EXPLICIT cannot. Audit log records `HCM_DOC_SIGNING_REASSIGNED`. |
| Deadline elapse | Signer doesn't act within the per-step deadline. | Reminder fires first; on deadline, the document routes per template policy (chase / escalate / cancel). |
Audit ledger
Every event in the lifecycle is captured in an immutable ledger:
| Field | What it does | Accepted values / default |
|---|---|---|
| Delivered | Signer received the request. | Timestamp + signer + IP + UA. |
| Opened | Signer opened the document. | Timestamp + IP + UA. Multiple opens recorded separately. |
| Signed | Signer signed. | Timestamp + IP + UA + signature image hash. |
| Declined | Signer declined. | Timestamp + rationale (required for decline). |
| Reassigned | Signer reassigned the step. | Timestamp + new signer. |
Common template uses
| Field | What it does | Accepted values / default |
|---|---|---|
| Offer letter | New-hire offer with comp + start date. | SUBJECT signs; HR countersigns. |
| NDA | Confidentiality + IP assignment. | SUBJECT signs; HR signs. |
| Equity grant agreement | Grant + vesting acceptance. | SUBJECT signs; per board cosign requirements. |
| Annual policy acknowledgement | Employee handbook + policies confirm. | SUBJECT signs; HR signs to record. |
| Promotion letter | Promotion comp + level confirmation. | SUBJECT + MANAGER_OF_SUBJECT + HR. |
| Separation agreement | Termination + severance + release. | SUBJECT + HR + (sometimes) legal review. |
Every field, explained
| Field | What it does | Accepted values / default |
|---|---|---|
| Field type | What the signer fills. | Signature / initial / date / checkbox / text. |
| Field position | Page + x + y on the PDF. | Fractional coords (0..1) for resolution independence. |
| Field assignee | Which signer is responsible. | Required per field. |
| Signing role | SUBJECT / MANAGER_OF_SUBJECT / EXPLICIT / ROLE. | Resolved at send-time. |
| Step deadline | How long the step has before reminder / chase. | Business days. |
| SHA-256 hash (activation) | Content + field-placement hash. | Locks the template body at activation. |
Audit codes
For ESIGN / UETA defensibility + SIEM ingestion, this surface emits:
See Reference → Audit codes for the canonical description of each.
Common gotchas
- "Drafter tried to activate." 4-eyes SoD; a different admin activates. UI hides the activate button.
- "Field shifted on a different screen." Fractional coords prevent this for the most part; if the source PDF re-renders at a different page size, the proportions still apply.
- "Signer can't find the document in their inbox." Check the signer-role resolution — for ROLE, anyone in the role can claim; for EXPLICIT, the named person must sign. The ledger shows what was delivered to whom.
- "My template is in-flight on the old version after activation." By design — in-flight chains complete on the version they started with. New chains use the new version.
Troubleshooting
| Error code | What it means | Fix |
|---|---|---|
DOC_TEMPLATE_ACTIVATE_4EYES_VIOLATION | Drafter tried to activate. | Different admin activates. |
DOC_FIELD_NO_ASSIGNEE | A field has no signer assignment. | Assign before activation. |
DOC_SIGNING_DECLINE_REQUIRES_RATIONALE | Decline submitted without rationale. | Add a rationale. |
DOC_SIGNING_REASSIGN_NOT_PERMITTED | EXPLICIT signer tried to reassign. | Only ROLE-based signers can reassign. |
DOC_SIGNING_DEADLINE_ELAPSED | Step deadline passed. | Per template policy: extended, chased, or cancelled. |
Related