WRKLOG-2026-06-03
Summary
Wednesday. Fill summary at end of day.
URGENT - All Domains
Carryover Backlog (CRITICAL)
| Task | Details | Origin | Days | Status |
|---|---|---|---|---|
MSCHAPv2 Migration Report |
Report due. 6-sheet Standard Report (exec summary, trend, waves, device detail, stale, policy match). Sheet 6 added 05-14: policy match by protocol for removal planning + anonymous identity validation. Migration window 2026-05-04 to 2026-05-30. ~6,227 devices, 5 waves. |
2026-04-17 |
49 |
P0 - DUE — run report this week |
Abnormal Security — ✅ COMPLETE |
CR-2026-05-07-abnormal-read-write. CAB approved 2026-05-12. Implemented successfully 2026-05-13. Read/write enabled for pilot group. Post-deployment validation pending. |
2026-05-07 |
29 |
✅ IMPLEMENTED — post-validation pending |
SIEM QRadar → Sentinel Migration |
Lead role. Monad console error RESOLVED 2026-05-12 — secrets configured in CHLA production tenant. ISE secure syslog integration in progress — cert imported, remote logging target configured, streaming errors under investigation. Blocking: DCR not created (Rule ID + Stream Name). Azure private network policy unresolved. Victor + Mauricio action. |
2026-04-10 |
56 |
P0 - ACTIVE — ISE syslog + DCR blocking |
Monad Pipeline Evaluation |
Sentinel output connector. Console error resolved. 3 of 6 values configured. Remaining: Endpoint URL (have it), Rule ID + Stream Name (need DCR). ISE Remote Logging Target configured 2026-05-18 — TLS cert imported, secure syslog target created. Streaming errors in Monad console under investigation. |
2026-03-11 |
86 |
P0 - ACTIVE — ISE integration in progress |
Guest Redirect ACL |
Guest redirect ACL work needed. Related to Mandiant remediation findings. |
2026-05-12 |
24 |
P0 - TODO |
ISE Patch 10 (CVE-2026-20147 CVSS 9.9) |
ISE 3.2 Patch 10. Supersedes Patch 9. 61 days on a CVSS 9.9 — schedule maintenance window. Write CR if needed. |
2026-03-12 |
85 |
P0 - OVERDUE — schedule immediately |
k3s NAT verification |
NAT rule 170 for 10.42.0.0/16 pod network - test internet connectivity. 64 days — test this week or defer to Q3. |
2026-03-09 |
88 |
P0 - BLOCKING — TRIAGE: schedule or defer |
Wazuh indexer recovery |
Restart pod after NAT confirmed working - SIEM visibility blocked. Blocked by k3s NAT — cannot proceed until above resolved. |
2026-03-09 |
88 |
P0 - Blocked by k3s |
Strongline Gateway VLAN fix |
8 devices in wrong identity group (David Rukiza assigned) |
2026-03-16 |
81 |
P0 - TODO |
TCP Clocks deployment |
ISE identity group validation, query outputs, comms with team. Active d001 data Apr 22-23. |
2026-04-22 |
44 |
P0 - ACTIVE |
IoT Dr. Kim — recurring |
Sleep study devices (Apr 15-16), watches recurrence (Apr 22). 5 incident versions in d001. Validate iPSK enrollment. |
2026-04-15 |
51 |
P0 - RECURRING |
Murus Portae (WAF) — Phase 0 |
FMC cert expired, ACP returns zero rules. d001: zone map, architecture D2, FMC API reference, ops script. |
2026-04-16 |
50 |
P0 - INVESTIGATING |
Vocera EAP-TLS Supplicant Fix |
~10 phones failing 802.1X, missing supplicant config. 61 days — schedule with clinical engineering team. |
2026-03-12 |
85 |
P1 - TODO — schedule |
ISE MnT Messaging Service |
Enable "Use ISE Messaging Service for UDP syslogs delivery". 61 days — low risk, schedule with ISE Patch 10 maintenance window. |
2026-03-12 |
85 |
P2 - BUNDLE with Patch 10 |
| Professional backlog remains critical. Check Days column for priorities. |
BLOCKERS — Fix Immediately
| Task | Details | Origin | Days | Impact |
|---|---|---|---|---|
Z Fold 7 Termux |
gopass and SSH not working |
2026-03-10 |
58 |
BLOCKER — Cannot access passwords on mobile |
gopass v3 organization |
Inconsistent structure, poor key-value usage |
2026-03-20 |
48 |
Inefficient password management, no aggregation |
Git history scrub — sensitive personal terms |
Plaintext references to personal legal matters in committed worklogs (WRKLOG-2026-03-14, WRKLOG-2026-04-18). Forward-fixed but old commits still contain strings. Requires |
2026-04-22 |
15 |
SECURITY — sensitive terms in public git history |
Runbook: Git History Scrub (d000 Personal Terms)
Problem: Two committed worklogs contained plaintext references to personal legal matters. The files have been edited (forward-fix), but git history retains the original text in prior commits.
Affected commits: Any commit touching these files:
# Identify affected commits
git log --oneline -- \
docs/modules/ROOT/pages/2026/03/WRKLOG-2026-03-14.adoc \
docs/modules/ROOT/pages/2026/04/WRKLOG-2026-04-18.adoc
Scrub procedure:
# 1. BEFORE: Full backup of the repo
cp -a ~/atelier/_bibliotheca/domus-captures ~/atelier/_bibliotheca/domus-captures.bak
# 2. Install git-filter-repo (if not present)
# Arch: pacman -S git-filter-repo
# pip: pip install git-filter-repo
# 3. Create expressions file for replacement
cat > /tmp/scrub-expressions.txt << 'EXPR'
regex:(?i)divorce==[REDACTED]
regex:(?i)dissolutio(?!n\.adoc\.age)==[REDACTED-LEGAL]
regex:(?i)iliana==[REDACTED-NAME]
regex:(?i)angulo-arreola==[REDACTED-NAME]
regex:legal-divorce-notes\.age==legal-notes.age
regex:1099-NEC-iliana==1099-NEC
EXPR
# 4. Verify before (dry run — count matches in history)
git log -p --all -S 'divorce' -- '*.adoc' | grep -c 'divorce' || echo "0 matches"
git log -p --all -S 'iliana' -- '*.adoc' | grep -c 'iliana' || echo "0 matches"
# 5. Run filter-repo (DESTRUCTIVE — rewrites all commit hashes)
git filter-repo --replace-text /tmp/scrub-expressions.txt --force
# 6. Verify after
git log -p --all -S 'divorce' -- '*.adoc' | grep -c 'divorce' || echo "0 matches — CLEAN"
git log -p --all -S 'iliana' -- '*.adoc' | grep -c 'iliana' || echo "0 matches — CLEAN"
# 7. Re-add remotes (filter-repo removes them)
git remote add origin git@github.com:<user>/domus-captures.git
# Add any other remotes (Gitea, etc.)
# 8. Force-push to all remotes (DESTRUCTIVE — overwrites remote history)
git remote | xargs -I{} git push {} main --force
# 9. Clean up
rm /tmp/scrub-expressions.txt
rm -rf ~/atelier/_bibliotheca/domus-captures.bak # only after verifying
Post-scrub checklist:
-
Backup created before running
-
git filter-repoinstalled -
Expressions file reviewed — no false positives (e.g., Don Quijote "Angulo el Malo" is in
segunda-parte/texto/texto-011.adoc— the regex targetsangulo-arreolaspecifically to avoid this) -
Dry-run counts match expectations
-
Filter-repo executed
-
Post-scrub verification shows 0 matches
-
Remotes re-added
-
Force-pushed to all remotes
-
Cloudflare Pages rebuild verified
-
Local clones on other machines re-cloned or
git fetch --all && git reset --hard origin/main -
Backup removed
URGENT - Requires Immediate Action
| Item | Details | Deadline | Status | Impact |
|---|---|---|---|---|
Housing Search |
Granada Hills area - apartments/rooms |
TBD |
In Progress |
Quality of life, commute |
2025 Tax — IRS Transcript Review |
MFJ filed 2026-04-22. Pull IRS Return Transcript to verify contents. Consult attorney re: Form 8857 (Innocent Spouse Relief). Details in encrypted case file. |
Before attorney meeting |
In Progress |
Financial — liability exposure. See |
Rack Relocation |
Physical move of server rack. CR written: CR-2026-04-18 (pending in infra-ops). Borg backup completed. VM XML dumps, switch save, shutdown/startup procedure documented. |
TBD |
Pending |
Infrastructure downtime — all services offline during move |
D000 Legal Planning |
Encrypted case file: |
Before Jan 2029 |
Active — escalating |
Life transition — see case file for details |
Credit Report Review |
Pull reports from all 3 bureaus via annualcreditreport.com. Verify no unknown joint accounts or debts. Credentials in gopass: |
TBD |
In Progress |
Financial discovery — FL-142 preparation |
Gopass Security Audit |
Rotate passwords on shared/known accounts. Add 2FA backup codes to |
TBD |
Pending |
Digital security — pre-filing preparation |
Subscription Audit |
Download 3 months bank/CC statements (Chase, NFCU, USAA). Identify all recurring charges. Cancel unnecessary. Document active subscriptions for FL-150. |
TBD |
Pending |
Financial — expense documentation |
401(k) Enrollment |
Enroll in CHLA 401(k) immediately. Post-separation contributions are 100% separate property. Reduces gross income for support calculations. Max 2026: $23,500/yr. |
In progress (started 5/4) |
In Progress |
Financial — support calculation + retirement |
URGENT — Performance Review Certifications
| Certification | Provider | Deadline | Status | Impact |
|---|---|---|---|---|
CISSP |
ISC² — Certified Information Systems Security Professional |
July 12, 2026 |
ACTIVE — Week 2 of 10 (Project) |
Required for performance review. 10-week accelerated plan. |
RHCSA 9 |
Red Hat Certified System Administrator |
Q3 2026 |
ACTIVE — 21-phase curriculum (Project) |
After CISSP. Required for performance review. |
| CISSP: 41 days remaining (exam July 12). Domain 1 study in progress. Schedule exam today (06-01). |
Early Morning - 5:30am
Regex Training (CRITICAL CARRYOVER)
-
Session 3 - Character classes, word boundaries
-
Practice drills from regex-mastery curriculum
-
Status: 52 days carried over (since 2026-03-16) — CRITICAL
| Regex training continues to slip. This is the foundation for all CLI mastery. |
Daily Notes
Triage Status
| Item | Status | Destination |
|---|---|---|
Schedule CR implementation: Guest ACL Hardening (approved 06-02) |
Action needed |
Coordinate with Tony Sun (switch ACL) + David Rukiza (validation) |
Schedule CR implementation: Anonymous Identity Test (approved 06-02) |
Action needed |
Coordinate with Argam (AirWatch profile push) |
Tube System Re-run (iTrack 3528165) |
Carry-forward from 06-01 |
Scripts fixed, 15 MACs confirmed NOT IN ISE — re-run pending |
Alex Pena — ISE device verification |
Pending |
Run ERS API + DataConnect checks on his claimed device adds |
ISE Annual Cert Renewal — CSR generation |
Ready |
51 days to expiry (July 24). DigiCert CA. CSR config + commands in d001. |
Linux Inventory Discovery — run queries |
Pending |
SQL ready: |
Abnormal ESA→EOP Policy Review — follow-ups |
Active |
DKIM disabled (investigate), AutoForwarding On (fix), pilot→full org rollout |
Android Handheld Scanners — ISE policy for shared devices |
June 8 deadline (5 days) |
Argam needs MDM profile before vendor onsite. ISE auth/authz policy needed. |
ESA Message Trace — policy divergence investigation |
Active |
ESA-Bypass skipping blacklist/sender group enforcement |
Getwell iPads — iPSK onboard (Argam/Spectrum IoT) |
Done |
2 devices added to iPSK workflow. 4C:B9:10:9F:05:9F, C4:12:34:2D:F3:14 |
Monad Pipeline — weekly sync (William Cox) |
Meeting |
FMC/ISE kinks, add Cisco network sources, begin transforms |
ESA Mail Flow Policy Divergence — Five Canons Analysis
Dispositio
This investigation applies the Five Canons of rhetoric as an analytical framework — not for persuasion, but for structured technical reasoning.
I. Inventio (Discovery — What is observed)
Identical messages are handled differently by ESA depending on the mail path:
-
Standard ESA path → message blocked (blacklist / policy enforcement)
-
ESA-Bypass path → same message delivered
Both cases show:
-
Comparable sender IP
-
SBRS in gray range (~2.6)
-
No obvious content delta
The divergence is in policy application, not message content.
II. Dispositio (Arrangement — How the problem is structured)
| Phase | Method |
|---|---|
Data extraction |
ESA message tracking PDFs → |
Normalization |
Remove noise, align format → |
Signal isolation |
Policy, SBRS, sender group, action → |
Comparative analysis |
Diff between flows → |
This allows direct correlation of: listener → policy → sender group → action.
III. Elocutio (Style — High-signal output)
Output reduced to decision-determining fields only:
-
Sender IP — confirms same source
-
SBRS — Talos reputation score
-
Listener — ESA-Bypass vs standard
-
Mail Policy — which rule set applied
-
Sender Group — Trusted / Unknown / Blacklisted
-
Action / Verdict — Delivered vs Dropped
-
Blacklist hits
IV. Memoria (Reproducibility — Codified workflow)
The workflow is terminal-native and repeatable:
-
pdftotext→ extraction -
sed→ normalization -
grep→ signal filtering -
diff→ comparison -
Process substitution for one-liner execution
V. Pronuntiatio (Conclusion — What it means)
Findings:
-
ESA-Bypass omits enforcement present in standard ESA
-
Blacklist and sender group classification not applied in bypass path
-
SBRS alone does not explain delivery behavior
Implications for migration:
-
Aligning all listeners before ESA decommission is prerequisite
-
ESA-Bypass scope must be restricted to trusted/internal systems
-
This evidence supports the Abnormal policy review deliverable in d001
ESA Message Trace — Reproducible Workflow
Step 1 — Extract text from ESA PDFs
pdftotext "jv_esa_message_tracking_details (60).pdf" normal.txt
pdftotext "sc_bypassesa__message_tracking_details (61).pdf" bypass.txt
Step 2 — Normalize (remove noise)
sed -E '/^$/d;/^Page/d' normal.txt > normal.clean
sed -E '/^$/d;/^Page/d' bypass.txt > bypass.clean
Step 3 — Extract high-signal fields
grep -Ei 'Sender|IP|SBRS|Policy|Listener|Action|Verdict|Spam|Blacklist' normal.clean > normal.sig
grep -Ei 'Sender|IP|SBRS|Policy|Listener|Action|Verdict|Spam|Blacklist' bypass.clean > bypass.sig
Step 4 — Diff signal only
diff -u normal.sig bypass.sig
Step 5 — One-liner (process substitution — no temp files)
diff -u \
<(pdftotext "jv_esa_message_tracking_details (60).pdf" - \
| sed -E '/^$/d;/^Page/d' \
| grep -Ei 'IP|SBRS|Policy|Listener|Action|Verdict|Blacklist') \
<(pdftotext "sc_bypassesa__message_tracking_details (61).pdf" - \
| sed -E '/^$/d;/^Page/d' \
| grep -Ei 'IP|SBRS|Policy|Listener|Action|Verdict|Blacklist')
Process substitution <(cmd) creates virtual files from command output — no temp files, no cleanup. pdftotext … - outputs to stdout instead of a file. This is the pattern to reach for when comparing two command outputs.
|
Expected Finding
Normal ESA:
Listener : IncomingMail
Policy : Default
SenderGroup : Blacklisted
Action : Dropped
ESA-Bypass:
Listener : ESA-Bypass
Policy : BypassPolicy
SenderGroup : Unknown
Action : Delivered
Root Cause
ESA-Bypass is not enforcing:
-
Blacklists
-
Sender group classification
-
Anti-spam scanning
The standard ESA path applies these controls correctly. The divergence is in policy application, not message content or SBRS score.
Recommended Actions
-
Align blacklist and sender group enforcement across all listeners
-
Restrict ESA-Bypass scope to trusted/internal systems only
-
Validate before migration cutover — prerequisite for ESA decommission
Reuse Pattern
diff -u \
<(pdftotext "file-a.pdf" - | sed -E '/^$/d' | grep -Ei 'PATTERN') \
<(pdftotext "file-b.pdf" - | sed -E '/^$/d' | grep -Ei 'PATTERN')
diff <(command-a) <(command-b)
ISE Certificate — CSR Generation
ISE Certificate — Generate CSR Today
Expiry: July 24, 2026 (51 days)
CA: DigiCert (GeoTrust TLS RSA CA G1)
Current cert: CN=access2.ise.chla.org, SAN=*.ise.chla.org, 2048-bit
New cert: Same CN/SAN, upgrading to 4096-bit
Step 1 — Create config file
cat > /tmp/ise-cert-renewal.cnf << 'EOF'
[req]
default_bits = 4096
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[dn]
C = US
ST = California
L = Los Angeles
O = Childrens Hospital Los Angeles
OU = Information Security
CN = access2.ise.chla.org
[req_ext]
subjectAltName = @alt_names
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
[alt_names]
DNS.1 = access2.ise.chla.org
DNS.2 = *.ise.chla.org
EOF
Step 2 — Generate key + CSR
openssl genrsa -out /tmp/ise-cert-renewal.key 4096
openssl req -new \
-key /tmp/ise-cert-renewal.key \
-config /tmp/ise-cert-renewal.cnf \
-out /tmp/ise-cert-renewal.csr
Step 3 — VERIFY before submitting
# CN must be access2.ise.chla.org — NOT *.ise.chla.org
openssl req -in /tmp/ise-cert-renewal.csr -noout -subject -text | grep -E 'Subject:|DNS:'
Subject: C=US, ST=California, L=Los Angeles, O=Childrens Hospital Los Angeles, OU=Information Security, CN=access2.ise.chla.org
DNS:access2.ise.chla.org, DNS:*.ise.chla.org
If CN shows *.ise.chla.org — STOP. Delete and regenerate. Windows 802.1X will reject it (CSCuh22029).
|
Step 4 — Secure the private key
# Copy to d001 encrypted storage
cp /tmp/ise-cert-renewal.key data/d001/projects/ise-annual-cert-renewal/certs/ise-cert-renewal-2026.key
cp /tmp/ise-cert-renewal.csr data/d001/projects/ise-annual-cert-renewal/csr/ise-cert-renewal-2026.csr
# Encrypt the private key
rm -f data/d001/projects/ise-annual-cert-renewal/certs/ise-cert-renewal-2026.key.age
encrypt-file data/d001/projects/ise-annual-cert-renewal/certs/ise-cert-renewal-2026.key
# Clean up /tmp
rm -f /tmp/ise-cert-renewal.key /tmp/ise-cert-renewal.csr /tmp/ise-cert-renewal.cnf
# Verify
ls -la data/d001/projects/ise-annual-cert-renewal/certs/*.age
ls -la data/d001/projects/ise-annual-cert-renewal/csr/*.csr
Step 5 — Submit to DigiCert
-
CSR verified: CN =
access2.ise.chla.org, SAN =*.ise.chla.org -
Private key encrypted in d001
-
CSR submitted to DigiCert: method (portal / email)
-
Explicitly requested CA does NOT auto-add wildcard to CN
-
Expected turnaround: days
Results
-
CSR generated: yes/no
-
Verification passed: yes/no
-
Submitted to CA: date
-
Key secured in d001: yes/no
Monad Pipeline — Weekly Sync
Monad Pipeline — Weekly Sync
Date: 2026-06-03
From: William Cox (Teams)
Note: Will joined late — on DR call with Andrew and Sarah
Agenda (William’s priorities)
| Priority | Item | Status |
|---|---|---|
1 |
Resolving kinks with added log sources (FMC, ISE) |
Active |
2 |
Confirming we can add further sources (Cisco network sources) |
Pending validation |
3 |
Adding further log sources |
Planning |
4 (Important) |
Beginning transforms — flexing what Monad does for us |
Next phase |
Current Log Source Status
Based on existing documentation (partials/projects/monad-evaluation/log-sources.adoc):
| Source | Protocol | In Monad? | Kinks? |
|---|---|---|---|
ISE RADIUS (pPAN/sPAN, pMNT/sMNT, 4 PSNs) |
Syslog |
confirm |
William says kinks — what specifically? |
FMC / FTD Sensors |
Syslog |
confirm |
William says kinks — what specifically? |
Cisco Network (switches, routers, WLC) |
Syslog |
not yet |
Next to add per agenda item 2-3 |
ASA VPN |
Syslog |
confirm |
— |
Microsoft Defender / 365 |
Native API |
confirm |
— |
Questions to Capture During Meeting
-
What are the specific kinks with FMC log source? (parsing? connectivity? volume?)
-
What are the specific kinks with ISE log source? (which ISE services? RADIUS? TACACS? both?)
-
Which Cisco network sources are next? (switches first? WLC? routers?)
-
What transforms does William want to start with? (filtering low-value? OCSF normalization? enrichment?)
-
Is Sentinel receiving anything yet, or is everything still in staging?
-
DR discussion overlap — does DR affect Monad pipeline availability?
Transforms — What to Prepare
William flagged transforms as the next phase. Based on existing work (monad-sdk/ partials):
| Transform Type | What It Does |
|---|---|
Filtering |
Drop low-value logs before Sentinel ingestion → cost reduction |
Normalization (OCSF) |
Convert vendor-specific formats to Open Cybersecurity Schema Framework |
Enrichment |
Add context (GeoIP, threat intel, asset metadata) before storage |
Routing |
Critical → Sentinel (real-time), Bulk → Cold Storage (S3) |
Existing transform docs:
-
ISE transforms:
partials/projects/monad-sdk/ise-transforms.adoc -
FTD transforms:
partials/projects/monad-sdk/ftd-transforms.adoc -
jq patterns:
partials/projects/monad-sdk/jq-patterns.adoc -
Training:
pages/education/training/monad/transforms.adoc
API Key Management — Proposal
Monad will provide a shell script to create pipelines and add devices via API key. Security considerations:
| Concern | Mitigation |
|---|---|
Key at rest |
Encrypted with age. Never in plaintext on disk. Never committed to source control. |
Key at runtime |
Loaded into environment variable only: |
Key in script |
The vendor script must NOT hardcode the key. If it does, we rewrite it. |
Key rotation |
Establish rotation cadence with Monad. Scoped keys preferred — one per function, not one for everything. |
Key access |
Only our team. If Monad support needs access for troubleshooting, separate key with limited scope. |
Audit |
Log every API call. Key usage traceable to operator. |
# Key stored in gopass, loaded via dsource
dsource d001 dev/monad # loads MONAD_API_KEY
# Or age-encrypted one-off
MONAD_API_KEY=$(age -d -i ~/.age/identities \
data/d001/projects/monad-pipeline/certs/monad-api-key.txt.age)
export MONAD_API_KEY
# Script uses the var
./monad-create-pipeline.sh --source switches --key "$MONAD_API_KEY"
# Read every line first
less monad-pipeline-setup.sh
# Check what it calls
grep -E 'curl|wget|ssh|scp|eval|exec' monad-pipeline-setup.sh
# Check for hardcoded credentials
grep -Ei 'key|token|pass|secret|auth' monad-pipeline-setup.sh
# Check for external downloads
grep -Ei 'http|ftp|download|raw\.' monad-pipeline-setup.sh
# Check what it writes/modifies
grep -E '>/|>>|tee|mv|cp|rm|install' monad-pipeline-setup.sh
ASA Firewall — Add via Monad GUI
The ASA firewall log source needs to be added through the Monad web GUI, not the API script.
| Field | Value |
|---|---|
Source Type |
Syslog (ASA sends syslog natively) |
Source Name |
ASA-FW or org naming convention |
Source IP |
ASA management IP — confirm |
Protocol |
UDP 514 or TCP 514 (confirm with network team) |
Log Format |
Cisco ASA syslog (auto-detected by Monad) |
Destination |
Monad collector IP/port |
Expected Volume |
MEDIUM (VPN + firewall events) |
! On the ASA
logging enable
logging host <interface> <monad-collector-ip> udp/514
logging trap informational
logging device-id hostname
! Verify
show logging
| If the ASA is already forwarding syslog to QRadar, you may need to add Monad as a second destination during migration — don’t remove QRadar until Monad is validated. |
-
Does Monad auto-detect ASA syslog format?
-
Does Monad support dual syslog destinations (ASA → QRadar + Monad simultaneously)?
-
What Monad collector IP/port do we point the ASA to?
-
Is there a Monad parser specifically for ASA events (failover, VPN, ACL hits)?
My Action Items
| Action | Owner | Due |
|---|---|---|
Review Monad pipeline script when received — verify no hardcoded keys |
Evan |
When received |
Set up gopass/dsource entry for MONAD_API_KEY |
Evan |
Before first script run |
Add ASA firewall via Monad GUI |
Evan |
This week |
Test one switch pipeline before batch deployment |
Evan |
After script review |
EOP Anti-Spam Policy Review — BCL + SCL
EOP Anti-Spam Policy Review — BCL + SCL
BCL (Bulk Complaint Level) — Sender Reputation
BCL measures how "bulky" a sender is based on complaint rate across all O365 tenants. Microsoft assigns it per sender, not per message.
Lower threshold = MORE filtering (stricter). Higher = LESS filtering (lenient).
| BCL | What it means | Example senders |
|---|---|---|
0 |
Not bulk — regular sender |
Direct person-to-person email |
1–3 |
Bulk, few complaints |
LinkedIn, DocuSign, Zoom, Microsoft notifications |
4–6 |
Bulk, mixed complaints — gray zone |
Marketing you may or may not want. Phishing hides here. |
7–9 |
Bulk, high complaints |
Unsolicited marketing, newsletter spam |
Current BCL Thresholds (from 06-02 audit)
| Policy | Threshold | Assessment |
|---|---|---|
Default |
7 |
Too lenient — only worst bulk filtered |
Test Policy |
7 |
Same — lenient |
Standard Preset |
6 |
Slightly stricter |
Abnormal Best Practices |
5 |
Recommended for healthcare |
Anti-Spam-Inb-CHLA |
7 |
Too lenient |
Team Discussion: BCL Threshold
The team wants to lower to 1. Impact analysis:
| Threshold | What gets quarantined | Operational impact |
|---|---|---|
5 (recommended) |
Phishing-disguised-as-bulk, gray-zone marketing |
Few false positives. Manageable. |
4 |
Above + some legit marketing |
Occasional false positive. Acceptable for healthcare. |
3 |
Above + most vendor newsletters |
Weekly user complaints. Frequent quarantine releases. |
1 (team proposal) |
Everything with BCL > 0 — nearly all bulk |
LinkedIn, DocuSign, Zoom, fax2mail, medical journals, vendor alerts, conference registrations, KidsX/AVIA executive emails, Cisco/Microsoft security advisories ALL quarantined. Help desk becomes email release desk. Hundreds of messages daily. |
Dispositio — What to say
Exordium:
«The threshold is a cutoff — anything at or above that number gets treated as spam. Lowering from 7 to 5 catches more, not less. Going to 1 quarantines everything that isn’t direct person-to-person.»
Confirmatio:
«At BCL 1, these get quarantined: LinkedIn, DocuSign, Zoom invitations, medical journal subscriptions, vendor security advisories, fax2mail, KidsX executive emails. Someone needs to review and release hundreds of quarantined messages daily.»
Peroratio:
«Let’s set to 5 today — Abnormal’s recommendation. Monitor one week. If phishing gets through at 5, tighten to 4. Validate each step. Going straight to 1 isn’t tightening security — it’s turning off bulk email.»
If they insist on 1:
«I need that decision in writing with an owner for the quarantine review queue.»
SCL (Spam Confidence Level) — Per-Message Score
SCL measures how "spammy" a specific message is based on content analysis. EOP assigns it per message.
| SCL | Meaning | What EOP does |
|---|---|---|
-1 |
Trusted — skip spam filtering |
Internal, safe senders, transport rule override |
0 |
Not spam — clean |
Deliver |
1–4 |
Low confidence spam |
Deliver (usually) |
5–6 |
Spam |
Action from |
7–8 |
High confidence spam |
Action from |
9 |
Highest confidence |
Always quarantine/reject |
Current SCL Actions (from 06-02 audit) — THE BIGGER PROBLEM
| Policy | SpamAction (SCL 5-6) | HighConfSpamAction (SCL 7-8) | Assessment |
|---|---|---|---|
Default |
AddXHeader |
AddXHeader |
CRITICAL — does nothing. Spam delivered with invisible stamp. |
Test Policy |
Quarantine |
Quarantine |
Good — but scoped to test users only |
Standard Preset |
MoveToJmf |
Quarantine |
Good |
Abnormal Best Practices |
MoveToJmf |
MoveToJmf |
Good — but pilot group only |
Anti-Spam-Inb-CHLA |
Quarantine |
Quarantine |
Good — but check scope |
The Default policy uses AddXHeader for BOTH spam and high-confidence spam. This means anyone NOT in a scoped policy (Abnormal pilot, CHLA test, Standard Preset) receives no real spam filtering. Spam hits their inbox with a hidden header nobody sees.
|
What to tell the team about SCL
«We’re debating BCL thresholds for bulk marketing, but the Default anti-spam policy has a bigger gap. It uses AddXHeader for spam — that means spam gets delivered to inboxes with a stamp nobody can see. We need to change the Default to MoveToJmf for spam and Quarantine for high-confidence spam. Otherwise most users have no real spam protection.»
Recommended Changes
| Policy | Change | From → To | Priority |
|---|---|---|---|
All policies |
BulkThreshold |
7 → 5 |
P1 |
Default |
SpamAction |
AddXHeader → MoveToJmf |
P0 — critical |
Default |
HighConfidenceSpamAction |
AddXHeader → Quarantine |
P0 — critical |
Abnormal policies |
Scope |
Pilot group → full org |
P1 |
PowerShell — Verify and Change
Get-HostedContentFilterPolicy | Format-List Name, SpamAction, HighConfidenceSpamAction, BulkThreshold, BulkSpamAction
# Set-HostedContentFilterPolicy -Identity "Default" -SpamAction MoveToJmf -HighConfidenceSpamAction Quarantine
# Get-HostedContentFilterPolicy | Set-HostedContentFilterPolicy -BulkThreshold 5
Get-HostedContentFilterPolicy | Format-List Name, SpamAction, HighConfidenceSpamAction, BulkThreshold
The Set- commands are commented out. Uncomment and run only after team approval. These are production changes.
|
Monitoring After Changes
Get-QuarantineMessage -StartReceivedDate (Get-Date).AddDays(-1) -EndReceivedDate (Get-Date) |
Group-Object Type | Select-Object Name, Count | Format-Table -AutoSize
Get-QuarantineMessage -StartReceivedDate (Get-Date).AddDays(-1) -EndReceivedDate (Get-Date) |
Where-Object { $_.SenderAddress -match 'linkedin|docusign|zoom|cisco|microsoft|aamc' } |
Select-Object ReceivedTime, SenderAddress, Subject | Format-Table -AutoSize
Monad jq ↔ GJSON Translation Reference
jq ↔ GJSON — Translation Reference
The Workflow: Terminal First, GUI Second
| Step | What |
|---|---|
1. Capture raw log |
|
2. Prototype in terminal |
|
3. Translate to GJSON |
Use this reference to convert jq expressions to Monad GUI paths |
4. Deploy in Monad |
Apply via GUI (GJSON) or API (jq transform) |
5. Validate |
Compare Monad output against your jq output — must match |
Field Access
| Operation | jq (terminal) | GJSON (Monad GUI) |
|---|---|---|
Simple field |
|
|
Nested field |
|
|
Deep nested |
|
|
Array first element |
|
|
Array length |
|
|
Array last element |
|
|
All values of key in array |
|
|
Nested in array |
|
|
Filtering
| Operation | jq (terminal) | GJSON (Monad GUI) |
|---|---|---|
Equals |
|
|
Not equals |
|
|
Greater than |
|
|
Less than |
|
|
Pattern match |
|
|
Not pattern |
|
|
Multiple conditions |
|
No direct equivalent — use chained transforms or jq |
Transforms — jq to Monad GUI
| What | jq (prototype in terminal) | Monad GUI transform |
|---|---|---|
Drop low-value logs |
|
Type: |
Drop successful auths |
|
Type: |
Rename field |
|
Type: |
Add static field |
|
Type: |
Conditional tagging |
|
Type: |
Route by severity |
|
Requires jq transform (too complex for GJSON) |
Extract and flatten |
|
Requires jq transform (restructuring) |
OCSF normalization |
|
Requires jq transform (full restructuring + conditionals) |
When to Use Which
| Tool | Context | Use When |
|---|---|---|
jq (terminal) |
Prototype + validate |
Always start here. Test with real log data before deploying anything. |
GJSON (Monad GUI) |
Simple transforms in production |
Drop by field value, rename, add static field, simple conditionals. William and the team can see and modify these. |
jq (Monad API) |
Complex transforms in production |
Multi-condition routing, OCSF normalization, restructuring, MITRE tagging with logic. Only you will maintain these. |
Terminal Prototype Workflow
# From Monad pipeline logs, or capture directly
# Save as sample.json for testing
cat > /tmp/ise-sample.json << 'EOF'
{
"timestamp": "2026-06-03T10:30:00Z",
"severity": "high",
"event_type": "auth_failure",
"user": {"name": "jdoe", "domain": "CHLA"},
"endpoint": {"mac": "AA:BB:CC:DD:EE:FF", "ip": "10.50.10.100"},
"ise": {
"policy_set": "Wired_802.1X_Closed",
"auth_result": "FAILED",
"failure_reason": "Certificate validation failed"
}
}
EOF
# Filter: only failures
jq 'select(.ise.auth_result == "FAILED")' /tmp/ise-sample.json
# Add routing tag
jq '. + {"route": "sentinel", "mitre": "T1078"}' /tmp/ise-sample.json
# Flatten for Sentinel
jq '{
user: .user.name,
ip: .endpoint.ip,
mac: .endpoint.mac,
result: .ise.auth_result,
reason: .ise.failure_reason,
policy: .ise.policy_set,
time: .timestamp,
route: "sentinel"
}' /tmp/ise-sample.json
# OCSF normalize
jq '{
class_uid: 3002,
activity_id: 2,
actor: {user: {name: .user.name, domain: .user.domain}},
src_endpoint: {ip: .endpoint.ip, mac: .endpoint.mac},
severity_id: 3,
status_id: 2,
message: .ise.failure_reason,
time: .timestamp
}' /tmp/ise-sample.json
# Your jq output
jq '<transform>' /tmp/ise-sample.json > /tmp/expected.json
# Monad's output (from pipeline logs)
cat /tmp/monad-output.json > /tmp/actual.json
# Diff
diff <(jq -S '.' /tmp/expected.json) <(jq -S '.' /tmp/actual.json)
ASA-Specific Transforms (for the firewall log source)
# ASA syslog → structured JSON (what Monad receives)
# Example raw ASA syslog:
# %ASA-6-302013: Built inbound TCP connection 12345 for inside:10.1.1.50/45678 to outside:8.8.8.8/443
# jq transform for ASA connection logs
jq '{
action: (if .message | test("Built") then "allow" elif .message | test("Teardown") then "close" else "deny" end),
src_ip: (.message | capture("for \\w+:(?<ip>[\\d.]+)") | .ip),
dst_ip: (.message | capture("to \\w+:(?<ip>[\\d.]+)") | .ip),
protocol: (if .message | test("TCP") then "tcp" elif .message | test("UDP") then "udp" else "other" end),
severity: .severity,
route: (if .severity == "critical" or .severity == "high" then "sentinel" else "s3" end)
}'
# Drop informational connection logs (high volume, low value)
jq 'select(.severity != "info" and .severity != "debug")'
# Keep only denied connections (security-relevant)
jq 'select(.message | test("Deny|denied|Drop|Teardown"))'
Getwell iPads — iPSK Onboard
Getwell iPads — iPSK Endpoint Onboard
Date: 2026-06-03 10:32 (Teams)
Requestor: Argam
Project: Getwell / Spectrum IoT
Policy: iPSK workflow
Status: Devices added
Request
Hey Evan,
I'm trying to onboard these as part of the Getwell/Spectrum project per Argam.
Not sure what ISE group to add them too
N54850 - H9HFFTGEQ1GG 4cb9109f059f
N56426 - F435M24LC3 c412342df314
Devices
| # | Asset | Serial | MAC |
|---|---|---|---|
1 |
N54850 |
H9HFFTGEQ1GG |
4C:B9:10:9F:05:9F |
2 |
N56426 |
F435M24LC3 |
C4:12:34:2D:F3:14 |
iPSK Workflow Entries
association: "Getwell iPads"
device-mac: "4C:B9:10:9F:05:9F"
description: "2026-06-03 10:37 - Per Argam request, Getwell Spectrum IoT Project"
fullname: "getwell-ipads"
email: "getwell-ipads.chla.usc.edu"
association: "Getwell iPads"
device-mac: "C4:12:34:2D:F3:14"
description: "2026-06-03 10:37 - Per Argam request, Getwell Spectrum IoT Project"
fullname: "getwell-ipads"
email: "getwell-ipads.chla.usc.edu"
Verification
dsource d001 dev/network/ise
curl -sk "https://$ISE_PAN_FQDN:$ISE_ERS_PORT/ers/config/endpoint?filter=mac.EQ.4C:B9:10:9F:05:9F" \
-u "$ISE_API_USER:$ISE_API_PASS" \
-H "Accept: application/json" | jq '.SearchResult.total'
curl -sk "https://$ISE_PAN_FQDN:$ISE_ERS_PORT/ers/config/endpoint?filter=mac.EQ.C4:12:34:2D:F3:14" \
-u "$ISE_API_USER:$ISE_API_PASS" \
-H "Accept: application/json" | jq '.SearchResult.total'
cat > /tmp/getwell-macs.txt << 'EOF'
4C:B9:10:9F:05:9F
C4:12:34:2D:F3:14
EOF
source scripts/ise-check-macs.sh /tmp/getwell-macs.txt
Notes
-
iPSK workflow — pre-shared key per device based on MAC, no 802.1X
-
Target: Getwell patient entertainment iPads on IoT VLAN
-
Verify with Argam that devices are also enrolled in Intune/MDM
-
Both devices need correct VLAN assignment after authentication
Terminal Commands and Tools
File Discovery + Inspection Workflow
Find → Open in nvim
# Command substitution — open first match
nvim $(find docs/ -name '*2026-06-03*' -type f | head -1)
# Open ALL matches in one nvim session (buffers)
nvim $(find docs/ -name '*2026-06-03*' -type f)
# -exec + variant — opens all in one nvim
find docs/ -name '*2026-06-03*' -type f -exec nvim {} +
# Safe (handles spaces in filenames)
find docs/ -name '*2026-06-03*' -type f -print0 | xargs -0 nvim
Grep → Open results in nvim
# Find files containing a term, open all in nvim
grep -Rl --include='*.adoc' 'cert.*auth' . | xargs nvim
# With line numbers
grep -Rn --include='*.adoc' 'Client Authentication' . | head -20
Content Inspection (without opening)
# Structure map — all section headers
grep -n '^=\+ ' file.adoc
# Dependency map — all includes
grep -n 'include::' file.adoc
# Uniqueness check (before sed)
grep -c 'pattern' file.adoc
# Context around a match
grep -n -B3 -A3 'pattern' file.adoc
# View specific line range
awk 'NR>=42 && NR<=92' file.adoc
# Count matches per file across repo
grep -Rn --include='*.adoc' 'cert' . \
| awk -F: '{count[$1]++} END {for (f in count) print count[f], f}' \
| sort -nr
Process Substitution (compare without temp files)
# Compare two command outputs
diff <(command-a) <(command-b)
# Compare two PDFs
diff -u \
<(pdftotext "file-a.pdf" - | grep -Ei 'PATTERN') \
<(pdftotext "file-b.pdf" - | grep -Ei 'PATTERN')
# Compare two API responses
diff <(curl -s url-a | jq '.') <(curl -s url-b | jq '.')
d000 / d001 Shortcuts
d000 LECTURA-PRIMEROS-PASOS # fuzzy open
d000 build p1-cap-038-notas pdf --theme dark # build
d001 open okta-to-entra # decrypt
d001 build ise-cert-renewal-procedure pdf --theme navy
d001 close okta-to-entra # encrypt + stage
Pipeline: Find → Filter → Extract → Act
# General pattern
find <where> -name '<what>' -type f |
xargs grep -Il '<content>' |
xargs nvim
# Concrete: ISE cert files → open in nvim
find . -name '*.adoc' -type f |
xargs grep -Il 'cert.*ISE\|ISE.*cert' |
xargs nvim
Git — Undo a Commit Without Losing Work
Existing codex: partial$codex/git/git-quick-reference.adoc (§ Undoing Things, lines 145–163)
This partial adds the verify pattern and explains what each level preserves.
Three levels of undo
| Command | Files become | Use when |
|---|---|---|
|
Staged (green in |
Wrong commit message, want to re-commit differently |
|
Modified but unstaged (red in |
Want to rearrange what gets committed |
|
Modified + new files return to untracked |
Want to go back to before |
git reset --hard HEAD~1 destroys changes from disk. Never use unless you mean it.
|
Verify-before / change / verify-after
# Before — confirm what the last commit contains
git log --oneline -3
git show --stat HEAD
# Change — undo the commit
git reset HEAD~1
# After — files are back to modified/untracked
git status
# ~1 = one commit, ~2 = two commits, ~3 = three, etc.
git reset HEAD~2
# The commit is NOT gone — git reflog shows every HEAD position
git reflog | head -5
# Recover an undone commit by its hash
git cherry-pick <hash>
How to find this partial
# By keyword — from anywhere in the repo
grep -rl 'undo.*commit\|reset.*HEAD' docs/modules/ROOT/partials/ --include='*.adoc'
# By filename
find docs/modules/ROOT/partials/worklog -name '*git-undo*'
# In the codex (existing terse version)
grep -n 'reset.*HEAD' docs/modules/ROOT/partials/codex/git/git-quick-reference.adoc
JSONL + jq — Practical Workflows
Existing codex references:
-
partial$codex/json-yaml/jq/files.adoc— file ops, validate, merge, JSONL basics -
partial$codex/json-yaml/jq/advanced.adoc— --arg, regex, streaming, recursive descent -
data/d000/…/quijote-study/partials/jsonl-search-methodology.adoc— Claude Code session search (7-step)
This partial adds the daily-use patterns for work and personal contexts.
What is JSONL?
One JSON object per line. No wrapping array. Every line is independently parseable.
{"id":1,"name":"alpha","status":"active"}
{"id":2,"name":"beta","status":"inactive"}
{"id":3,"name":"gamma","status":"active"}
Why it matters: log files, API streams, Claude Code sessions, Monad pipeline output, Sentinel query results — all use JSONL. It’s the lingua franca between JSON tools and line-oriented Unix tools.
Core pattern: grep prefilter → jq refine
# grep is fast on raw text — prefilter BEFORE jq parses
grep 'search-term' data.jsonl | jq '{name: .name, status: .status}'
grep scans at disk speed. jq parses JSON. Combining them: grep narrows to relevant lines, jq extracts structure. Never run jq on a 500MB file without grep first.
Extract fields from JSONL
jq -r '{name: .name, ip: .ip}' devices.jsonl
jq -r '[.name, .status, .ip] | @tsv' devices.jsonl
jq -r '[.name, .status, .ip] | @csv' devices.jsonl
Filter JSONL
jq 'select(.status == "active")' devices.jsonl
jq 'select(.status == "active" and .vlan == 10)' devices.jsonl
jq 'select(.name | test("^ise-"))' devices.jsonl
jq 'select(.status != "inactive")' devices.jsonl
Aggregate JSONL
jq -s 'length' data.jsonl
jq -s 'group_by(.status) | map({status: .[0].status, count: length})' data.jsonl
jq -r '.status' data.jsonl | sort -u
jq -s 'map(.bytes) | add' traffic.jsonl
Transform between formats
jq -c '.[]' array.json > output.jsonl
jq -s '.' input.jsonl > array.json
jq -r '[.name, .status] | @tsv' data.jsonl | awk -F'\t' '{printf "%-20s %s\n", $1, $2}'
Claude Code sessions — quick commands
# Where are my sessions?
ls ~/.claude/projects/-home-evanusmodestus-atelier--bibliotheca-domus-captures/*.jsonl | wc -l
# Find sessions mentioning a topic
grep -rli 'atributos\|protocolo' \
~/.claude/projects/-home-evanusmodestus-atelier--bibliotheca-domus-captures/ \
--include='*.jsonl' | grep -v '/subagents/'
# Extract my messages from a session
grep '"role":"user"' <session>.jsonl | jq -r '
.message.content |
if type == "array" then
map(select(.type == "text") | .text) | join(" ")
elif type == "string" then .
else empty end
' 2>/dev/null | awk 'NF && length > 10' | head -20
Full methodology: d000 quijote-study → partials/jsonl-search-methodology.adoc
Work contexts — ISE, Monad, Sentinel
curl -sk https://ise-01/ers/config/endpoint \
-H 'Accept: application/json' -u admin:pass | \
jq -r '.SearchResult.resources[] | [.name, .id] | @tsv'
jq 'select(.source == "ise")' pipeline-output.jsonl | jq -r '.mac'
jq -r '.[] | [.TimeGenerated, .Computer, .EventID] | @tsv' sentinel-results.json
How to find this partial later
grep -rl 'jsonl.*jq\|jq.*jsonl\|JSONL' docs/modules/ROOT/partials/ --include='*.adoc'
Education — Evening Sessions
Cicerón — De Inventione
Started: 2026-06-03 (late night / early morning)
Guide: d000 LECTURA-PRIMEROS-PASOS
Key passage: prólogo, líneas 42–92 — elocuencia + sabiduría
Connection: The Five Canons applied to ESA investigation above — inventio through pronuntiatio as technical analysis framework.
Don Quijote — Lectura del día
Capítulo: XXXVIII (tercera lectura) / XXXIX (inicio del Cautivo)
Build: d000 build p1-cap-038-notas html --variant catppuccin
Custom roles: .cervantes, .retorica, .testimonio, .teologia, .gramatica, .ironia, .pregunta
Lo que leí hoy
Escribe en español.
Vocabulario nuevo
| Palabra | Definición | Ejemplo en contexto |
|---|---|---|
palabra |
definición |
cita del texto |
Conexiones con Cicerón
De Inventione, prólogo (líneas 42–92) — ¿qué conecta con lo que leíste hoy?
Notas para SIELE/DELE
-
Registro formal observado:
-
Estructura sintáctica compleja:
AsciiDoc Inline Emphasis — Marking Words for Study
Reference for highlighting, annotating, and visually distinguishing words and phrases in reading notes.
Core emphasis — single characters
| Syntax | Renders as | Use for |
|---|---|---|
|
bold |
Key terms, vocabulary words, first occurrence of a concept |
|
italic |
Foreign words, titles, Spanish phrases in English prose |
|
bold italic |
Maximum weight — thesis statements, critical terms |
|
|
Commands, code, literal strings, grammatical forms like |
Highlight and mark — visual emphasis
| Syntax | Renders as | Use for |
|---|---|---|
|
highlighted |
Yellow background mark — words to study, vocabulary to memorize |
|
Pass-through for role application |
Required when combining roles with marks (see custom roles below) |
|
underlined |
Structural emphasis — topic sentences, key phrases in long passages |
|
struck |
Corrections, superseded translations, wrong-then-right pattern |
Size modifiers
| Syntax | Renders as | Use for |
|---|---|---|
|
larger text |
Section labels, visual hierarchy without headings |
|
smaller text |
Meta-commentary, grammar labels, register notes under annotations |
|
superscript |
Footnote markers, edition numbers, century indicators (XVIIe) |
|
subscript |
Chemical formulas, phonetic notation |
Combining roles — the power syntax
Single requires unique text. Double # allows role application to any span.
The word *#garbeare#* is a subjuntivo futuro — extinct in modern Spanish.
Renders: The word garbeare is a subjuntivo futuro — extinct in modern Spanish.
[.underline]##_effictio_## is the rhetorical term for a head-to-toe physical description.
Renders: effictio is the rhetorical term for a head-to-toe physical description.
está *atenido* a la miseria de su paga:::
_Dependiente de._ Su vida entera cuelga de un salario que no controla. +
[.small]##Dativo de interés · B2 · «atenerse a» = depender de##
[.line-through]#«puesto que» = because# → «puesto que» = *although* (Siglo de Oro concessive)
Renders: «puesto que» = because → «puesto que» = although (Siglo de Oro concessive)
Custom literary roles (from domus-asciidoc-build)
These require the Catppuccin variant CSS (--variant catppuccin or --theme don-quijote).
| Role | Color / Icon | Purpose |
|---|---|---|
|
Mauve / pencil |
Autobiographical voice — author behind character |
|
Blue / balance scale |
Rhetorical figures, dispositio, persuasion |
|
Teal / shield |
Personal experience, military testimony |
|
Gold / book |
Moral/theological reading, sacred layer |
|
Green / graduation cap |
Siglo de Oro syntax, archaisms, extinct forms |
|
Peach / exclamation |
Cervantine humor, double meaning |
|
Pink / question circle |
Open questions, unresolved threads |
[.gramatica]
.Subjuntivo futuro — forma extinta
****
«Garbeare» es subjuntivo futuro de «garbear». Hoy diríamos «lo que pueda robar».
****
Practical patterns for Quijote annotations
un *#coleto acuchillado#* le sirve de gala
*garbeare*::: _robar, saquear_ +
[.small]##subjuntivo futuro · forma extinta · C2##
[.underline]##Epizeuxis## — «sí, sí» — repetición inmediata como acto performativo.
*atenido a* — dependiente de ^B2^
*garbeare* — futuro de subjuntivo de _garbear_ ^C2^
*coleto acuchillado* — chaleco de cuero con cortes ^C1^
See xref:education/programming/rust/asciidoc-notes-syntax.adoc[AsciiDoc Notes Syntax] for the complete formatting reference.
Quijote XXXVII — Texto Anotado + Atributos System
Created: p1-cap-037-texto-anotado.adoc — full chapter with custom study marks across all 29 sections.
Atributos file: atributos-quijote.adoc — single source of truth for the entire Quijote study. 11 categories, included with one line in any chapter file.
What was built:
-
p1-cap-037-texto-anotado.adoc— full chapter text with ~90 vocabulary items (bold highlight+ CEFR), ~20 archaic forms (bold italic), ~15 grammar annotations (), ~20 rhetorical structures (monospaceunderline) -
atributos-quijote.adoc— reusable attributes file: protocol marks, CEFR levels, grammar labels, rhetorical figures, dispositio, characters, biblical references, Arabic etymologies, chapter navigation -
protocolo-marcas.adoc— Antora partial + d000 standalone: the 5-level study annotation system (Dubium → Quaestio → Placet → Delectat → Mirabile) -
protocolo-lectura.adoc— full protocol contract: what each mark means, how to use it, how the professor responds
Attribute system — how it works:
AsciiDoc attributes are key-value pairs defined once and substituted everywhere at build time.
// In atributos-quijote.adoc (definition):
:mark-d: ❓
:subj-fut: [.small]##subjuntivo futuro · forma extinta##
:c2: ^C2^
:ar-burgi: [.small]##del árabe burġī — bota alta##
// In any texto-anotado (usage):
pagalle:: {mark-d}
`quisiere` {subj-fut}
*#borceguíes#* {c2} {ar-burgi}
The same mechanism as {ise-01-ip} → 10.50.1.20 in infrastructure docs. Attributes don’t care what the value is — text, emoji, IP address, rhetorical label.
Live workflow:
Terminal 1 |
|
Terminal 2 |
|
Browser |
|
Watch mode fix: inotifywait -e modify broke after first save because nvim writes via temp-file-then-rename (inode changes). Fixed to watch the directory for close_write,moved_to events. Committed to domus-asciidoc-build.
First marks test — §2 (prueba):
| pagalle |
❓ ❓ |
| jubilaba |
❔ ❔ |
| era el afligido, el desventurado y el triste |
🌟 🌟 |
All attributes resolved. Marks render correctly in browser.
Violin
Evening session: Gavotte — J. Becker. 1 hour.
Scales, left hand technique, bowings.
Don Quijote — Lectura
Evening session: 30 min so far — re-reading Caps. XXXVII + XXXVIII.
Continuing through both chapters tonight.
Discovery — Wayland Screenshots
grim for full screen, grim -g "$(slurp)" for region select. Install: sudo pacman -S grim slurp.
Work (CHLA)
| CHARGE TIME IN PEOPLESOFT - CRITICAL. Do this NOW before anything else. |
Critical (P0)
| Project | Description | Owner | Status | Due | Blocker |
|---|---|---|---|---|---|
Linux Research (Xianming Ding) |
EAP-TLS for Linux workstations, dACL, UFW |
Evan |
BEHIND (72 days overdue) |
02-24 |
Certificate "password required" - nmcli fix documented |
iPSK Manager |
Pre-shared key automation |
Ben Castillo |
BEHIND |
— |
DB replication issues |
MSCHAPv2 Migration |
Legacy auth deprecation — 6,227 devices, 5 waves. 6 batch SQL queries + 3-API endpoint profile script added (05-11). Report due. |
Evan |
25% — Report due, batch queries ready |
05-30 |
Report to turn in |
Research Segmentation |
All endpoints to Untrusted VLAN |
Evan |
BLOCKED |
— |
CISO decision pending |
Disaster Recovery |
ISE DR scoping — dot1x closed mode = total blackout |
Evan |
Scoping |
— |
— |
Mandiant Remediation |
Copy 4/16 findings, Guest ACL lab, Q2 assessment |
Evan |
Active |
— |
— |
SIEM QRadar → Sentinel |
Full SIEM platform transition. Monad console error resolved 05-12. Secrets configured. Blocked on DCR creation (Rule ID + Stream Name). Azure private network policy unresolved. |
Evan |
Active — blocked on DCR |
Q2 2026 |
Victor/Mauricio: create DCR, resolve Azure network policy |
Abnormal Security |
AI email platform — ESA cutover. CR assigned, CAB May 12 15:00. Implementation May 14 10:00. |
Evan |
Active — CAB today 15:00 |
05-14 |
Pre-CAB checklist: confirm Tyler, Jason, Sarah |
High Priority (P1)
| Project | Description | Owner | Status | Target |
|---|---|---|---|---|
ISE 3.4 Migration |
Upgrade from 3.2p9 |
Evan |
Blocked — maintenance window needed |
Q2 2026 |
Switch Upgrades |
IOS-XE fleet update (C9300, 3560CX) |
Evan |
Pending |
Q2 2026 |
Spikewell BYOD VPN |
dACL SQL, AD group integration |
Evan |
Active |
— |
Strongline Gateway |
MAC capture, Identity Group setup — 37 days aging |
Evan |
Active — David Rukiza assigned |
— |
Abnormal Security |
AI email security platform research, ESA cutover timeline |
Evan |
Newly assigned |
— |
DMZ Migration |
External services audit behind NetScaler |
Evan |
Audit phase |
— |
Firewall Audit (murus-portae) |
EtherChannel query, prefilter, policy assignments |
Evan |
Scoping — ASA API creds needed |
— |
iPSK Manager HA |
Server 2 config, TLS, SQL security audit |
Evan |
In progress |
— |
Sentinel KQL |
Build proficiency, distinguish from team |
Evan |
Onboarding |
— |
VNC Blocking |
Block and eliminate VNC protocol enterprise-wide |
Evan |
Active — Phase 0 (Discovery) |
Mid-June 2026 |
Strategic (P2)
| Project | Description | Owner | Status |
|---|---|---|---|
HHS Regulatory Compliance |
New HHS security policies implementation |
TBD |
NOT STARTED |
InfoSec Reporting Dashboard |
PowerBI metrics for executives |
TBD |
NOT STARTED |
EDR Migration (AMP → Defender) |
Endpoint protection consolidation |
TBD |
NOT STARTED |
Azure Legacy Migration |
Modern landing zone |
Team |
In Progress |
ChromeOS EAP-TLS |
SCEP + Victor, Paul testing |
Victor |
In Progress |
P0 — Critical / Blocking
Security & Compliance
-
ISE 3.2 Patch 10 upgrade — CVE-2026-20147 CVSS 9.9 / CVE-2026-20148. Propose maintenance window once patch confirmed on software.cisco.com.
-
ISE Advisory sa-ise-rce-traversal-8bYndVrZ — check Patch 10 availability
-
Mandiant Remediation — findings status tracked. Working session prep + defensive posture documented (comms-2026-04-24). Copy 4/16 updates into Excel at work. Guest ACL lockdown (WIR-M-01) pending lab validation. appendix-todos updated with MSCHAPv2 milestones.
-
Guest ACL update — guest redirect ACL work needed. Lab validate GUEST_CWA_REDIRECT_MAX_SECURITY in d000, then joint CR with NE. On today’s task list.
-
Disaster Recovery & Downtime Procedures — ISE top priority (dot1x closed mode = SPOF for network access)
-
ISE DR: Document failover sequence — PAN, MnT, PSN priority order
-
ISE DR: RADIUS dead-server detection on WLCs/switches — critical-auth VLAN fallback
-
ISE DR: Backup/restore procedures — scheduled config backups, tested restores
-
FTD/FMC DR: FMC loss = no policy management
-
Network DR: Core/distribution switch failure, STP reconvergence, HSRP failover
-
Document RTO/RPO per system
-
SIEM Migration (QRadar → Sentinel)
-
SIEM QRadar → Sentinel Migration — LEAD ROLE. 4 collection iterations (Apr 16, 17, 17-streamlined, 20-streamlined). Python chart pipeline built (
qradar-charts.py). Migration XLSX generated. Verification pending. Comms sent Apr 23.-
d001 artifacts: 8 JSON exports, 2 CSV inventories, migration XLSX, top5 source SVG/PNG, verification doc
-
Dependency: Monad pipeline for log source transition
-
Dependency: Sentinel KQL proficiency for query migration
-
-
Monad Pipeline Evaluation (origin: 2026-03-11) — lead role. Console error RESOLVED 05-12 — secrets configured in CHLA production tenant. Blocked on DCR creation (Rule ID + Stream Name). Azure private network policy unresolved. 10am call today 05-12.
-
Sentinel KQL — build proficiency, distinguish from team. Azure portal access acquired.
-
QRadar log source report — run AQL queries, fetch JSON, generate Python Excel
Active Deployments & Migrations
-
MSCHAPv2 Migration — Report due. 6-sheet Standard Report ready (Sheet 6: policy match by protocol added 05-14 for removal planning + anonymous identity validation on cert profiles). Migration window 5/4 – 5/30. 6,227 MSCHAPv2 devices, 14,249 EAP-TLS/TEAP (70% migrated). Focus: run Standard Report, turn in spreadsheet.
-
MSCHAPv2 weekly cadence — recurring Wednesday call established (first 04-22). Completed 2026-04-22.
-
MSCHAPv2 ownership matrix — sent in scoping email 4/24 with manager callouts (@Albert, @John). Completed 2026-04-24.
-
TCP Clocks deployment — new device added via ERS POST and confirmed (04-24). 7+ clocks validated. v2 query file with partials architecture. Revalidate full set — confirm no flapping.
-
SRT Research VLAN — confirm roles with Tony Sun: Tony implementor, Evan tester. CAB approved 04-21.
-
Downtime Computers enforcement — draft ISE AuthZ rule: medigate_724 + Wireless = DenyAccess. Separate CR. d001: DC queries, audit CSVs (v1-v3), wireless violations report delivered 04-21.
-
Enterprise Linux 802.1X — standardize Shahab/Ding deployment (CISO priority). Overdue since 02-24. Blocked by nmcli cert fix.
-
Abnormal Security — CR-2026-05-07-abnormal-read-write. CAB 05-12 approved, implementation 05-14. Jason Landeros implements, Evan presents. 06-01 update: Review Jihad’s policy mapping XLSX + Tyler’s Policy and Rules Migration doc before next call. Plan email migration expansion beyond security group to full environment — priority to move off ESA. Exchange rule considerations: external sender disclaimer (sender not company, outside org, not internal IP → prepend disclaimer).
-
Team: Cox/William, Landeros/Jason, Rosado/Evan, Naranjo/Mauricio, Sandoval/Carlos
-
Tube System Upgrade (NEW — 06-01)
-
Tube System Upgrade — iTrack 3528165. 15x 10" TS stations need MAC addresses added to ISE identity group IoT_Onboard. MACs received from vendor (C8:1A:FE:20:xx:xx series). Station list spans ICU (CTICU, PICU, BMT, NICU, NICCU), ED, Surgery, Trauma, Pharmacy. Vendor contact: John Genest. Rationale: manufacturer no longer supports current system; failure risks delayed/missed patient care.
BMS Device Inventory (NEW — 04-24)
-
BMS Device Inventory — 72 devices discovered across 37 switches (04-24). Profile-driven architecture (Claroty/Medigate). 16 queries built. Phase 0 complete. Next: cross-reference with Visio diagrams, classify by function, begin D2 diagrams. Cleanup: delete 4 orphaned test groups, migrate 4 retire-dACL devices, investigate 3 null-profile devices.
VNC Blocking (NEW — 05-11)
-
VNC Blocking — block and eliminate VNC enterprise-wide. Due mid-June 2026. Phase 0: discovery. January AQL query baseline to incorporate. Cross-reference BMS inventory for VNC-capable devices.
Investigations & Audits
-
Murus Portae (WAF) — Phase 0 discovery in progress. FMC cert expired. d001: DMZ NetScaler WAF investigation, zone map, architecture D2 diagrams (v1+v2 SVGs), FMC REST API reference guide, ops script. FMC API returning zero ACP rules — under investigation.
-
Firewall audit — FMC discovery inventory done (d001: fmc-discovery-2026-04-16). EtherChannel query, prefilter, policy assignments pending.
-
IoT Dr. Kim devices — RECURRING. All 4 MACs validated in IoT_iPSK_VLAN1620_Misc (04-24). v2 validation queries built with 7 deep analysis queries (group flapping, credential leakage, profile drift, NAS tracking, remediation timeline, deny audit, OUI scan). Revalidate — confirm no flapping since 04-24.
-
IoT device validation queries — v2 created with partials architecture, 16 queries across ERS/MnT/DataConnect/FMC. Completed 2026-04-24.
Stale Blockers (carried via carryover tracker)
-
k3s NAT verification — rule 170, 10.42.0.0/16 pod network (origin: 2026-03-09). 59 days. Blocks Wazuh indexer recovery → blocks SIEM visibility. Weekend task?
-
Strongline Gateway VLAN fix — 8 devices wrong identity group (origin: 2026-03-16). 52 days. David Rukiza assigned — follow up on status.
Administrative
-
PeopleSoft — track time for current week
-
iTrack tickets — close open tickets
-
KQL library — build initial queries in codex + d001
-
Linux Research project — finalize and review
-
Tax filing 2025 (MFJ) — see encrypted case file in
data/d000/personal/for details and action items
P1 — Important
-
MSCHAPv2 action-item tracker — owner/status/next-steps per workstream
-
ISE admin MFA enforcement — recommendation tied to advisory (interim control pending Patch 10)
-
DMZ Migration — external services audit behind NetScaler. Linked to Murus Portae investigation.
-
Vocera/Wyse iTrack RCA — complete root cause report
-
GCC ISE Support — 3/4 nodes restored, PSN-04 deferred
-
Wazuh indexer recovery — blocked by k3s NAT (origin: 2026-03-09)
-
Vocera EAP-TLS Supplicant Fix (origin: 2026-03-12)
-
iPSK Manager HA — blocked by DB replication (Ben Castillo)
-
ISE 3.4 Migration — depends on Patch 10 completion first
-
Git history scrub — murus-portae-output.md + ise-analytics CSVs
-
Encrypt
prep-cmds-2026-04-15.adoc— plaintext committed to git -
ISE MnT Messaging Service — enable UDP syslog delivery (maintenance window needed)
Infrastructure (Personal)
-
Borg backups — test and validate on ALL systems (Razer, P16g, vault-01, bind-01, kvm-01, kvm-02)
-
Borg — verify backup script paths updated from dotfiles-optimus to dots-quantum
-
Borg — create initial archive for ThinkPad P16g if none exists
-
Libvirt VLAN hook debug on both KVMs
-
Te1/0/2 cable replacement and re-test
-
Vault Raft cluster — verify vault-01 rejoined
-
Fix EAP-TLS keyring/secrets issue on Razer workstation
Completed (confirmed — do not delete, archive only)
-
CR-2026-04-15 SRT Research VLAN — submitted to iTrack. Completed 2026-04-15.
-
CAB presentation 4/21 — SRT Research VLAN 233 → CHLA-Research. APPROVED. Completed 2026-04-21.
-
Downtime Computers wireless audit — 45 computers, 16 violating, v3 report delivered. Completed 2026-04-21.
-
Git identity fix — dots-quantum/git/.gitconfig email corrected. Completed 2026-04-21.
-
MSCHAPv2 10:30 meeting — next steps + ACL coordination. Completed 2026-04-17.
Service Requests (SR)
| SR# | Request | Requestor | Opened | Status |
|---|---|---|---|---|
3508542 |
Zoll cards connection issue |
— |
— |
STALE — verify in iTrack |
3508524 |
Disable dot1x on (2) network ports - 5th floor 3250 Wilshire (PXE-boot imaging issues) |
— |
— |
STALE — verify in iTrack (issues persisted after disable) |
3528165 |
Tube System Upgrade — 15 stations, MAC addresses for ISE IoT_Onboard identity group |
Genest, John (vendor contact) |
2026-06-01 |
NEW — MACs received, need ISE onboarding |
Incidents (INC)
| INC# | Priority | Description | Opened | SLA | Status |
|---|---|---|---|---|---|
1911859 |
— |
Strongline Gateways in Miscellaneous Subnet |
— |
— |
STALE — verify in iTrack (related to carryover P0) |
Change Requests - Emergency (ECAB)
| CR# | Description | Opened | Scheduled | Status |
|---|---|---|---|---|
No emergency changes |
Change Requests - Normal
| CR# | Description | Opened | Scheduled | Status |
|---|---|---|---|---|
No normal changes |
Change Requests - Scheduled/Standard
| CR# | Description | Opened | Window | Status |
|---|---|---|---|---|
No scheduled changes |
Change Requests - Root Cause / Post-Incident
| CR# | Description | Related INC | Opened | Status |
|---|---|---|---|---|
100451 |
Vocera Phones and Wyse devices went off network |
— |
— |
STALE — verify in iTrack |
Session Accomplishments (Claude Code)
Day-specific accomplishments here.
Personal
In Progress
| Project | Description | Status | Notes |
|---|---|---|---|
k3s Platform |
Production k3s cluster on kvm-01 |
Active |
Prometheus, Grafana, Wazuh deployed |
Wazuh Archives |
Enable archives indexing in Filebeat |
Active |
PVC fix pending |
kvm-02 Hardware |
Supermicro B deployment |
Active |
Hardware ready, RAM upgrade done |
Planned
| Project | Description | Target | Blocked By |
|---|---|---|---|
Vault HA (3-node) |
vault-02, vault-03 on kvm-02 |
Q2 2026 (slipped from Q1) |
kvm-02 deployment |
k3s HA (3-node) |
Control plane HA |
Q2 2026 (slipped from Q1) |
kvm-02 deployment |
ArgoCD GitOps |
k3s GitOps deployment |
After k3s stable |
— |
MinIO S3 |
Object storage for k3s |
After ArgoCD |
— |
Personal asset management (YAML + CLI + AsciiDoc) |
Q2 2026 |
Schema approved |
Active — Infrastructure
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
Wazuh agent deployment |
Deploy agents to all infrastructure hosts |
P2 |
Pending |
After archives fix |
k3s Platform |
Production k3s cluster on kvm-01 |
P1 |
In Progress |
— |
Wazuh Archives |
Enable archives indexing in Filebeat, PVC fix |
P1 |
In Progress |
— |
kvm-02 Hardware |
Supermicro B deployment, RAM upgrade done |
P1 |
In Progress |
— |
Active — Security & Encryption
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
Configure 4th YubiKey |
SSH FIDO2 keys |
P1 |
TODO |
— |
Cold storage M-DISC backup |
age-encrypted archives |
P1 |
TODO |
After YubiKey setup |
Active — Development & Tools
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
netapi Commercialization |
Go CLI rewrite with Cobra-style argument discovery, package for distribution |
P0 |
Active |
— |
Ollama API Service |
FastAPI (17 endpoints), productize — config audit, doc tools, runbook gen |
P0 |
Active |
— |
Shell functions (fe, fec, fef) |
File hunting helpers |
P3 |
TODO |
— |
Active — Documentation
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
D2 Catppuccin Mocha styling |
domus-* spoke repos (177 files total) |
P3 |
In Progress |
— |
Active — Financial
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
Amazon order history import |
Download CSV from Privacy Central → parse with awk → populate subscriptions tracker |
P1 |
Waiting |
Pending Amazon data export (requested 2026-04-04) |
Active — Education
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
No active education tasks — see education trackers |
Active — Personal & Life Admin
| Task | Details | Priority | Status | Due |
|---|---|---|---|---|
ThinkPad T16g Setup |
Arch install, stow dotfiles, Ollama stack, netapi dev env |
P0 |
Pending |
— |
P50 Arch to Ubuntu migration |
P2 |
In Progress |
— |
|
X1 Carbon Ubuntu installs |
2 laptops, LUKS encryption |
P2 |
In Progress |
— |
P50 Steam Test |
Test Flatpak Steam + apt cleanup of broken i386 packages |
P3 |
Pending |
— |
Documentation Sites
-
docs.domusdigitalis.dev - Private documentation hub
-
docs.architectus.dev - Public portfolio site
Education
Claude Code Mastery
| Resource | Details | Progress | Status |
|---|---|---|---|
Claude Code Full Course (4 hrs) |
Nick Saraev - YouTube comprehensive course |
26:49 / 4:00:00 |
IN PROGRESS |
Claude Code Certification |
Anthropic official certification (newly released) |
Not started |
GOAL |
Active Tracks (Focus)
-
Don Quijote - Primera Parte
Skills Mastery (Critical)
-
Regex Mastery - 10-module curriculum
-
AsciiDoc Docs - Documentation format
-
Antora Docs - Documentation pipeline
Certification Deadlines
-
CISSP - July 12, 2026 (10-week plan active — Week 1)
-
RHCSA 9 - Q3 2026 (after CISSP)
-
LPIC-1 - Renewal required (blocks LPIC-2)
Spanish C1 Certification Goals
| Certification | Provider | Target | Status | Strategy |
|---|---|---|---|---|
Instituto Cervantes / UNAM / Salamanca |
Q2 2026 |
ACTIVE |
Computer-based, faster results - take FIRST |
|
Q3/Q4 2026 |
PLANNED |
After SIELE success, harder exam |
||
2027 |
FUTURE |
Mastery level - requires extensive immersion |
| SIELE is computer-adaptive, results in 3 weeks. DELE is paper-based, results in 3-4 months. Do SIELE first to validate readiness. |
Don Quijote Writing Practice - DELE C1/C2 Initiative
Method:
-
Read chapter in original Spanish
-
Write personal analysis/understanding en espanol
-
AI review for grammar, vocabulary, register
-
Build comprehensive understanding of literary elements
Today’s Study
-
Focus: CISSP (41 days to July 12 exam — schedule exam today 06-01), MSCHAPv2 migration wrap-up
-
Secondary: RHCSA curriculum, Spanish SIELE C1
-
CISSP — Security & Risk Management (continuing). Schedule exam this afternoon.
-
RHCSA — continue curriculum phase
-
Spanish — Don Quijote reading + analysis (DTLA study day)
-
MSCHAPv2 — migration window closed 05-30, review final report
Regex Training (CRITICAL)
-
Status: 52 days carried over (since 2026-03-16)
-
Priority: After PeopleSoft, before Quijote
-
Session: Character classes, word boundaries
Infrastructure
Documentation Sites
| Site | URL | Status | Actions Needed |
|---|---|---|---|
Domus Digitalis |
Active |
Validate, harden, improve |
|
Architectus |
Active |
Public portfolio site - maintain |
HA Deployment Status
| System | Description | Status | Notes |
|---|---|---|---|
VyOS HA |
vyos-01 (kvm-01) + vyos-02 (kvm-02) with VRRP VIP |
✅ COMPLETE |
2026-03-07 - pfSense decommissioned |
BIND DNS HA |
bind-01 (kvm-01) + bind-02 (kvm-02) with AXFR |
✅ COMPLETE |
Zone transfer operational |
Vault HA |
Raft cluster (vault-01/02/03) |
✅ COMPLETE |
Integrated with PKI |
Keycloak Rebuild |
keycloak-01 corrupted, rebuild from scratch |
🔄 NEXT |
Priority P3 - SSO broken |
FreeIPA HA |
ipa-02 replica planned |
📋 PLANNED |
Linux auth redundancy |
AD DC HA |
home-dc02 replication |
📋 PLANNED |
Windows auth redundancy |
iPSK Manager HA |
ipsk-mgr-02 with MySQL replication |
📋 PLANNED |
PSK portal redundancy |
ISE HA |
PAN HA (ise-01 reconfigure) |
⏳ DEFERRED |
Wait until ise-02 stable |
ISE 3.5 Migration |
Upgrade path: 3.2p9 → 3.4 (P1) → 3.5 (target) |
📋 PLANNED |
After 3.4 Migration completes (Q2 2026) |
Single Points of Failure (CRITICAL)
| These systems have NO redundancy - outage impacts production. |
| System | Impact if Down | Mitigation |
|---|---|---|
ISE (ise-02) |
All 802.1X stops - wired and wireless auth fails |
ise-01 reconfiguration deferred until ise-02 stable |
Keycloak (keycloak-01) |
SAML/OIDC SSO broken (ISE admin, Grafana, etc.) |
NEXT PRIORITY - Rebuild runbook |
FreeIPA (ipa-01) |
Linux auth, sudo rules, HBAC fails |
ipa-02 replica planned |
AD DC (home-dc01) |
Windows auth, Kerberos, GPO fails |
home-dc02 replica planned |
iPSK Manager |
Self-service PSK portal unavailable |
ipsk-mgr-02 with MySQL replication planned |
Validation Tasks
| Task | Details | Status |
|---|---|---|
docs.domusdigitalis.dev validation |
Test all cross-references, search, rendering |
TODO |
docs.domusdigitalis.dev hardening |
HTTPS, CSP headers, security review |
TODO |
docs.architectus.dev validation |
Public site content review |
TODO |
Hub-spoke sync verification |
All components building correctly |
Ongoing |
Quick Commands
Git & GitHub CLI
gh repo create <name> --private --source . --remote origin --push
gh repo clone EvanusModestus/PowerShell ~/atelier/_projects/work/PowerShell
gh repo clone defaults to SSH. If key is passphrase-protected, load agent first: eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519_github
|
for repo in ~/atelier/_bibliotheca/domus-*/ ~/atelier/_projects/personal/domus-*/; do
[ -d "$repo/.git" ] || continue
name=$(basename "$repo")
git -C "$repo" log --since="2026-04-06" --until="2026-04-07" --format="%h %aI %s" 2>/dev/null |
awk -v r="$name" '{print r, $0}'
done
git log --oneline -- $(find . -name "*.adoc" -type f -newermt "$(date +%F)")
git restore --staged data/d001/api/ise-dataconnect/output/output-2026-04-24
Safe — removes from staging area only. Working tree is untouched. Use when you accidentally git add a plaintext or output file.
gh CLI — repo discovery and filtering
gh repo list --limit 100 --json name,description \
| jq -r '.[] | select(.name | test("domus|antora|asciidoc"; "i")) | "\(.name)\t\(.description)"'
gh repo list --limit 100 --json name,description,updatedAt \
| jq -r 'sort_by(.updatedAt) | reverse | .[:20] | .[] | "\(.updatedAt[:10])\t\(.name)\t\(.description)"'
gh repo list --limit 100 --json name,diskUsage \
| jq -r '.[] | "\(.diskUsage)\t\(.name)"' | sort -rn | head -10
gh repo clone EvanusModestus/<repo-name> ~/atelier/_bibliotheca/<repo-name>
find & grep
find . -name "*.adoc" -type f -newermt "$(date +%F)" | sort
-mtime 0 means "last 24 hours", not "today". -newermt "$(date +%F)" compares against midnight — exact.
|
find . -iname "*mschap*" -type f | sort
find . -type f \( -iname "*ise*" -o -iname "*mschap*" \) | sort
find . -type f -iregex '.*\(ise\|mschap\).*'
find . -type f -iname "*meeting*" \
-not -path "*/node_modules/*" \
-not -path "*/.git/*" \
-not -path "*/build/*"
find .drafts -type f -printf '%T@ %Tc %p\n' | sort -rn | awk '{$1="";print}' | head -3
grep -rl "pattern" . --include="*.adoc" # file count (which files)
grep -rn "pattern" . --include="*.adoc" # line matches (every occurrence)
grep -rc "pattern" . --include="*.adoc" | grep -v ':0$' # match count per file
grep -rn -E 'git init|gh repo create' docs/ --include='*.adoc' -B2 -A2
Search codex by content — which files contain a command?
find docs/modules/ROOT/examples/codex/powershell -type f -name "*.adoc" \
-exec grep -l 'Get-Process\|Start-Process\|pipeline\|Where-Object' {} \;
Pattern: find -exec grep -l returns only filenames with matches — like grep -rl but with find’s `-type f -name filtering. Use \| for OR in grep basic regex. Swap the pattern for any cmdlet or keyword to locate coverage across the codex.
find docs/modules/ROOT -name "powershell" -type d \
-exec sh -c 'echo "$1: $(find "$1" -type f | wc -l) files"' _ {} \;
for f in $(find docs/modules/ROOT/examples/codex/powershell -name "*.adoc" -type f); do
base=$(basename "$f")
dir_parent=$(basename $(dirname "$f"))
grep -rq "$dir_parent/$base" docs/modules/ROOT/pages/codex/powershell/ \
docs/modules/ROOT/examples/codex/powershell/*.adoc 2>/dev/null \
|| echo "ORPHAN: $f"
done
find → grep → open in nvim
nvim $(find -path '*oauth*' -name '*.adoc' -type f \
-exec grep -l 'timeout\|expire\|reconfig\|token' {} \;)
Command substitution $(…) feeds all matches as arguments to nvim — opens every hit as a buffer. :bn/:bp to cycle, :ls to list. One file? Opens directly. Five files? All loaded, ready to navigate.
nvim $(find docs/modules/ROOT -name '*.adoc' -type f \
-exec grep -l 'token.*expire\|oauth.*refresh' {} \;)
find -path '*oauth*' -name '*.adoc' -type f \
-exec grep -l 'timeout\|expire' {} \; \
-exec nvim {} \;
Trailing \| in grep patterns matches empty string — every file matches. Always end with a term, not a pipe: 'timeout\|expire\|token' not 'timeout\|expire\|token\|'.
|
Trace Antora partial inclusion chains
grep -rl 'commands/shell' docs/modules/ROOT/partials/
grep -rl 'quick-commands' docs/modules/ROOT | wc -l
file="commands/shell"
grep -rl "$file" docs/modules/ROOT/partials/ | while read f; do
parent=$(basename "$f" .adoc)
echo "$file -> $parent"
grep -rl "$parent" docs/modules/ROOT/pages/ | while read p; do
echo " -> $(basename "$p")"
done
done
Pattern: grep -rl finds which files contain the string. Chain two passes — first finds the assembler partial, second finds every page that includes it. Works for any partial in the Antora include hierarchy.
Multi-pattern file search — worklog partial discovery
find docs/modules/ROOT -name "*urgent.adoc*" -type f
find docs/modules/ROOT -name "*morning.adoc*" -type f
find docs/modules/ROOT -type f -regextype posix-extended \
-regex '.*(urgent|morning|work-chla|personal|education|infrastructure|quick-commands|related)\.adoc' \
| sort
Pattern: -regextype posix-extended enables | alternation without escaping. One process, one sort — versus 8 separate finds. The sort deduplicates visually and groups by path.
find docs/modules/ROOT -type f -name "*.adoc" \
| grep -E 'urgent|morning|work-chla|personal|education|infrastructure|quick-commands|related'
Trade-off: the pipeline version is more readable but spawns two processes. The regex version is a single find — faster on large trees, same result.
Cross-repo literary term search — bibliotheca-wide discovery
When searching for a term across the entire _bibliotheca (multiple repos, mixed file types), these patterns escalate from narrow to broad.
grep -rn --include='*.adoc' -c 'sanchuelo' . | grep -v ':0$'
grep -rl --include='*.adoc' -i 'sanchuelo' ~/atelier/_bibliotheca/ | sort
grep -rn --include='*.adoc' -i -B1 -A1 'sanchuelo' ~/atelier/_bibliotheca/domus-captures/
grep -rl -i 'sanchuelo' ~/atelier/_bibliotheca/ --include='*.txt' --include='*.adoc' | sort
find ~/atelier/_bibliotheca/ -type f \( -name '*.adoc' -o -name '*.txt' \) -print0 \
| xargs -0 grep -li 'sanchuelo' | sort
grep -rl -i 'sanchuelo' ~/atelier/_bibliotheca/ --include='*.adoc' --include='*.txt' | xargs nvim
Pattern escalation: #1 confirms the term exists and where. #2 expands to all repos. #3 shows context without opening files. #4 adds plain text sources (Quijote .txt originals). #5 is the safe version for automation. #6 opens everything for editing.
Trade-off: grep -r --include is faster for known file types. find | xargs grep is safer for paths with spaces and more extensible (add -name '*.md' etc.). For literary searches across the bibliotheca, #4 or #5 is usually the right starting point — the source texts are .txt, not .adoc.
Email thread analysis — extract people, dates, commitments, silence
grep -P '(@\w+|^From:.*<)' comms.adoc
grep -nP '\d{1,2}/\d{1,2}/\d{2,4}|20\d{2}-\d{2}-\d{2}' comms.adoc
grep -niP '(I can |I will |I.ll |we will |we.ll )' comms.adoc
grep -niP '(\?|need to confirm|need to validate|TBD|pending)' comms.adoc
comm — set difference (who hasn’t replied)
# All recipients
grep -oP '<\K[^>]+' comms.adoc | sort -u > /tmp/all-recipients
# All senders
grep -P '^From:' comms.adoc | grep -oP '<\K[^>]+' | sort -u > /tmp/replied
# Who's silent — follow-up targets
comm -23 /tmp/all-recipients /tmp/replied
comm -23 outputs lines only in file 1 (recipients not in senders). Requires sorted input. grep -oP '<\K[^>]+' uses PCRE lookbehind — match < but don’t include it, capture until >.
awk, sed, jq
awk — field extraction
awk '{print $2}' file.txt
awk -F: '{print $1, $3}' /etc/passwd
awk '/\[source,json\]/{getline; if ($0 ~ /^----/) {p=1; next}} p && /^----/{p=0; next} p' file.adoc
awk '{printf "%-30s %s\n", $1, $2}' file.txt
sed — stream editing
# Before
awk 'NR==73' /etc/ssh/sshd_config
# Change
sed -i '73s/#GSSAPIAuthentication no/GSSAPIAuthentication yes/' /etc/ssh/sshd_config
# After
awk 'NR==73' /etc/ssh/sshd_config
sed -n '10,20p' file.txt
jq — JSON processing
curl -s localhost:8080/stats | jq '.stats.total_files'
jq '.results[] | select(.category == "standards")' response.json
jq -r '.[] | [.title, .path] | @tsv' response.json | column -t -s $'\t'
gh api "repos/EvanusModestus/domus-captures/commits?path=docs/&per_page=10" |
jq -r '.[] | "\(.commit.author.date[:10]) \(.sha[:7]) \(.commit.message | split("\n")[0])"'
Shell Patterns
xargs — when the next command reads arguments, not stdin
| Next command reads… | Use |
|---|---|
stdin ( |
pipe directly |
arguments ( |
|
-I{} placeholdermkdir -p /tmp/adoc-backup-$(date +%F) && \
find . -name "*.adoc" -type f -newermt "$(date +%F)" | \
xargs -I{} cp {} /tmp/adoc-backup-$(date +%F)/
-P4 runs 4 at a timefind .drafts -name "*.adoc" -type f | xargs -P4 -I{} asciidoctor -o /dev/null {}
find . -name "*.adoc" -type f -print0 | xargs -0 wc -l
Process substitution — <(cmd) treats output as a file
diff <(grep '|' partials/trackers/work/adhoc/carryover.adoc | head -20) \
<(git show HEAD~1:partials/trackers/work/adhoc/carryover.adoc | grep '|' | head -20)
diff <(find docs/modules/ROOT/pages/projects/chla/mschapv2-migration -name "*.adoc" -type f | sort) \
<(grep -oP 'mschapv2-migration/[^[]+\.adoc' docs/modules/ROOT/nav.adoc | sort)
Command substitution — embed output as arguments
nvim "$(find data/ -name '*.adoc' -type f -printf '%T@ %p\n' | sort -rn | awk 'NR==1{print $2}')"
wc -l $(find docs/modules/ROOT -path '*mschapv2*' -name '*.adoc' -type f)
Conditional execution — capture, test, act
files=$(find .drafts -name 'in*' -type f) && [ -n "$files" ] && nvim $files
files=$(grep -rl '\[ \]' .drafts/*.adoc) && [ -n "$files" ] && nvim $files
grep -q 'TODO\|FIXME\|\[ \]' "$file" && nvim "$file"
Pattern: $(capture) → [ -n ] tests non-empty → && only proceeds if true.
grep -q is the idempotent guard — run repeatedly, only opens when there’s work.
Decrypt and open — find .age, decrypt, nvim in one shot
files=$(find . -name "*tcp-clock*.age" -type f) && \
[ -n "$files" ] && echo "$files" | xargs -I{} decrypt-file {} && \
nvim $(echo "$files" | sed 's/\.age$//')
Pattern: find .age only (never tries plaintext), sed derives the decrypted path, guard prevents empty nvim. Change the glob to match any project.
tee_clean — color on screen, clean text in file
tee_clean() {
tee >(sed 's/\x1b\[[0-9;]*m//g' > "$1")
}
# Color output on terminal, stripped in file
jq -C '.' data.json | tee_clean output.json
xq -C '.' data.xml | tee_clean output.json
# Wrap a whole block
{
echo "=== Summary ==="
jq -C '.[] | .name' data.json
} | tee_clean summary.txt
The >(cmd) is process substitution — tee writes to stdout AND to the subshell pipe. sed strips ANSI escape sequences (\x1b\[[0-9;]*m) before they hit the file.
Dependency check — verify toolchain in one shot
for cmd in asciidoctor asciidoctor-pdf pandoc rouge d2 mmdc age; do
printf "%-20s %s\n" "$cmd" "$(command -v $cmd >/dev/null 2>&1 && echo 'OK' || echo 'MISSING')"
done
Pattern: command -v checks if binary exists on PATH. >/dev/null 2>&1 suppresses output — we only care about exit code. Swap the tool list for any project’s dependencies.
printf safety — dashes as data, not options
--- as invalid optionprintf '---\n\n'
--- as dataprintf '%s\n\n' '---'
Kill stuck SSH sessions
lsof -i TCP -n -P | awk '/ssh.*ESTABLISHED/ {print $2, $9}'
lsof -i TCP -n -P | awk '/ssh.*kvm-01.*ESTABLISHED/ {print $2}' | sort -u | xargs kill
lsof -i TCP -n -P | awk '/ssh.*ESTABLISHED/ {print $2}' | sort -u | xargs kill
lsof -i TCP -n -P lists all TCP connections. awk filters for SSH + ESTABLISHED, prints only the PID ($2). sort -u deduplicates (multiple file descriptors per process). xargs kill sends SIGTERM to each.
File Descriptors & Redirection
The three file descriptors
| FD | Name | Purpose |
|---|---|---|
0 |
stdin |
input to the command |
1 |
stdout |
normal output (valid results) |
2 |
stderr |
error messages |
Split stdout and stderr into separate files
find / -name "*.conf" 1>results.txt 2>errors.txt
Suppress errors — 2>/dev/null
find / -name "*.conf" 2>/dev/null
Merge stderr into stdout — 2>&1
command 2>&1 | grep "pattern"
This sends both stdout and stderr through the pipe. Without 2>&1, only stdout reaches grep — errors print to the terminal and bypass the pipeline.
Heredoc patterns
cat <<'EOF'
Line 1
Line 2
EOF
git commit -m "$(cat <<'EOF'
feat: add new feature
Multi-line description here.
EOF
)"
API & curl/jq
domus-api — Documentation System REST API
cd ~/atelier/_projects/personal/domus-api && uv run uvicorn domus_api.main:app --host 0.0.0.0 --port 8080
curl -s localhost:8080/ | jq
curl -s 'localhost:8080/search?q=mandiant' | jq
curl -s 'localhost:8080/search?q=mandiant' | jq '.results[] | {path, title, match_count}'
curl -s 'localhost:8080/pages?category=standards' | jq
curl -s localhost:8080/attributes | jq
GitHub API
gh search code "vault seal" --owner EvanusModestus --json repository,path,textMatches |
jq '.[] | {repo: .repository.full_name, file: .path, match: .textMatches[].fragment}'
gh api 'repos/EvanusModestus/domus-captures/git/trees/main?recursive=1' |
jq '[.tree[] | select(.path | endswith(".adoc"))] | length'
Domus Workflows
Read content from terminal (meeting-ready)
bat docs/modules/ROOT/pages/2026/04/WRKLOG-$(date +%Y-%m-%d).adoc
bat docs/modules/ROOT/partials/trackers/work/priorities/current.adoc
bat docs/modules/ROOT/partials/trackers/work/adhoc/carryover.adoc
bat docs/modules/ROOT/partials/projects/mandiant-remediation/summary.adoc
Search and discovery
grep -rl "MSCHAPv2" docs/modules/ROOT/ --include="*.adoc" | sort
grep -rn "pattern" docs/modules/ROOT/partials/codex/ --include="*.adoc" -B1 -A3
ls -1 docs/modules/ROOT/pages/2026/04/WRKLOG-*.adoc
Tracker aging — calculate days from origin
echo $(( ($(date +%s) - $(date -d "2026-03-09" +%s)) / 86400 ))
Encrypted data access (d001)
age --decrypt -i ~/.secrets/.metadata/keys/master.age.key \
data/d001/projects/mandiant-remediation/findings-status-2026-04-16.adoc.age \
| bat --language asciidoc
for d in data/d001/projects/*/; do
total=$(find "$d" -type f | wc -l)
plain=$(find "$d" -type f ! -name '*.age' ! -name 'README.adoc' ! -name '.gitkeep' ! -name '*.py' | wc -l)
printf "%-25s %s files %s plaintext\n" "$(basename "$d")" "$total" "$plain"
done
ISE & Network Ops
ISE ERS API — endpoint CRUD
export ISE_HOST="{ise-ip}" ISE_USER="admin" ISE_PASS="$(gopass show -o ise/admin)"
curl -sk "https://$ISE_HOST:{ise-ers-port}/ers/config/identitygroup" \
-H "Accept: application/json" -u "$ISE_USER:$ISE_PASS" | jq '.SearchResult.resources[].name'
curl -sk "https://$ISE_HOST:{ise-ers-port}/ers/config/endpoint?filter=mac.EQ.AA:BB:CC:DD:EE:FF" \
-H "Accept: application/json" -u "$ISE_USER:$ISE_PASS" | jq '.SearchResult.total'
Certificate inspection
openssl x509 -in {cert-dir}/client.pem -text -noout | head -30
openssl x509 -in {cert-dir}/client.pem -enddate -noout
Network diagnostics
ss -tlnp | grep -E ':{port-https}|:{port-ssh}|:{port-ldaps}'
nc -zv {ise-ip} {ise-ers-port}
dig {ise-hostname} +short
PowerShell (from zsh)
All PowerShell commands run inside pwsh -NoLogo -Command '…' from zsh. Running them bare fails — zsh interprets $, |, () as shell syntax.
|
Process management
pwsh -NoLogo -Command 'Get-Process | Sort-Object WorkingSet64 -Descending |
Select-Object -First 5 ProcessName, Id,
@{N="MB";E={[math]::Round($_.WorkingSet64/1MB)}} | Format-Table'
pwsh -NoLogo -Command 'Get-Process | Where-Object {$_.ProcessName -like "*teams*"} | Stop-Process'
pwsh -NoLogo -Command 'Start-Process "ms-teams"'
Export to JSON (pipe to jq)
pwsh -NoLogo -Command 'Get-Process | Sort-Object WorkingSet64 -Descending |
Select-Object -First 5 ProcessName, Id,
@{N="MB";E={[math]::Round($_.WorkingSet64/1MB)}} | ConvertTo-Json' | jq '.'
Never pipe Format-Table into ConvertTo-Json — it produces layout metadata, not data. Select-Object first, then ConvertTo-Json.
|
Wi-Fi management (netsh)
netsh wlan disconnect interface="Wi-Fi"
netsh wlan show networks mode=bssid
netsh wlan connect name="CHLA-Remote" interface="Wi-Fi"
SSH from PowerShell
ssh evan@modestus-razer.inside.domusdigitalis.dev
Security & Encryption
View encrypted files without writing to disk
age --decrypt -i ~/.secrets/.metadata/keys/master.age.key \
data/d001/projects/mandiant-remediation/findings-status-2026-04-16.adoc.age \
| bat --language asciidoc --file-name "findings-status-2026-04-16.adoc"
Batch re-encrypt — brace expansion + loop
for f in data/d001/projects/mandiant-remediation/{findings-status,guest-acl-update,siem-report}-2026-04-16.adoc; do
rm -f "${f}.age" && echo y | encrypt-file "$f"
done
Always rm -f the .age first. If you skip it, encrypt-file prompts about overwrite and may only delete the plaintext without re-encrypting.
|
Detect stale plaintext — files needing re-encryption
for f in data/d001/projects/*/*.adoc; do
age="${f}.age"
if [ -f "$f" ] && [ -f "$age" ]; then
pt_mod=$(/usr/bin/stat -c'%Y' "$f")
age_mod=$(/usr/bin/stat -c'%Y' "$age")
[ "$pt_mod" -gt "$age_mod" ] && echo "STALE: $f"
fi
done
Secure delete — shred for sensitive plaintext
shred -u data/d001/projects/mandiant-remediation/man-report.txt
On SSD/NVMe, shred is less effective (wear leveling), but better than rm which only removes the directory entry.
|
Pre-push audit — find all unencrypted project files
find data/d001/projects -type f ! -name '*.age' ! -name 'README.adoc' ! -name '.gitkeep' ! -name '*.py' | sort
System & Infrastructure
PipeWire audio validation
wpctl status # PipeWire status
pactl list sinks short # list audio sinks
pw-play /usr/share/sounds/freedesktop/stereo/bell.oga # test default sink
journalctl -b --grep='sof|cs35l56' --no-pager | tail -20 # kernel audio firmware
cat /proc/asound/cards # ALSA sound cards
gopass — personal document management
gopass-personal-docs # interactive entry creation
gopass-query bills # list recurring bills with totals
gopass-query storage # list storage units with gate codes
gopass-query export bills # export category to JSON
Makefile — daily workflow
make new-day # create today's worklog + update attributes
make serve # build + local server (port 8000)
make # build only
make sync-nav # sync worklog nav entries
make update-index # rebuild monthly index
Per-project file dashboard
for d in data/d001/projects/*/; do
total=$(find "$d" -type f | wc -l)
plain=$(find "$d" -type f ! -name '*.age' ! -name 'README.adoc' ! -name '.gitkeep' ! -name '*.py' | wc -l)
echo "$(basename "$d") | ${total} files | ${plain} plaintext"
done