← Back

EC Terms Gate And Owner Lockout Addendum

01_terms/ec_terms_gate_and_owner_lockout_addendum.md

Employee Center Terms Gate, Company Acceptance Grace Period, and Owner LOCKOUT Addendum — VSCode Implementation Spec

Version: 2.2 — Login-Page Gate / Certificate Email Attachment and DB Output Revision
Date: May 30, 2026
Project: Employee Center / EC
Owner: Quintin N. Mahan
Applies To: Terms acceptance workflow, login workflow, employee setup page, owner profile page, company-authority acceptance, owner lockout, emergency service-disable mode
Database Requirement: Postgres only
Primary Terms Route: /legal/terms-and-conditions
Root Legal Hub: /legal
Policy Library: /legal/policies
Owner Notification From: support@crsabq.com
Owner Notification To: mahanquintin@gmail.com
Mail Transport: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials, same sending path as invoice email delivery


1. Purpose

This addendum modifies the EC Terms acceptance workflow so users sign in first, are authenticated, and are then forced into a Terms acceptance gate before any licensed EC usage is allowed.

The purpose is to ensure EC captures the authenticated user identity, account record, company, role, timestamp, IP address, user agent, active Terms version, active Terms hash, Legal hub hash, Policy Library hash, full Legal bundle hash where practical, acceptance/decline status, and all related evidence directly in the EC Postgres database.

This addendum also defines:


2. Critical Security Rule: Do Not Store Raw Passwords

The workflow must authenticate the user using username/password or the configured EC authentication method.

EC must not log, email, store, hash-for-evidence, display, export, or preserve the raw password entered during sign-in.

The legal evidence record should capture the authenticated account identity after successful credential validation, including:

This captures who signed in without creating a dangerous password-retention problem.


3. Mail Delivery Rules

EC must use two different mail-delivery paths depending on the event type.

Certificate / Acceptance / Decline / Owner-Notification Emails

For acceptance, decline, certificate, company acceptance, owner notification, owner LOCKOUT notification, Michael SSH enforcement notification, certificate-generation, Terms legal/audit event, and similar owner-directed legal/audit notifications, EC should use Google Workspace service credentials controlled by Quintin N. Mahan.

Envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Google Workspace service credentials

No CC or BCC should be used.

Certificate email body must include this line:

Attached Certificate of Acceptance for EC Terms and Conditions for: {{ username }}

Certificate emails must attach the generated PDF certificate.

For ordinary individual user acceptance, attach the generated individual acceptance certificate PDF.

For Kendra or Chuck company-authority acceptance, attach both generated certificates:

Certificate emails must include the stored EC database/audit output for the acceptance event.

At minimum, the DB/audit output block should include, where applicable:

authenticated_user_id: {{ authenticated_user_id }}
authenticated_username: {{ authenticated_username }}
authenticated_email: {{ authenticated_email }}
company_id: {{ company_id }}
company_name: {{ company_name }}
acceptance_type: {{ acceptance_type }}
individual_acceptance_record_id: {{ individual_acceptance_record_id }}
company_acceptance_record_id: {{ company_acceptance_record_id }}
certificate_id: {{ certificate_id }}
company_certificate_id: {{ company_certificate_id }}
terms_version: {{ terms_version }}
terms_hash: {{ terms_hash }}
policy_bundle_hash: {{ policy_bundle_hash }}
addendum_hash: {{ addendum_hash }}
accepted_at: {{ accepted_at }}
ip_address: {{ ip_address }}
user_agent: {{ user_agent }}
checkbox_text: {{ checkbox_text }}
terms_url: {{ terms_url }}
certificate_pdf_hash: {{ certificate_pdf_hash }}
company_certificate_pdf_hash: {{ company_certificate_pdf_hash }}
audit_event_id: {{ audit_event_id }}
delivery_event_id: {{ delivery_event_id }}

Certificate email body, subject, attachments, and transmitted DB output must not state or imply mailbox cleanup, sent-copy cleanup, deletion, purging, removal, or internal message-retention handling.

EC may perform internal sent-message copy cleanup for qmahan@crsabq.com after sending, to the extent technically available through the Google Workspace service credential implementation.

Internal sent-message copy cleanup must not delete EC’s internal legal/audit evidence.

EC must preserve, inside EC owner-controlled records:

Raw secret values must never be included in email bodies, DB output blocks, certificate PDFs, or audit logs.

If Google Workspace service credential delivery fails, EC may queue an owner-only local notification/audit record for direct owner review and must not silently discard the event.

Day-30 / Day-31 Warning Emails

Day-30 and day-31 company-acceptance warning emails must keep the original Zoho layout/transport specified in this addendum.

For those warning emails only, use:

FROM: support@crsabq.com
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials

Do not convert day-30/day-31 warning emails to Google Workspace service credential delivery unless Quintin N. Mahan later signs a separate written instruction.


4. Login-Page Terms Acceptance Gate Flow

EC must use a login-page Terms acceptance gate built from a cloned sign-in page.

The ordinary sign-in page may remain the default login page when a user already has a current valid acceptance for the active Terms version/hash.

When a user has no current acceptance, previously declined, or the active Terms version/hash or incorporated legal/policy bundle hash changed, EC must redirect or route the user to a cloned Terms-acceptance sign-in page.

The cloned Terms-acceptance sign-in page should preserve the ordinary sign-in layout while adding:

The required red warning text must appear immediately above the checkbox until the checkbox is checked:

You must agree to the terms and conditions before signing in.

The required checkbox wording must be:

I agree to the Terms and Conditions.

The words “Terms and Conditions” must be an open link to the active Terms and Conditions page.

The sign-in button must remain disabled until the checkbox is checked.

Once the checkbox is checked, the red warning text should clear, hide, or otherwise stop displaying.

The checkbox is client-side UI gating only. Binding acceptance is server-side and attaches only after successful username/password authentication.

If authentication fails, EC must not record Terms acceptance.

If authentication succeeds and the checkbox was checked, EC records acceptance for the authenticated user and then proceeds into EC.

If the authenticated user is Kendra or Chuck and server-side company authority is enabled, EC may also record company-level acceptance according to this addendum.

No acceptance means no EC access.


5. No Licensed Usage Before Acceptance

A user without current valid acceptance for the active Terms version/hash is not licensed for normal EC usage.

A user without current valid acceptance may only see:

A user without current valid acceptance must not reach:

No acceptance means no EC access.


6. Pre-Acceptance Authentication and Session State

The Terms checkbox may be checked before sign-in, but legal acceptance must not be recorded until after successful server-side authentication.

If a login attempt fails, EC must not record Terms acceptance and must not generate a certificate.

If a login attempt succeeds and the checkbox was checked, EC may record acceptance against the authenticated user account.

The server must use authenticated account identity, server-side user ID, server-side company ID, server-side role, and server-side company-authority status.

The server must not rely on raw email or form-submitted identity to determine company acceptance authority.

A pre-acceptance or cloned-login session must not provide normal EC access until the acceptance requirement is satisfied.


7. Cloned Terms-Acceptance Sign-In Page Requirements

The cloned Terms-acceptance sign-in page must preserve the ordinary sign-in page layout as much as practical while adding the required Terms controls.

Required UI behavior:

  1. show normal username/password fields;
  2. show the required red warning text immediately above the checkbox;
  3. show the checkbox text I agree to the Terms and Conditions.;
  4. make “Terms and Conditions” an open link to the active Terms page;
  5. keep the sign-in button disabled until the checkbox is checked;
  6. clear or hide the red warning text once the checkbox is checked;
  7. include a Decline button;
  8. do not record acceptance until authentication succeeds;
  9. do not provide normal EC access until acceptance succeeds;
  10. redirect back to the normal EC application after successful authentication and acceptance.

Required red warning text:

You must agree to the terms and conditions before signing in.

Required checkbox text:

I agree to the Terms and Conditions.

The ordinary sign-in page may omit the checkbox for users with a current valid active Terms acceptance.

When active Terms/policy hash changes, EC may redirect affected users to the cloned Terms-acceptance sign-in page until they accept.


8. Accept Action

Route example:

POST /login/terms

The route name may follow existing EC routing conventions, but the behavior must match this section.

When a user submits the cloned Terms-acceptance sign-in page with the checkbox checked:

  1. validate the checkbox was checked;
  2. authenticate username/password server-side;
  3. if authentication fails, do not record acceptance;
  4. if authentication succeeds, load authenticated server-side user ID;
  5. load server-side company ID;
  6. load server-side role and company-authority flags;
  7. determine active Terms version and hash;
  8. determine incorporated legal/policy bundle hash;
  9. determine active addendum hash;
  10. record individual acceptance for the authenticated user;
  11. generate an individual acceptance certificate PDF;
  12. compute and store individual certificate PDF hash;
  13. if the authenticated user has company authority as Kendra or Chuck, record company-level acceptance according to this addendum;
  14. if company-level acceptance is recorded, generate a company acceptance certificate PDF for Cash Register Systems, Inc.;
  15. if company-level acceptance is recorded, compute and store company certificate PDF hash;
  16. build the stored DB/audit output block for the email;
  17. email certificate/acceptance notice using Google Workspace service credentials from qmahan@crsabq.com to mahanquintin@gmail.com;
  18. attach the generated certificate PDF or PDFs;
  19. include the required certificate email line;
  20. include the stored DB/audit output block;
  21. perform internal sent-message copy cleanup from qmahan@crsabq.com to the extent technically available, without mentioning cleanup in the email body, subject, attachments, or transmitted DB output;
  22. record audit event;
  23. establish normal authenticated EC session;
  24. redirect to the requested EC destination or default dashboard.

Required certificate email body line:

Attached Certificate of Acceptance for EC Terms and Conditions for: {{ username }}

For ordinary individual user acceptance, attach one PDF: the individual acceptance certificate.

For Kendra or Chuck company-authority acceptance, attach two PDFs:

Do not record acceptance based only on a checked box.

Do not record acceptance for a failed login.

Do not record company acceptance based on form-submitted email alone.


9. Decline Action

Route example:

POST /login/terms/decline

The Decline button must update Terms status without granting normal EC access.

When a user clicks Decline, EC should:

  1. identify the account if possible;
  2. record decline/refusal/non-acceptance status;
  3. record active Terms version/hash;
  4. record incorporated legal/policy bundle hash;
  5. record timestamp, IP address, and user agent where available;
  6. set account Terms status to declined or equivalent where the account is identifiable;
  7. set access state to no-access pending acceptance;
  8. email decline/owner notice using Google Workspace service credentials from qmahan@crsabq.com to mahanquintin@gmail.com;
  9. perform internal sent-message copy cleanup from qmahan@crsabq.com to the extent technically available, without mentioning cleanup in the email body, subject, attachments, or transmitted DB output;
  10. prevent normal EC access;
  11. return the user to the login/terms page or declined access message.

Decline does not create a license to use EC.

Decline does not transfer EC Protected Materials.

Decline does not create company ownership.

Decline does not create source-code rights.

Decline does not create credential rights.

Decline means no access until later acceptance or separate written owner authorization.


10. Declined Access State

Users with a declined status must not access normal EC functions until they later accept the active Terms or Quintin N. Mahan separately authorizes access in writing.

Declined users may be shown a minimal message such as:

Access is not authorized unless you accept the current Employee Center Terms and Conditions.

Declined users may be allowed to return to the cloned Terms-acceptance sign-in page to accept the active Terms.

Declined status must be visible in owner/admin audit views and employee setup status displays where applicable.


11. Account Terms Status

Each account should maintain Terms status fields sufficient to support the login-page acceptance flow.

Recommended statuses:

pending
accepted
declined
stale_due_to_terms_hash_change
company_acceptance_required
blocked

Recommended fields:

These fields must be server-controlled.


12. Employee Setup Page Status Display

On the employee setup page, show a non-editable Terms status flag.

Label:

Terms Status

Allowed visible values:

Pending
Accepted
Declined

Display metadata where owner/admin is permitted:

This flag must be non-editable from the employee setup UI.

No admin, manager, superuser, or employee may manually flip this status through the normal employee setup page.

Changes must occur only through:


13. Terms Renewal Logic

When any of the following changes, EC may require renewed acceptance:

Renewed acceptance should be enforced through the cloned Terms-acceptance sign-in page.

A user with a stale acceptance may authenticate only through the Terms-acceptance flow and must not access normal EC operational pages until renewed acceptance is recorded.

The ordinary sign-in page may be used only when the user’s acceptance is current.

If a user declines after a hash change, the user remains no-access until later acceptance.


14. Company-Authority Acceptance Rule — One of Two Is Enough

For CRS company acceptance, the license is considered company-accepted if at least one of the two configured company-authority users accepts the current active Terms:

Kendra
Chuck

Both may accept, and EC should preserve separate company-authority records and certificates for both if both accept.

However, one valid current company-authority acceptance is enough to satisfy company acceptance for continued employee access.

The accepted company-authority record must include:

For Kendra or Chuck company-authority acceptance, EC must generate two certificate records and two generated certificate PDFs:

The owner-directed certificate email for Kendra or Chuck must attach both generated certificate PDFs and include stored DB/audit output for both the individual acceptance record and the company acceptance record.


15. Company-Authority 30-Day Grace Period

After the active Terms are published/enforced, EC should allow a 30-day grace period for company-authority acceptance by Kendra or Chuck.

During the grace period:

If either Kendra or Chuck company-accepts within the 30-day grace period, the company license is considered current and no day-31 company-authority lockout occurs.


16. Day-30 Company-Acceptance Warning Email

If neither Kendra nor Chuck has company-accepted the current active Terms by day 30 of the company-acceptance grace period, EC must send a warning email at 8:00 AM America/Denver on day 30.

Email envelope:

FROM: support@crsabq.com
TO: support@crsabq.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials

Subject:

Employee Center Terms Acceptance Required

Body:

Cash Register Systems, Inc. has not accepted the terms and conditions for continued access to the Employee Center. Access to all accounts will be disabled tomorrow morning at 8 am. Either Kendra or Chuck must log in and accept the terms to provide continued access. Please click the link below to log in.

{{ employee_center_login_url }}

The link must route to the Employee Center login page.

This email should be logged in Postgres with delivery metadata.

Do not CC or BCC anyone.


17. Day-31 Company-Acceptance Lockout and Auto-Unlock

If neither Kendra nor Chuck has company-accepted the current active Terms by day 31, EC must immediately lock all accounts except the immutable owner account.

This lockout is not the same as owner LOCKOUT/service disablement.

This is a company-acceptance-required account lock.

Set all non-owner accounts to locked or blocked until company acceptance clears.

Recommended status/reason:

account_locked = true
account_locked_reason = company_terms_acceptance_required

The immutable owner account remains available.

The lockout must prevent normal EC usage by every non-owner account, including employees, admins, managers, superusers, service accounts, display accounts, and API/integration accounts, unless Quintin N. Mahan expressly excludes a specific technical account in a server-side owner-only configuration.

Kendra and Chuck must still be allowed to reach the restricted login/Terms gate path so one of them can accept the Terms and restore company access.

They must not be allowed to access normal EC usage before acceptance.

Auto-Unlock After Company Acceptance

Once either Kendra or Chuck signs in and completes both:

  1. individual Terms acceptance; and
  2. company-authority Terms acceptance on behalf of Cash Register Systems, Inc.;

EC must automatically clear the company-acceptance-required lockout for all accounts that were locked solely because of:

company_terms_acceptance_required

Auto-unlock must:

Recommended auto-unlock reason:

company_terms_acceptance_completed_auto_unlock

Recommended audit fields:

company_acceptance_id
accepted_by_user_id
accepted_by_user_email
terms_version
terms_sha256_hash
unlocked_accounts_count
skipped_accounts_count
skipped_accounts_json
auto_unlocked_at
support_restored_notice_sent_at
owner_detail_notice_sent_at

Detailed Auto-Unlock Email to Quintin

Email envelope:

FROM: support@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials

Subject:

Employee Center Access Restored After Company Terms Acceptance

Body:

Cash Register Systems, Inc. has accepted the terms and conditions for continued access to the Employee Center. Employee access has been restored for accounts locked only because company acceptance was required.

Accepted By: {{ accepted_by_user_name }}
Accepted At: {{ accepted_at }}
Accounts Restored: {{ unlocked_accounts_count }}
Accounts Skipped: {{ skipped_accounts_count }}

{{ employee_center_login_url }}

The detailed email to Quintin may include the certificate record IDs, certificate hashes, account unlock counts, skipped account details, and audit IDs.

Simple Restored-Access Email to Support

After all eligible accounts locked solely for company acceptance are confirmed unlocked, EC must send a simple email to support.

Email envelope:

FROM: support@crsabq.com
TO: support@crsabq.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials

Subject:

Employee Center access is restored.

Body:

Employee Center access is restored.

This support email must not include certificate hashes, owner-only audit details, skipped account details, private legal metadata, or internal owner-control details.

Day-31 lockout must be logged in Postgres and emailed to Quintin.

Day-31 lockout email envelope:

FROM: support@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured EC/Zoho sending credentials

Subject:

Employee Center Access Disabled Pending Terms Acceptance

Body:

Cash Register Systems, Inc. has not accepted the terms and conditions for continued access to the Employee Center. Access for all employees has been disabled until Terms are accepted. Either Kendra or Chuck must log in and accept the terms to provide continued access. Please click the link below to log in.

{{ employee_center_login_url }}

The link must route to the Employee Center login page.

Do not CC or BCC anyone.


18. qmahan@crsabq.com Terms Gate Deferral

The account qmahan@crsabq.com must not be forced through the Terms gate until after company-authority acceptance is satisfied.

Company-authority acceptance is satisfied when at least one of the following has accepted on behalf of CRS:

Kendra
Chuck

This is an owner-control exception.

Recommended logic:

def should_defer_owner_terms_gate(user):
    return (
        user.email.lower() == "qmahan@crsabq.com"
        and not company_authority_acceptance_satisfied()
    )

The owner account may still voluntarily view the Terms, Legal hub, acceptance dashboard, and certificate records.

Once company-authority acceptance is satisfied, the owner account may be prompted for owner acceptance if Quintin wants an owner acceptance record.

This exception applies only to the owner account and must not apply to Michael, admins, superusers, managers, or any other account.


19. Owner-Only LOCKOUT Button

Add a restricted button on the owner profile page.

Button label:

LOCKOUT

Visibility rule:

The button is visible only when the authenticated principal is the immutable owner principal for Quintin N. Mahan.

Before the owner email migration, the visible account email is:

qmahan@crsabq.com

After lockout/migration, the owner account email may become:

mahanquintin@gmail.com

Do not rely only on role names such as superuser, admin, owner, or manager.

Not even a superuser should see this button unless the authenticated principal is the immutable owner principal.

Michael must not see this button.

Kendra must not see this button.

Chuck must not see this button.

No other admin must see this button.

Recommended immutable owner controls:

EC_OWNER_PRINCIPAL_ID=<Quintin owner user id>
EC_OWNER_PRE_LOCKOUT_EMAIL=qmahan@crsabq.com
EC_OWNER_POST_LOCKOUT_EMAIL=mahanquintin@gmail.com

The owner principal ID should not be editable through the normal UI.


20. Emergency Nature of Owner LOCKOUT

Owner LOCKOUT is an emergency owner-protection measure reserved for serious owner-control, access-control, credential, legal, payment, ownership, hostile-access, unauthorized-control, attempted-seizure, service-continuity, or security events.

Owner LOCKOUT is not intended as routine administration, punishment, retaliation, ordinary user management, ordinary collection activity, or ordinary employee discipline.

Owner LOCKOUT is data-preserving.

Owner LOCKOUT preserves EC structures, schemas, tables, table data, legal records, Terms records, acceptance records, decline records, certificate records, certificate PDFs, hashes, audit records, customer records, employee records, operational records, and owner evidence while disabling non-owner access and severing credential-backed outside-world integrations.

Owner LOCKOUT exists to prevent unauthorized control, misuse, seizure, compromise, attempted takeover, credential misuse, hostile access, continued unlicensed use, or loss of owner control over privately owned EC systems, EC source/control structures, EC infrastructure, owner-controlled credentials, and EC-connected integrations.

Where practical, less restrictive steps should be used first, including:

Owner LOCKOUT remains available as a last-resort emergency measure when Quintin N. Mahan determines that immediate owner-control protection is required.

Nothing in this section limits Quintin N. Mahan’s right to use Owner LOCKOUT when he determines in good faith that immediate protection of EC, owner credentials, owner infrastructure, owner access, legal records, audit evidence, or EC-connected systems is necessary.


21. LOCKOUT Confirmation With Email 2FA

Because LOCKOUT is destructive, require owner-only confirmation and email 2FA.

The LOCKOUT confirmation page must require:

No other user may reach this page.

The 2FA code must be generated only after owner identity is re-confirmed.

The 2FA code must expire automatically after five minutes.


22. LOCKOUT Email 2FA Code Handling

When the owner initiates LOCKOUT:

  1. generate a cryptographically secure random code;
  2. store only a hash of the code in Postgres;
  3. store expiration timestamp five minutes from generation;
  4. store used/unused status;
  5. email the plaintext code to mahanquintin@gmail.com through the Zoho integration;
  6. immediately remove the plaintext email payload/code from EC memory/outbox records after send;
  7. do not store the plaintext code in logs;
  8. do not store the plaintext code in Postgres;
  9. do not store the plaintext code in email-log body fields;
  10. wait for the owner to enter the code before continuing.

Recommended table:

CREATE TABLE IF NOT EXISTS owner_lockout_2fa_challenges (
    id BIGSERIAL PRIMARY KEY,
    owner_user_id BIGINT NOT NULL,
    code_hash TEXT NOT NULL,
    expires_at TIMESTAMPTZ NOT NULL,
    used_at TIMESTAMPTZ NULL,
    attempts_count INTEGER NOT NULL DEFAULT 0,
    max_attempts INTEGER NOT NULL DEFAULT 5,
    delivery_email TEXT NOT NULL DEFAULT 'mahanquintin@gmail.com',
    delivery_from TEXT NOT NULL DEFAULT 'support@crsabq.com',
    delivery_transport TEXT NOT NULL DEFAULT 'zoho_integration',
    delivery_message_id TEXT NULL,
    ip_address TEXT NULL,
    user_agent TEXT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

The email body should be minimal:

Employee Center LOCKOUT verification code:

{{ code }}

This code expires in 5 minutes.

If you did not initiate LOCKOUT, secure Employee Center immediately.

Email envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials

After sending, any EC outbound-mail staging row containing the plaintext code must be purged, redacted, or overwritten so the code cannot be recovered from EC.

It is acceptable to store delivery metadata such as message ID, timestamp, transport, from, to, and success/failure status.

It is not acceptable to store the plaintext code or full email body containing the code.


23. LOCKOUT Action — Full DEV/PROD Access Shutdown

Route:

POST /owner/lockout

When the immutable owner principal confirms LOCKOUT, EC must perform a full owner-only access shutdown across DEV and PROD.

The purpose of LOCKOUT is to immediately stop all non-owner access to EC and sever credential-backed outside-world integrations, while preserving EC structures, schemas, tables, table data, internal records, legal records, certificate records, hashes, audit records, and owner evidence.

LOCKOUT must not delete EC business data merely because service is disabled.

LOCKOUT does not create ownership of raw database data, raw CRS-owned operational records, customer records, customer relationships, independent outside source records, or third-party-owned records. LOCKOUT preserves table data as evidence and operational records while severing outside-world access and protecting EC Protected Materials.

LOCKOUT must preserve:

LOCKOUT must remove, revoke, clear, disable, sever, or cryptographically destroy credential-backed outside-world connections and access pathways.

When the owner confirms LOCKOUT, EC must perform the following in a single audited owner-control workflow:

  1. verify authenticated immutable owner principal;
  2. verify account email is currently qmahan@crsabq.com or immutable owner principal ID matches;
  3. require password re-authentication;
  4. require valid unexpired email 2FA code sent to mahanquintin@gmail.com;
  5. require confirmation text LOCKOUT;
  6. mark the 2FA challenge used;
  7. write pre-lockout audit event;
  8. change the owner account email/username on file from qmahan@crsabq.com to mahanquintin@gmail.com;
  9. preserve the owner user ID, owner password hash, owner MFA/recovery state where applicable, and owner-only capability;
  10. lock every non-owner PROD web account;
  11. lock every non-owner DEV web account;
  12. revoke every non-owner PROD web session;
  13. revoke every non-owner DEV web session;
  14. invalidate all non-owner remembered-login cookies and persistent web-login tokens;
  15. revoke all non-owner API sessions/tokens;
  16. revoke or block all non-owner local agent sessions;
  17. revoke or block all non-owner SSH access controlled by EC policy;
  18. lock Michael’s SSH key and any mapped Michael session token;
  19. lock all other non-owner SSH keys controlled by EC policy unless expressly owner-exempted in server-side owner-only configuration;
  20. terminate active non-owner SSH sessions where technically possible;
  21. disable all non-owner service/display/API/integration accounts unless expressly owner-exempted in server-side owner-only configuration;
  22. clear all saved Google Workspace service credentials;
  23. clear all saved Google OAuth tokens;
  24. clear all saved Google refresh tokens;
  25. clear all saved Google service-account/private-key material stored in EC;
  26. clear all saved Zoho credentials;
  27. clear all saved Zoho OAuth tokens and refresh tokens;
  28. clear all saved Zoho API keys/secrets stored in EC;
  29. clear all saved Authorize.net credentials, transaction keys, API login IDs, client keys, webhook secrets, and tokenized gateway access secrets stored in EC;
  30. clear all saved Zapier webhook URLs, Zapier secrets, Zapier API tokens, and Zapier integration credentials stored in EC;
  31. clear all saved Selflane credentials, API keys, OAuth tokens, webhook secrets, and credential-backed Selflane connection details stored in EC;
  32. clear all saved credentials for non-free or paid third-party APIs;
  33. clear all saved credentials for credential-backed outside-world integrations;
  34. disable scheduled Google sync jobs;
  35. disable scheduled Zoho sync jobs;
  36. disable Authorize.net sync/payment/webhook workers;
  37. disable Zapier outgoing/incoming webhook workers;
  38. disable Selflane sync/API workers;
  39. disable non-free API workers;
  40. disable all external integration workers that rely on cleared credentials;
  41. disable outbound API calls except owner-approved direct-owner notification and owner-tailnet maintenance routes where configured;
  42. disable inbound webhooks from outside systems unless owner-approved and non-credentialed;
  43. set global EC mode to service_disabled;
  44. set license/service status to disabled_contract_required;
  45. preserve direct owner access over Tailnet by direct Tailnet IP address;
  46. block public/normal web access for every non-owner account;
  47. block DEV access for every non-owner account;
  48. block PROD access for every non-owner account;
  49. preserve owner-only legal, audit, certificate, export, status, and lockout review access over direct Tailnet IP where configured;
  50. write post-lockout audit event;
  51. email owner immediately at mahanquintin@gmail.com;
  52. redirect all non-owner/non-exempt requests internally to the service-disabled page.

Owner notification email:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials if available before credential clearing; otherwise owner-only local queue / owner-tailnet review

No CC or BCC should be used.

If required LOCKOUT emails are sent through Zoho, they must be sent and committed before Zoho credentials are cleared.

After final required LOCKOUT email delivery is attempted, Zoho credentials may be cleared as part of the lockout workflow.

If Zoho delivery is unavailable, the lockout must still execute, and the owner notification must be queued in an owner-only local audit/notification queue for direct Tailnet review.


24. Credential Clearing and Outside-World Severance Requirements

Credential clearing must remove active secrets from EC-controlled storage and sever credential-backed outside-world access.

The goal is:

Preserve EC structures and table data.
Sever external credential-backed connections.
Prevent non-owner access.
Keep only immutable owner access through direct Tailnet IP where configured.

Credential clearing must target, without limitation:

Do not merely hide credentials in the UI.

Credential records should be either deleted, nulled, revoked, rotated to unusable values, or cryptographically destroyed by deleting the encryption key, depending on the existing EC secret-storage model.

Preserve an audit record that credentials were cleared without preserving the secret values themselves.

Audit records must not include raw secret values.

Tables, schemas, structural records, and historical business data should remain intact unless Quintin N. Mahan separately authorizes deletion.

Important: LOCKOUT may use Google Workspace service credentials to send owner 2FA and final owner lockout notifications before clearing Google credentials. Day-30 and day-31 warning emails remain Zoho-only as specified above. After final required owner LOCKOUT email delivery is attempted or queued, Google/Zoho credentials may be cleared according to the lockout workflow.


25. Account Locking Requirements

During owner LOCKOUT, all accounts except the immutable owner principal must be locked.

Recommended account fields:

ALTER TABLE users
ADD COLUMN IF NOT EXISTS account_locked BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS account_locked_at TIMESTAMPTZ NULL,
ADD COLUMN IF NOT EXISTS account_locked_reason TEXT NULL,
ADD COLUMN IF NOT EXISTS locked_by_user_id BIGINT NULL,
ADD COLUMN IF NOT EXISTS owner_lockout_exempt BOOLEAN NOT NULL DEFAULT FALSE;

Set for every non-owner account:

account_locked = true
account_locked_at = now()
account_locked_reason = owner_lockout_service_disabled_contract_required
locked_by_user_id = <owner_user_id>

Only the immutable owner principal should have:

owner_lockout_exempt = true

This field must not be editable through the normal UI.


26. Global Service Disabled Mode

Create or use a global system settings table.

Recommended fields:

CREATE TABLE IF NOT EXISTS system_service_status (
    id BIGSERIAL PRIMARY KEY,
    status TEXT NOT NULL,
    reason TEXT NULL,
    message TEXT NULL,
    changed_by_user_id BIGINT NULL,
    changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    metadata_json JSONB NULL
);

Set status:

service_disabled

Set reason:

disabled_contract_required

Set message:

SERVICE IS DISABLED. NEGOTIATION OF A PAID CONTRACT IS REQUIRED TO RESTART SERVICE. LICENSES START AT $50/USER PER MONTH.

27. Service Disabled Page

When global service status is service_disabled, all non-owner users and unauthenticated app access should route internally to:

/service-disabled

Display exactly:

SERVICE IS DISABLED. NEGOTIATION OF A PAID CONTRACT IS REQUIRED TO RESTART SERVICE. LICENSES START AT $50/USER PER MONTH. SETUP FEE: $1,500.

The page must not expose normal EC navigation.

The page must not expose customer data, reports, dashboards, tasks, timecards, calls, directory, attachments, exports, imports, admin tools, integrations, or operational records.

The page must not expose any owner-only legal, certificate, audit, lockout, SSH, credential, API, or Tailnet information.

The immutable owner principal may retain access only through owner-approved direct Tailnet access by direct Tailnet IP address, where configured.

Owner retained access may include owner-only:

No non-owner account should retain normal DEV or PROD web, SSH, API, agent, integration, display, or service-account access after owner LOCKOUT.


28. Owner Lockout Audit Table

Recommended table:

CREATE TABLE IF NOT EXISTS owner_lockout_events (
    id BIGSERIAL PRIMARY KEY,
    event_type TEXT NOT NULL,
    initiated_by_user_id BIGINT NOT NULL,
    initiated_by_email_before TEXT NULL,
    initiated_by_email_after TEXT NULL,
    ip_address TEXT NULL,
    user_agent TEXT NULL,
    confirmation_text_hash TEXT NULL,
    two_factor_challenge_id BIGINT NULL,
    two_factor_verified_at TIMESTAMPTZ NULL,
    accounts_locked_count INTEGER NULL,
    sessions_revoked_count INTEGER NULL,
    google_credentials_cleared_count INTEGER NULL,
    zoho_credentials_cleared_count INTEGER NULL,
    service_status_after TEXT NULL,
    owner_email_sent_at TIMESTAMPTZ NULL,
    owner_email_message_id TEXT NULL,
    metadata_json JSONB NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Do not store raw confirmation text if a hash is sufficient.

Do not store passwords, raw 2FA codes, or raw secrets.


29. Owner Lockout Email

Subject:

EC OWNER LOCKOUT EXECUTED — SERVICE DISABLED

Body must include:

Envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials if available before credential clearing; otherwise owner-only local queue / owner-tailnet review

Service Disabled Message:

SERVICE IS DISABLED. NEGOTIATION OF A PAID CONTRACT IS REQUIRED TO RESTART SERVICE. LICENSES START AT $50/USER PER MONTH. SETUP FEE: $1,500.

No CC or BCC should be used.


30. Middleware Priority

Request handling priority must be:

  1. static required assets;
  2. owner lockout 2FA and emergency/lockout routes where owner-authenticated;
  3. global service-disabled mode;
  4. authenticated terms gate requirement;
  5. pre-acceptance Terms-page-only exception;
  6. normal route permission checks;
  7. normal app handling.

No normal EC route should run before the service-disabled and Terms gate checks.


31. Decline Email

Subject:

EC TERMS DECLINED — {{ user_name }} — {{ user_email }}

Body must include:

Envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials

Send immediately after the decline record is committed.

If email delivery fails, preserve the database decline record and retry email through owner/admin retry tooling.


32. Acceptance Email

Subject:

EC TERMS ACCEPTED — {{ user_name }} — {{ user_email }}

For Kendra/Chuck company-authority acceptance, also send:

EC TERMS ACCEPTED — COMPANY — Cash Register Systems, Inc. — accepted by {{ accepted_by_user_name }}

Envelope for all acceptance/certificate emails:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials

No user receives certificate emails by default.


When the active Terms acceptance requirement is activated, renewed, materially updated, or enforced for a new Terms version/hash, EC must force-clear all existing DEV and PROD web sessions so no user can continue using a previously authenticated browser session without passing through the current Terms gate.

This applies to:

The purpose is to ensure that users already logged in before Terms activation are forced to complete a fresh login and current Terms gate check immediately.

Required Behavior

Upon Terms activation or Terms version/hash change:

  1. increment a global session_epoch or terms_session_epoch;
  2. invalidate all existing web sessions in PROD;
  3. invalidate all existing web sessions in DEV;
  4. invalidate all remembered-login tokens;
  5. invalidate all browser session mappings server-side;
  6. force all users to log in again;
  7. require current Terms acceptance before normal EC usage;
  8. preserve the immutable owner exception where configured;
  9. write an audit event;
  10. email Quintin N. Mahan that session invalidation occurred.

Recommended system setting:

terms_session_epoch = <monotonic integer or timestamp>

Each session should carry the epoch that existed when the session was created.

If the session epoch is older than the active terms_session_epoch, EC must treat the session as invalid and require fresh login.

Client Cookies

EC cannot directly erase cookies from browsers that are not currently making requests, but EC must invalidate the server-side session/token backing those cookies.

On the next request, the stale cookie must be rejected, cleared by response header where practical, and redirected to login/Terms gate.

Recommended response behavior:

Set-Cookie: <session_cookie>=; Max-Age=0; Path=/; HttpOnly; Secure; SameSite=Lax

Use the actual EC cookie names.

Owner Exception

The immutable owner principal may be exempted from forced Terms gate presentation until the configured company-authority acceptance condition is satisfied.

The owner account may still have sessions invalidated for safety, but after re-login it may bypass the Terms gate according to the owner exception rule.

No other user receives this exception.


34. Dev Machine / Agent Enforcement of PROD Acceptance Status

The development machine and any EC-connected local agents must be able to verify the current company acceptance, individual user acceptance, company lockout, and service-disabled status from EC PROD.

This is required so development tools, DEV web accounts, local agents, SSH-assisted scripts, and automation agents cannot be used to bypass the company-acceptance lockout, individual Terms acceptance, owner LOCKOUT, or service-disabled state.

DEV must depend on PROD for Terms acceptance validity.

If a user has not accepted the current active Terms on PROD, that user’s DEV web account must be locked by default until PROD acceptance is valid.

The immutable owner principal is the only default exception.

Michael’s DEV access depends on whether Michael has accepted the current live Terms on PROD.

The same rule applies to all non-owner DEV users.

Required Background Runner

Implement a background runner on the dev machine and any EC-controlled agent host that needs enforcement.

Recommended runner name:

ec-prod-terms-status-runner

Recommended behavior:

  1. run on startup;
  2. run on a recurring interval;
  3. contact EC PROD over HTTPS/Tailscale or another owner-approved secure channel;
  4. authenticate using an owner-approved machine credential;
  5. request only the minimum needed status;
  6. verify response signature or HMAC where implemented;
  7. cache the most recent valid PROD status locally;
  8. fail closed for DEV web access and unlock/account-restore actions if PROD cannot be reached after the allowed grace window;
  9. write local audit logs;
  10. never cache raw secrets or certificate private material.

The background runner must query PROD for:

active_terms_version
active_terms_sha256_hash
company_acceptance_satisfied
company_acceptance_accepted_by
company_acceptance_accepted_at
company_acceptance_certificate_id
company_acceptance_certificate_hash
day_31_company_lockout_active
owner_lockout_active
service_disabled_active
user_acceptance_statuses
user_accepted_terms_versions
user_accepted_terms_hashes
user_terms_status_updated_at
michael_prod_terms_accepted
michael_prod_terms_version
michael_prod_terms_hash
michael_ssh_enforcement_required
michael_ssh_key_fingerprints
blocked_session_tokens
last_status_signed_at

Recommended PROD endpoint:

GET /api/internal/legal/acceptance-status

This endpoint must be owner/admin protected and intended for EC-controlled machine enforcement only.

It must not expose customer records, employee private data, passwords, raw secrets, raw tokens, or full certificate bodies unless explicitly required.

DEV Web Account Enforcement

DEV must enforce PROD acceptance status for every non-owner user.

Rules:

If PROD says user accepted current Terms: DEV account may be allowed according to normal DEV permissions.
If PROD says user is pending: DEV account locked.
If PROD says user declined: DEV account locked.
If PROD has no current acceptance record: DEV account locked.
If PROD cannot be verified after allowed grace window: DEV account locked.
If user is immutable owner principal: owner exception may apply.

Recommended DEV account lock reason:

dev_locked_pending_prod_terms_acceptance

Recommended DEV account unlock reason:

dev_unlocked_prod_terms_acceptance_verified

Do not allow DEV-only acceptance to substitute for PROD acceptance unless Quintin N. Mahan later creates a separate written owner-approved rule.

Local Enforcement File

The runner should write a local root/admin-owned status file on each enforced host.

Recommended path:

/etc/employee-center/prod_acceptance_status.json

Permissions:

owner: root
group: root
mode: 0600

The file should contain only the minimum enforcement status and verification metadata.


35. Michael SSH Key / Session Enforcement During Company Lockout

If day-31 company-acceptance lockout is active and the current PROD status does not show valid company acceptance by Kendra or Chuck, then Michael’s SSH key and any mapped Michael session token must not be allowed to unlock EC accounts, restore employee access, bypass the lockout, disable the runner, modify Terms records, clear company lockout flags, or change owner-control status.

This applies to:

Deny Message

If a command comes from Michael’s SSH key, Michael’s mapped session token, or Michael’s mapped machine principal and attempts to unlock accounts or bypass the Terms/company lockout while company acceptance is not satisfied, the system must deny it explicitly with:

UNAUTHORIZED: Company acceptance of the Employee Center Terms and Conditions is required before access can be restored. Either Kendra or Chuck must accept the Terms, or contact the owner.

The denial message must be printed to the active SSH session before termination where technically possible.

Immediate SSH Session Termination

After displaying the denial message, the active SSH command/session must be terminated immediately.

Recommended behavior:

  1. print the explicit denial message;
  2. write the denial and attempted command to local audit;
  3. send the immediate owner email;
  4. lock Michael’s SSH key;
  5. revoke Michael’s mapped local session token;
  6. terminate the active SSH process/session;
  7. refuse any further commands from that key until owner unlock or policy auto-unlock.

If the command is running through a forced-command wrapper, the wrapper must exit non-zero after printing the denial.

If the host can identify the active SSH process, it may terminate that process after the audit/email/key-lock operation is committed or queued.

Immediate SSH Key Lock

After such an unauthorized unlock/bypass attempt by Michael’s SSH key or mapped session token, the enforced host must immediately lock Michael’s SSH key until one of the following occurs:

  1. Quintin N. Mahan manually unlocks it through immutable owner controls; or
  2. the EC PROD runner verifies that company acceptance is valid/current and the key was locked solely for the company Terms acceptance reason.

Recommended actions:

  1. add Michael’s SSH public key fingerprint to an EC-controlled blocked-key list;
  2. deny further SSH command execution for that key;
  3. revoke or invalidate Michael’s mapped local session token;
  4. write a local enforcement audit event;
  5. notify Quintin N. Mahan by email immediately;
  6. terminate the active SSH session;
  7. do not allow Michael, a superuser, or any non-owner admin to self-unlock the SSH key.

This is a key-specific enforcement lock.

It does not need to delete the public key permanently.

It should disable or block use of the key until owner review or policy auto-unlock.

Runner Auto-Unlock After Valid Company Acceptance

The PROD acceptance status runner must continue checking company acceptance after Michael’s SSH key is locked for the company Terms acceptance reason.

If the runner verifies that:

then the runner may automatically unlock Michael’s SSH key for ordinary SSH access.

Recommended auto-unlock reason:

michael_ssh_key_auto_unlocked_company_terms_acceptance_valid

Recommended auto-unlock audit fields:

ssh_key_fingerprint
previous_lock_reason
company_acceptance_id
company_acceptance_certificate_hash
company_acceptance_accepted_by
company_acceptance_accepted_at
active_terms_version
active_terms_sha256_hash
auto_unlocked_at
runner_host
runner_status_signature

The auto-unlock must be logged and emailed to Quintin N. Mahan.

Protected Chain Restrictions Remain After Auto-Unlock

Auto-unlocking Michael’s SSH key after valid company acceptance does not grant Michael authority to modify, bypass, disable, or weaken the Terms/Legal/Owner-Control chain.

Even after his SSH key is auto-unlocked, Michael must remain blocked from modifying or disabling:

If Michael attempts to modify this protected chain, the system must deny the action even if company acceptance is valid.

Recommended denial message for protected-chain modification:

UNAUTHORIZED: This Terms, Legal, certificate, lockout, runner, and owner-control chain is restricted to the immutable owner principal.

This denial does not necessarily require locking Michael’s SSH key unless the attempt also qualifies as tampering, bypass, or an owner-control violation under the active security rules. The attempt must still be audited and emailed to Quintin N. Mahan.

Owner-Only SSH Key Unlock

Only the immutable owner principal may manually unlock Michael’s SSH key.

Recommended manual unlock controls:

owner principal only
password re-authentication
audit event required
reason required
optional email 2FA

No role called admin, superuser, manager, service manager, or developer should be enough.

The check must be against the immutable owner principal.


36. Agent Command Authorization Rules

Every EC-controlled agent capable of locking, unlocking, restoring, disabling, or altering Terms/acceptance state must enforce the following rule before executing any command:

if command.affects_terms_or_access_control:
    prod_status = load_verified_prod_acceptance_status()

    if prod_status.day_31_company_lockout_active and not prod_status.company_acceptance_satisfied:
        if command.actor_matches_michael_ssh_key_or_session:
            deny("UNAUTHORIZED: Company acceptance of the Employee Center Terms and Conditions is required before access can be restored. Either Kendra or Chuck must accept the Terms, or contact the owner.")
            lock_michael_ssh_key()
            notify_owner_immediately()
            terminate_active_ssh_session()
            return

        if not command.actor_is_immutable_owner:
            deny("UNAUTHORIZED: Owner approval or company acceptance is required.")
            return

This rule must apply even if the actor has local admin privileges on the dev machine or is otherwise a high-privilege EC user.

Local machine privileges do not override EC owner-control enforcement.


37. Michael SSH Enforcement Audit, Immediate Email, and Session Termination

When Michael’s SSH key or mapped session token is denied and locked, create an audit event and immediately notify Quintin N. Mahan.

Recommended local/PROD audit fields:

event_type = michael_ssh_key_locked_company_terms_required
actor_name
actor_user_id
ssh_key_fingerprint
session_token_hash
host_name
host_id
command_attempted
command_category
prod_company_acceptance_satisfied
prod_day_31_company_lockout_active
prod_status_timestamp
denied_at
ip_address
terminal_session_id
active_ssh_pid
denial_message_displayed
ssh_session_terminated
locked_by_policy = true
owner_unlock_required = true

Owner email envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials if available; otherwise queue locally for EC owner review

Subject:

Michael SSH Key Locked — Unauthorized Unlock Attempt

Body:

Michael’s SSH key or mapped session attempted an unauthorized unlock, access-restoration, or lockout-bypass action while company acceptance of the Employee Center Terms and Conditions was not satisfied.

The key has been locked pending owner review, and the active SSH session was terminated.

Denial Message:
UNAUTHORIZED: Company acceptance of the Employee Center Terms and Conditions is required before access can be restored. Either Kendra or Chuck must accept the Terms, or contact the owner.

Host: {{ host_name }}
SSH Key Fingerprint: {{ ssh_key_fingerprint }}
Attempted Command: {{ command_attempted }}
Denied At: {{ denied_at }}
Session Terminated: {{ ssh_session_terminated }}

Either Kendra or Chuck must accept the Terms, or the owner must review manually.

The email must be sent immediately after the audit/key-lock event is committed or queued.

If Zoho mail is unavailable because credentials were cleared or PROD is unavailable, the local agent must queue the owner notification in an owner-only local queue and retry until delivered.

The active SSH session must still be denied and terminated even if email delivery is delayed.


38. New / Updated Terms Version Cycle Reset

Every new active Terms version, Terms hash, root Legal index hash, Policy Library index hash, or full Legal bundle hash that is configured to require renewed acceptance must restart the entire acceptance cycle.

This applies to:

Old acceptance does not satisfy a new active Terms version/hash.

Old company acceptance does not satisfy a new active Terms version/hash.

Old DEV acceptance does not satisfy PROD acceptance.

The cycle repeats every time a new Terms/version/hash state becomes acceptance-relevant.

Required Cycle Behavior for Every New / Updated Terms Cycle

When a new or updated Terms cycle is activated:

  1. prior acceptances remain preserved as historical evidence;
  2. prior certificates remain preserved as historical evidence;
  3. prior hashes remain preserved as historical evidence;
  4. current access must be evaluated against the new active Terms/version/hash state;
  5. DEV and PROD web sessions must be invalidated server-side immediately;
  6. stale cookies must be rejected on the next request;
  7. remembered-login tokens and persistent web-login tokens must be invalidated;
  8. users already logged in must be forced to log in again;
  9. users must flow through the Terms gate before normal EC usage;
  10. individual users must accept the new current Terms before normal usage;
  11. Kendra or Chuck must company-accept the new current Terms for company acceptance to be satisfied;
  12. the 30-day company-authority grace period starts over for the new active Terms cycle;
  13. if neither Kendra nor Chuck company-accepts by day 30, the day-30 warning email must send again;
  14. if neither Kendra nor Chuck company-accepts by day 31, the day-31 company-acceptance lockout must run again;
  15. all non-owner employee/user accounts must lock on day 31 if company acceptance is not satisfied;
  16. Kendra and Chuck must still be able to reach the restricted login/Terms gate path after day-31 lockout;
  17. once Kendra or Chuck company-accepts, accounts locked solely for company Terms acceptance must auto-unlock;
  18. Michael SSH/agent enforcement repeats against the new current Terms cycle;
  19. DEV user access again depends on verified current PROD acceptance for the new Terms cycle;
  20. the immutable owner exception remains available as configured.

Day-30 Email Repeats for Every New / Updated Terms Cycle

For every new or updated Terms cycle, if neither Kendra nor Chuck has company-accepted by day 30, EC must send the day-30 warning email again at 8:00 AM America/Denver.

Email envelope:

FROM: support@crsabq.com
TO: support@crsabq.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials

Subject:

Employee Center Terms Acceptance Required

Body:

Cash Register Systems, Inc. has not accepted the terms and conditions for continued access to the Employee Center. Access to all accounts will be disabled tomorrow morning at 8 am. Either Kendra or Chuck must log in and accept the terms to provide continued access. Please click the link below to log in.

{{ employee_center_login_url }}

Day-31 Lockout Repeats for Every New / Updated Terms Cycle

For every new or updated Terms cycle, if neither Kendra nor Chuck has company-accepted by day 31, EC must lock all non-owner accounts again.

This applies even if the company accepted a prior Terms version.

The lockout reason should be:

company_terms_acceptance_required

The immutable owner account remains exempt.

Kendra and Chuck may access only the restricted login/Terms gate path so one of them can company-accept the new Terms cycle.

Day-31 lockout email envelope:

FROM: qmahan@crsabq.com
TO: mahanquintin@gmail.com
CC: none
BCC: none
MAIL TRANSPORT: Zoho integration using Quintin N. Mahan’s configured credentials

Subject:

Employee Center Access Disabled Pending Terms Acceptance

Body:

Cash Register Systems, Inc. has not accepted the terms and conditions for continued access to the Employee Center. Access for all employees has been disabled until Terms are accepted. Either Kendra or Chuck must log in and accept the terms to provide continued access. Please click the link below to log in.

{{ employee_center_login_url }}

No Session Carryover

No active DEV or PROD session may carry over from one acceptance-relevant Terms cycle to the next.

No user may avoid the new Terms gate because they were already logged in.

No user may use a stale browser cookie, stale remembered-login token, old web session, old DEV session, old PROD session, old API session, or old local agent session to bypass the new Terms cycle.

The only exception is the immutable owner exception expressly configured by Quintin N. Mahan.


39. Tests

Implement tests for:

  1. valid credentials redirect to Terms gate when Terms not accepted;
  2. invalid credentials do not create Terms records;
  3. pre-acceptance authenticated session cannot access dashboard;
  4. pre-acceptance authenticated session cannot access directory;
  5. pre-acceptance authenticated session cannot access API data;
  6. Terms gate has no normal app navigation;
  7. Terms link is allowed from the Terms gate;
  8. Terms page from the gate has only Terms content and back-to-gate behavior;
  9. acceptance writes directly to Postgres;
  10. acceptance emails through Zoho only to mahanquintin@gmail.com;
  11. acceptance emails have no CC/BCC;
  12. acceptance clears pending/declined block;
  13. current accepted version bypasses Terms gate;
  14. active Terms version change reopens Terms gate;
  15. decline writes directly to Postgres;
  16. decline emails through Zoho only to mahanquintin@gmail.com;
  17. decline emails have no CC/BCC;
  18. decline logs user out immediately;
  19. declined account loops back to Terms gate after future login until accepted;
  20. employee setup Terms status displays Pending/Accepted/Declined;
  21. employee setup Terms status is non-editable;
  22. qmahan@crsabq.com bypasses Terms gate until company-authority acceptance is satisfied;
  23. one of Kendra or Chuck company-accepting satisfies company acceptance;
  24. both Kendra and Chuck may company-accept and generate separate certificates;
  25. day-30 warning sends at 8:00 AM America/Denver if neither has company-accepted;
  26. day-30 warning goes from support@crsabq.com to support@crsabq.com with the simple required notice text and Employee Center login link;
  27. day-31 locks all non-owner accounts if neither company-authority user accepted and emails the simple expired-session/access-disabled notice with Employee Center login link;
  28. Kendra or Chuck can still reach the restricted Terms gate during day-31 lockout;
  29. company-authority acceptance by either Kendra or Chuck automatically unlocks accounts locked solely for company_terms_acceptance_required;
  30. auto-unlock does not unlock accounts locked for unrelated security, termination, owner LOCKOUT, or service-disabled reasons;
  31. day-31 lock clears after Kendra or Chuck company-accepts, if Quintin permits automatic clearing;
  32. Michael cannot see LOCKOUT button;
  33. Kendra cannot see LOCKOUT button;
  34. Chuck cannot see LOCKOUT button;
  35. superuser who is not immutable owner cannot see LOCKOUT button;
  36. only immutable owner principal can see LOCKOUT button;
  37. LOCKOUT requires password re-authentication;
  38. LOCKOUT requires email 2FA code sent to mahanquintin@gmail.com;
  39. LOCKOUT 2FA code expires after five minutes;
  40. LOCKOUT stores only 2FA code hash, not plaintext code;
  41. LOCKOUT purges/redacts plaintext 2FA email body from EC after sending;
  42. LOCKOUT requires confirmation text;
  43. LOCKOUT changes owner email/username to mahanquintin@gmail.com;
  44. LOCKOUT locks all non-owner accounts;
  45. LOCKOUT revokes non-owner sessions;
  46. LOCKOUT clears Google Workspace credentials without logging secret values;
  47. LOCKOUT clears Zoho credentials without logging secret values after required final emails;
  48. LOCKOUT sets service status to service_disabled;
  49. non-owner users route to service-disabled page;
  50. service-disabled page exposes no operational data;
  51. owner lockout event is audited;
  52. owner lockout email goes through Zoho only to mahanquintin@gmail.com;
  53. owner lockout email has no CC/BCC.
  54. auto-unlock sends detailed unlock/certificate email to Quintin
  55. auto-unlock sends simple restored-access email to support only after all eligible accounts are confirmed unlocked or skipped for preserved unrelated locks
  56. support restored-access email subject is exactly Employee Center access is restored.
  57. support restored-access email body is exactly Employee Center access is restored.
  58. support restored-access email contains no certificate hashes, private audit details, or owner-only details
  59. dev background runner can query EC PROD acceptance status through owner-approved secure channel
  60. dev background runner writes verified local status file with restricted permissions
  61. dev background runner fails closed for unlock/account-restore actions when PROD status is unavailable beyond allowed grace window
  62. Michael’s SSH key cannot unlock accounts during day-31 company lockout if company acceptance is not satisfied
  63. Michael’s mapped session token cannot unlock accounts during day-31 company lockout if company acceptance is not satisfied
  64. Michael receives the explicit unauthorized message when attempting lockout bypass
  65. Michael’s SSH key is immediately locked after unauthorized unlock/bypass attempt
  66. Michael cannot self-unlock his SSH key
  67. admin/superuser who is not immutable owner cannot unlock Michael’s SSH key
  68. only immutable owner principal can unlock Michael’s SSH key
  69. all EC-controlled agents enforce PROD acceptance status before executing access-control commands
  70. Terms activation invalidates all existing PROD web sessions
  71. Terms activation invalidates all existing DEV web sessions
  72. stale browser cookies are rejected server-side and cleared on next response where practical
  73. remember-me tokens and persistent web login tokens are invalidated on Terms activation
  74. already logged-in users are forced to log in again and pass the Terms gate
  75. DEV locks every non-owner web account by default until current PROD Terms acceptance is verified
  76. DEV checks Michael’s current PROD Terms acceptance before allowing Michael DEV web access
  77. DEV checks all non-owner users’ current PROD Terms acceptance before allowing DEV web access
  78. DEV owner account exception applies only to immutable owner principal
  79. Michael SSH unauthorized unlock attempt immediately sends owner email
  80. Michael SSH unauthorized unlock attempt prints explicit denial message
  81. Michael SSH unauthorized unlock attempt terminates active SSH session
  82. Michael SSH key remains blocked until immutable owner manually unlocks it
  83. runner continues checking PROD company acceptance after Michael’s SSH key is locked for company Terms acceptance reason
  84. runner auto-unlocks Michael’s SSH key when company acceptance is valid/current and the key was locked solely for company Terms acceptance reason
  85. runner does not auto-unlock Michael’s SSH key when the key is locked for owner LOCKOUT, security incident, termination, discipline, manual owner hold, tampering, malware, or unrelated reason
  86. Michael remains blocked from modifying Terms, Legal, certificate, runner, lockout, owner-control, and acceptance-chain logic after SSH key auto-unlock
  87. protected-chain modification attempt by Michael receives explicit immutable-owner-only denial message
  88. protected-chain modification attempt by Michael is audited and emailed to Quintin
  89. new active Terms version/hash invalidates prior current acceptance for access-control purposes
  90. new active Terms version/hash restarts the 30-day company-authority grace period
  91. new active Terms version/hash causes day-31 company lockout cycle to repeat if neither Kendra nor Chuck company-accepts
  92. new active Terms version/hash forces DEV to re-check PROD acceptance for every non-owner user
  93. new or updated Terms cycle sends day-30 warning again if neither Kendra nor Chuck company-accepted
  94. new or updated Terms cycle locks all non-owner accounts on day 31 if neither Kendra nor Chuck company-accepted
  95. new or updated Terms cycle forces all existing DEV and PROD sessions through fresh login and Terms gate
  96. old company acceptance does not satisfy new active Terms version/hash
  97. old individual acceptance does not satisfy new active Terms version/hash
  98. stale cookies, remembered-login tokens, and persistent sessions cannot bypass a new Terms cycle
  99. owner LOCKOUT immediately locks all non-owner DEV web accounts
  100. owner LOCKOUT immediately locks all non-owner PROD web accounts
  101. owner LOCKOUT immediately revokes all non-owner DEV and PROD web sessions
  102. owner LOCKOUT locks Michael’s SSH key
  103. owner LOCKOUT locks non-owner SSH keys controlled by EC policy unless owner-exempted
  104. owner LOCKOUT terminates active non-owner SSH sessions where technically possible
  105. owner LOCKOUT changes owner email/username to mahanquintin@gmail.com
  106. owner LOCKOUT clears Google credential-backed connections
  107. owner LOCKOUT clears Zoho credential-backed connections after required final email send/queue
  108. owner LOCKOUT clears Authorize.net credential-backed connections
  109. owner LOCKOUT clears Zapier credential-backed connections
  110. owner LOCKOUT clears Selflane credential-backed connections
  111. owner LOCKOUT clears paid/non-free API credentials
  112. owner LOCKOUT disables external integration workers
  113. owner LOCKOUT preserves database structures and table data
  114. owner LOCKOUT preserves legal, certificate, hash, and audit records
  115. owner LOCKOUT leaves only immutable owner direct Tailnet IP access where configured
  116. service-disabled page displays $50/user/month and $1,500 setup fee
  117. Owner LOCKOUT section states LOCKOUT is an emergency owner-protection measure
  118. Owner LOCKOUT section states LOCKOUT is not routine administration, punishment, retaliation, ordinary user management, ordinary collection activity, or ordinary employee discipline
  119. Owner LOCKOUT section states LOCKOUT is data-preserving
  120. Owner LOCKOUT section states less restrictive steps should be used first where practical
  121. cloned Terms-acceptance sign-in page shows red warning text above checkbox
  122. red warning text clears when checkbox is checked
  123. sign-in button remains disabled until checkbox is checked
  124. checkbox text is exactly I agree to the Terms and Conditions.
  125. Terms and Conditions text links to the active Terms page
  126. Decline updates status and grants no normal EC access
  127. acceptance is recorded only after successful authentication
  128. failed login with checked checkbox does not create acceptance
  129. hash change routes user to cloned Terms-acceptance sign-in page
  130. ordinary sign-in page may omit checkbox for current accepted users
  131. certificate email body includes Attached Certificate of Acceptance for EC Terms and Conditions for: {{ username }}
  132. ordinary individual acceptance email attaches generated individual acceptance PDF certificate
  133. Kendra company-authority acceptance email attaches both individual and company PDF certificates
  134. Chuck company-authority acceptance email attaches both individual and company PDF certificates
  135. certificate email includes stored DB/audit output including Terms version, Terms hash, policy bundle hash, addendum hash, acceptance record IDs, certificate IDs, PDF hashes, timestamp, IP address, user agent, checkbox text, Terms URL, audit event ID, and delivery event ID
  136. certificate email body/subject/attachments/transmitted DB output do not mention mailbox cleanup or sent-copy handling
  137. internal sent-message copy cleanup does not delete EC certificate/audit records
  138. day-30 and day-31 warning emails remain Zoho layout/transport

40. Definition of Done

This addendum is complete when:


End of Employee Center Terms Gate, Company Acceptance Grace Period, and Owner LOCKOUT Addendum.