WRKLOG-2026-06-20
Summary
Saturday. 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 |
83 |
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 |
63 |
✅ 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 |
90 |
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 |
120 |
P0 - ACTIVE — ISE integration in progress |
Guest Redirect ACL |
Guest redirect ACL work needed. Related to Mandiant remediation findings. |
2026-05-12 |
58 |
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 |
119 |
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 |
122 |
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 |
122 |
P0 - Blocked by k3s |
Strongline Gateway VLAN fix |
8 devices in wrong identity group (David Rukiza assigned) |
2026-03-16 |
115 |
P0 - TODO |
TCP Clocks deployment |
ISE identity group validation, query outputs, comms with team. Active d001 data Apr 22-23. |
2026-04-22 |
78 |
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 |
85 |
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 |
84 |
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 |
119 |
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 |
119 |
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 encrypted D000 case file. |
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 D000 case file. Open: |
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 |
|---|---|---|
Submit PeopleSoft timesheet |
pending |
trackers/work/ (recurring) |
Submit annual review |
pending |
trackers/work/priorities/current.adoc |
TCP timeclock meeting — 1400 |
pending |
ephemeral |
Quijote I.039 lectura |
pending |
trackers/education/ |
Vim Adventures — complete |
pending |
schedule 30-min block |
Work
TCP Clocks — Go-Live Validation
Go-live day. DataConnect unavailable (DPY-6005 timeout — MnT node unreachable). Fell back to ERS-only validation.
Ran bulk ERS check against all 165 MACs with cached identity group lookups (optimized from 495 to 167 API calls). Results:
-
164/165 confirmed in
IoT_OnboardwithstaticGroupAssignment: true -
1 outlier:
40:AC:8D:00:95:FAstill inUnknown, no description, no static assignment — needs remediation
Session documented in d001/projects/tcp-clocks/partials/session-2026-06-20.adoc.
Action items:
-
Remediate
40:AC:8D:00:95:FA— assign to IoT_Onboard -
Investigate DataConnect timeout once network path confirmed
TCP Clocks — Connectivity Investigation Scripts
10 clocks reporting connectivity issues to updates.timeclockplus.com on port 443 (polling every 5 min). Built investigation tooling across three ISE APIs + FMC REST API.
Scripts Created
d001/projects/tcp-clocks/scripts/:
-
tcp-clocks-commands.sh— ISE investigation (DataConnect + MnT + ERS) -
tcp-clocks-fmc.sh— FMC firewall block investigation
Both scripts embed helper functions (dc_query, mnt, ers, fmc_auth, fmc_get) directly from data/shared/partials/. No copy-paste required — preflight validates env vars before execution.
ISE Script — What It Checks
| Step | Purpose |
|---|---|
0. Format probe |
Confirms MAC delimiter format in DataConnect (colons vs dashes) |
1. DC Summary |
Per-clock triage: auth count, failure count, first/last seen, switch/port |
2. DC Profiler |
ISE classification: profiler policy, identity group, static assignment |
3. DC Enrichment |
Last 50 auth events with failure reasons and authz profiles |
4. MnT Sessions |
Active session state per clock ( |
5. MnT Auth History |
7-day pass/fail timeline with failure reasons |
6. ERS Validation |
Endpoint store: group membership, static assignment, description |
7. Offline Deep Dive |
Specific investigation of |
FMC Script — What It Checks
| Step | Purpose |
|---|---|
1. Access Policies |
Identifies which policy governs the FTDs |
2. FQDN/URL Objects |
Checks if |
3. Network Objects |
Checks if clock subnets are defined in FMC |
4-5. Rule Table + Block Rules |
Full rule listing and enabled BLOCK rules |
6. Traffic Path Match |
Filters to rules matching IoT source → OUTSIDE destination |
7. Default Action |
Whether unmatched traffic is blocked or allowed |
8. Diagnosis |
Automated rule-order analysis — detects BLOCK-before-ALLOW and disabled rules |
Secrets Segmentation
Created d001 dev/network/fmc tier via dsec to isolate FMC credentials from ISE credentials. Blast radius: loading ISE creds no longer exposes FMC admin access.
Output
All output writes to d001/projects/tcp-clocks/output/{date}/ with dated subdirectories. Output files are gitignored (.txt under data/).
Execution
# ISE investigation
dsource d001 dev/network/ise
bash data/d001/projects/tcp-clocks/scripts/tcp-clocks-commands.sh
# FMC investigation (separate creds)
dsource d001 dev/network/fmc
POLICY_ID=<uuid> bash data/d001/projects/tcp-clocks/scripts/tcp-clocks-fmc.sh
Findings
Infrastructure Cleared
Full investigation across four ISE APIs (ERS, DataConnect, MnT, OpenAPI) and FMC REST API. Results:
| Layer | Finding | Status |
|---|---|---|
ISE DataConnect |
163 clocks authenticated, zero failures in 30 days |
✅ Clear |
ISE ERS |
164/165 in |
✅ Clear |
ISE MnT |
108 active sessions with IPs, 2 STOPPED (session cycling) |
✅ Clear |
FMC Firewall |
Zero block rules for IoT/clock subnets. ALLOW confirmed in GUI for clock IP |
✅ Clear |
Ping reachability |
108 UP from MnT live IPs, 2 DOWN (stale sessions) |
✅ Clear |
Authorization Profile Flow (confirmed working)
Manual onboard → IoT_Onboard (static) → IoT_Device_CM (transitional)
→ Medigate profiles → ISE global CoA reauth
→ medigate_TimeClock_Plus_TCP_Software_Time_Clock → Timeclock_CM_dACL ✅
-
IoT_Device_CMis the expected transitional state before Medigate profiles -
Timeclock_CM_dACLis the final operational state -
Wired-Guest-CWA-Redirect= device never onboarded or session predates static assignment
Remediation Performed
-
40:AC:8D:00:95:D5— was inUnknowngroup,static=false, no description. Reassigned toIoT_Onboardvia ERS PUT. CoA reauth returned HTTP 500 ("Incorrect PSN information") — clock will pick up new group on next natural reauth -
40:AC:8D:00:95:DC— initially showedUnknownin ISE GUI. Confirmed active onTimeclock_CM_dACLwith IP10.238.43.72after profiling cycle completed
Vendor Reports SSL Errors on 27 Clocks
Vendor (TCP Software / TimeClock Plus) reported 27 devices experiencing SSL errors connecting to updates.timeclockplus.com. Infrastructure investigation confirmed:
-
Clocks are on-network with IPs
-
Firewall is passing traffic (HTTP to
updates.timeclockplus.comconfirmed ALLOW in FMC) -
ISE is not blocking — zero auth failures
-
Clocks are pingable
The SSL error is application-layer, not infrastructure. Possible causes:
| Cause | Explanation |
|---|---|
TLS version mismatch |
Vendor server may have upgraded to TLS 1.3 or dropped TLS 1.0/1.1. 27 clocks may have older firmware than the working ones. |
Certificate trust |
Vendor changed their SSL certificate or CA chain. Clocks don’t trust the new CA — no mechanism to update trust store on these devices. |
SNI requirement |
|
SSL inspection |
If |
Vendor Proposed Disabling SSL — Rejected
Vendor suggested disabling SSL on the 27 affected clocks as a workaround. This was rejected. These devices operate in a HIPAA-regulated environment. Disabling SSL would transmit employee PII (badge IDs, punch timestamps, credentials) in plaintext across the network.
Vendor server configuration observed during troubleshooting:
-
Server URL:
updates.timeclockplus.com -
Namespace:
331511 -
Device name:
IS-Field Support Services -
"Skip SSL Validation" is enabled in the vendor’s server settings
This confirms the vendor’s TLS posture is permissive by design — they bypass certificate validation on their own infrastructure. This is a vendor risk finding for security review.
Acceptable remediation paths communicated to vendor:
-
Update clock firmware to support current TLS version
-
Fix the server-side certificate chain so clocks trust the CA
-
Provide the CA certificate for deployment to clock trust stores
If vendor cannot remediate TLS compatibility, this constitutes a vendor product deficiency and will be escalated.
Vendor subsequently claimed "data is encrypted already" even with SSL disabled, implying application-layer encryption makes TLS unnecessary. This claim was not accepted without evidence. Requested: specific encryption protocol, cipher suite, and key exchange method used for the claimed application-layer encryption. No response provided.
If no application-layer encryption exists, disabling SSL reduces transport to plaintext HTTP — employee PII (badge IDs, punch times, credentials) visible to any observer on the network path. Unacceptable in a HIPAA environment.
Root Cause Identified — Firmware Version
Vendor confirmed: 27 clocks require firmware 7.0.53.0 or later to connect to the API server (updates.timeclockplus.com). The affected clocks are on older firmware and cannot complete the TLS handshake with the current API server.
-
Update server:
updates.timeclockplus.com/updates6.0(HTTP, port 80) -
Update server URL was not set on the affected clocks from the vendor’s API server configuration
-
FMC confirmed HTTP traffic to
updates.timeclockplus.comis ALLOW (observed in live connection events)
This is a vendor configuration/deployment issue — the update server was not provisioned on these devices during initial setup.
Device Log Evidence — Screenshots Captured
Two screenshots captured from the clock’s on-device management interface (data/d001/projects/tcp-clocks/images/):
Screenshot 1 — Server Settings tab:
-
Server URL:
updates.timeclockplus.com -
Namespace: 331511
-
Device Name: IS-Field Support Services
Screenshot 2 — Connect Log tab (2026-06-21 01:58 UTC):
Update server not set from API server (Requires 7.0.53.0 or later)
Get version info from server returns http status 000
Unable to determine version of application server from url https://331...
Host version resolved to 1.72.2
WAITING: Round trip to update server failed on try 1 (6)
WAITING: Round trip to update server failed on try 2 (6)
WAITING: Round trip to update server failed on try 3 (6)
WAITING: Round trip to update server failed on try 4 (6)
ERROR: Unable complete round trip to update server http://updates.time...
Starting firmware.
The device’s own log states:
-
Firmware is
1.72.2— requires7.0.53.0or later -
Update server was not set from API server — vendor provisioning failure
-
HTTP status
000— no response from update server (URL not configured, not blocked) -
Clock retries 4 times, fails, falls back to stale firmware
This is the vendor’s device, the vendor’s log, reporting the vendor’s configuration error.
Vendor Has Centralized Management — Clock Hub
TCP Software provides a web-based management tool called Clock Hub for centralized clock administration:
-
Path: Configuration > Other Configurations > Clock Configurations
-
Capabilities: automatic firmware deployment to all clocks, remote reboot, configuration changes
-
This is the vendor’s own tool — no network changes required on our side
TCP Software has two management tools — the vendor may be conflating them:
| Tool | Purpose |
|---|---|
TimeClock Manager |
HR/admin web app — employee hours, leave, reports, payroll. NOT for device management. |
Clock Hub / Clock Status |
Physical clock hardware management — firmware deployment, device settings, RDTg configuration. This is where firmware gets pushed. |
Clock Status directly manages RDTg clock settings. The vendor’s own documentation states clocks communicate with the database in real-time and administrative changes are "immediately enforceable at the terminal."
The vendor can push firmware 7.0.53.0+ to the 27 affected clocks from Clock Status without any infrastructure changes. A packet capture is unnecessary — the device’s own Connect Log already shows the root cause.
References:
-
Clock Configuration Options (requires TCP community login)
Questions for Vendor
-
What is the exact SSL error? (untrusted CA, handshake failure, protocol version mismatch?)
-
Did they recently change their TLS certificate or minimum TLS version?
-
What firmware version are the 27 failing clocks on vs the working ones?
-
Can they provide server-side logs for one of the 27 failing devices?
Vendor Moved Clock to Non-dot1x Port — Clock Connected
Vendor moved an affected clock to a non-dot1x switch port (bypassing ISE authentication entirely). Clock connected and reached the update server. This confirms:
-
The clock’s network stack works on an unrestricted port
-
The clock cannot handle the 802.1X authentication/authorization flow on firmware 1.72.2
-
This does not mean ISE is the problem — it means the clock firmware is incompatible with standard enterprise network access control
-
The fix is firmware update to 7.0.53.0+, not bypassing 802.1X for 165 IoT devices
Moving production IoT devices to non-dot1x ports is not an acceptable remediation — it removes all network access control and creates an unmanaged attack surface.
Resolution
Vendor confirmed clocks are now working. No infrastructure changes were made on our side. The dACL, dot1x, SSL, and firewall rules remained unchanged throughout.
The fix was vendor-side — specific action taken by vendor is undocumented. Logs requested to confirm:
-
What changed on the vendor’s end to resolve the 27 affected clocks
-
Server-side logs showing successful connections from the previously failing devices
-
Whether the update server URL was configured and firmware 7.0.53.0+ deployed
This must be documented for the project record. The vendor spent the entire engagement attempting to shift responsibility to our infrastructure:
-
Requested SSL be disabled → rejected
-
Requested dACL removal → rejected
-
Requested packet capture → unnecessary (device logs showed root cause)
-
Moved clock to non-dot1x port → confirmed their firmware issue, not our controls
-
Claimed app-layer encryption justifies disabling SSL → no evidence provided
-
Claimed clock was "being muted" on dot1x port → no ISE failures in any API
Every vendor claim was investigated and disproven with API evidence. Resolution occurred only after vendor made changes on their side.
Boot Timing Issue — Clock DHCP Timeout vs 802.1X
Screenshot from clock Boot Log (Image.jpg, 2026-06-21 02:50 UTC) after being returned to dot1x port:
02:50:34 UTC Startup script started
02:50:34 UTC Skipping arp and name servers because boot protocol is DHCP.
02:50:50 UTC Waiting for network to start.
02:51:01 UTC Network is ready but no IP address assigned within 10 second wait period.
02:51:01 UTC Waiting for network completed (Network up=0)
02:51:01 UTC AutoUpdate of firmware is disabled because network is not ready.
02:51:01 UTC Starting firmware.
The clock has a 10-second DHCP timeout — it gives up before 802.1X MAB authentication completes. The port should be configured with C3PL (Common Classification Policy Language) to run MAB and dot1x simultaneously, not sequentially. If the switch port requires dot1x first, falls back to MAB, then authorizes — that exceeds 10 seconds and the clock starts on stale firmware with no IP.
Investigation needed:
-
SSH to the NAS (switch) and check the port config:
show run interface <port> -
Verify C3PL policy:
show policy-map interface <port> -
Check if
authentication order mab dot1xandauthentication priority mab dot1xare configured -
Confirm MAB is not waiting for dot1x timeout before attempting
The MnT and DataConnect output from tcp-clocks-check-mac.sh provides the NAS IP and port for each clock — use that to SSH directly to the switch.
Working Clock Network Status
Screenshot from clock Network tab (Media.jpg):
-
IP:
10.238.69.248 -
MAC:
40:AC:8D:00:93:EC -
Received: 10.00 KB / Transmitted: 4.00 KB
-
DHCP assigned, traffic flowing — clock is functional on dot1x port
This confirms that when the clock gets an IP before the DHCP timeout, it works. The issue is timing, not policy.
Action Items
-
Run ISE discovery script — DataConnect confirmed operational
-
Run FMC script — no block rules, traffic allowed
-
Remediate
40:AC:8D:00:95:D5— reassigned toIoT_Onboard -
Remediate
40:AC:8D:00:95:DC— confirmed profiled and active -
Follow up with vendor on SSL error details for the 27 clocks
-
Check if SSL inspection is in the traffic path for
updates.timeclockplus.com:443 -
Investigate CoA PSN targeting — MnT CoA returned HTTP 500 (PSN vs PAN issue)
-
Fix ISE OpenAPI — returns empty on all endpoints (not enabled or auth issue)
-
Fix discovery script counter bug — MnT active/stopped counts show 0 (subshell variable scope)
TCP Timeclock Meeting — 1400
Go-live validation meeting with Chris Murburi (PM).
-
ERS bulk validation complete — 164/165 in
IoT_Onboard(see tcp-clocks daily note) -
Outlier:
40:AC:8D:00:95:FAstill inUnknown— needs remediation discussion -
DataConnect unavailable from workstation — report connectivity issue to ISE team
-
Present ERS validation results (164/165 confirmed)
-
Flag the 1 outlier MAC and agree on remediation owner
-
Report DataConnect timeout — confirm MnT node reachability from workstation subnet
-
Confirm go-live sign-off criteria met
-
Session:
d001/projects/tcp-clocks/partials/session-2026-06-20.adoc -
Prior session:
d001/projects/tcp-clocks/partials/session-2026-06-18.adoc
Submit PeopleSoft Timesheet
Weekly timesheet submission — due before Monday.
-
Log hours for week of 2026-06-16 through 2026-06-20
-
Verify PeopleSoft codes against
partials/trackers/work/peoplesoft-codes/ -
Submit and confirm approval routing
Submit Annual Review
Performance review submission — deadline-driven.
-
Draft complete —
data/d000/cursus/annual-review/chla/2025/self-eval-draft-2026.adoc -
Content written to xlsx — 24 cells, 3 Exemplary / 5 Effective
-
CISSP exam confirmed August 2026
-
Review with manager (Sarah) before submission
-
Submit in Performance Lab
-
2026 xlsx (submission):
data/d000/cursus/annual-review/chla/2026/my-annual-review-2026.xlsx -
2025 xlsx (reference):
data/d000/cursus/annual-review/chla/2025/my-annual-review.xlsx -
Self-eval draft:
data/d000/cursus/annual-review/chla/2025/self-eval-draft-2026.adoc -
Portfolio data:
data/d000/cursus/portfolio/chla/ -
iTrack change history:
data/d000/cursus/portfolio/chla/data/itrack-change-history.yaml
-
2026-06-21: Cell mapping, openpyxl workflow, all 24 cells written
-
2026-06-22: Finalization, script improvements, submission workflow
Personal Infrastructure
Claude Code Vault-Backed Auth — Post-Upgrade Fix
After pacman -Syu + restow, Claude Code threw 401 on startup. Root cause: upgrade migrated auth from ~/.claude/credentials.json to a two-file model (~/.claude.json + ~/.claude/.credentials.json), overwriting vault-backed symlinks with plain files. Additionally, stow was managing .credentials.json via dots-quantum — a live bearer token as a plain file in a git-tracked repo.
Resolved:
-
Updated vault copy with current token
-
Removed
.credentials.jsonfrom dots-quantum, added to.gitignore -
Created vault symlinks for both files
-
Wrote
claude-relinkscript for post-mount and post-login recovery -
Verified remount cycle: unmount → 401 → remount → auth restored
Runbook: Claude Code Vault Auth
P16g Display & TTY — Ongoing Investigation
Screen blanking after extended idle has not been resolved despite the lid-wake fix (CR-2026-06-19-p16g-hyprlock-lid-wake) and PSR persistence fix (CR-2026-06-19-p16g-i915-psr-persistence). Symptoms worsening after yesterday’s pacman -Syu kernel upgrade:
-
Internal display remains black after wake — external monitor required to regain access
-
TTY switching (Ctrl+Alt+F1 through F6) inconsistent or non-functional
-
Both symptoms predate yesterday’s upgrade but have degraded further
Previous fixes addressed:
-
PSR hang (INC-2026-05-23-002):
i915.enable_psr=0— prevents self-refresh hang but does not address full DRM pipe teardown -
Lid-wake failure (CR-2026-06-19): Replaced
monitor disablewithbrightnessctl— avoids pipe teardown on lid close -
WAYLAND-1 phantom (2026-06-19): Phantom headless output stealing workspaces — source still unidentified
Next step: systematic log-driven investigation. No more hypothesizing — pull concrete evidence from journald, dmesg, i915 debugfs, and Hyprland logs across the kernel upgrade boundary. Cross-reference P16g deployment project (phase-13-maintenance.adoc) and all related incidents.
Scope for focused document:
-
All display-relevant kernel parameters (current vs expected)
-
journalctl -kfiltered for i915, drm, eDP, DPMS around wake events -
dmesgdiff: pre-upgrade vs post-upgrade kernel -
TTY/VT subsystem state:
cat /sys/class/tty/tty*/active, VT switch capability -
Hyprland monitor state:
hyprctl monitors allincluding disabled/phantom outputs -
Timeline: kernel versions vs symptom onset
External SSD — Encrypted Portable Vault
Researched and selected hardware for a LUKS-encrypted portable backup drive. Two machines to serve (ThinkPad P16g + Razer 18").
| Item | Model | Price |
|---|---|---|
NVMe SSD |
Samsung 990 PRO 2TB — PCIe 4.0 x4, M.2 2280, 7,450 MB/s read, DRAM cache, AES-256 hardware encryption, 1,200 TBW endurance |
~$160 |
Enclosure |
UGREEN 80Gbps NVMe M.2 — Thunderbolt 5/4/3 + USB4 compatible, fanless aluminum fin heatsink, no noise |
~$170 |
Total |
~$330 |
-
Both machines already have Samsung PM9E1 (9100 PRO OEM) internally — PCIe 5.0, 14,500 MB/s. The external doesn’t need to match internal speed.
-
The 990 PRO has DRAM cache — essential for git’s small random writes.
-
The UGREEN enclosure is fanless (no moving parts to fail) and TB5/USB4 backward compatible.
-
The 9100 PRO ($420) was rejected as overkill — same NAND family, double the price, speed wasted on text file backups.
smartctl)Model: SAMSUNG MZVLC2T0HBLD-00BLL (PM9E1) Interface: PCIe Gen 5.0 x4 — confirmed 32GT/s x4 via lspci Capacity: 2.04 TB Percentage Used: 0% Data Written: 1.44 TB (of 2,400 TBW endurance) Power On Hours: 39 Media Errors: 0 Temperature: 36°C Health: PASSED
-
LUKS full-disk encryption on the external drive
-
btrfs filesystem (matches both machines)
-
Git bare mirror repos via
git clone --mirror -
Add as git remote:
git remote add vault-ext /mnt/vault-ext/domus-captures.git -
Two layers: LUKS on the drive + age encryption on sensitive files inside
# Drive model
cat /sys/block/nvme0n1/device/{model,firmware_rev,serial}
# PCIe link speed (confirms Gen 5 x4)
sudo lspci -vv | awk '/Non-Volatile/,/^$/'
# Health, wear, temperature
sudo smartctl -a /dev/nvme0n1
# Partition layout
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL /dev/nvme0n1
Education
SSH Agent + Key Loading — Heredoc Pattern
Loaded GitHub SSH key into agent for git push. Teaching moment on when heredocs apply vs file path arguments.
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519_github
bash << 'EOF'
# ── SSH Agent + GitHub Key Loader ──
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_github
echo "── Loaded keys ──"
ssh-add -l
echo "── Testing GitHub connection ──"
ssh -T git@github.com 2>&1 || true
EOF
The consumer of the heredoc is bash — which reads scripts from stdin. Inside the heredoc, ssh-add still takes a file path argument. Two input mechanisms working together:
-
bash << 'EOF'— heredoc feeds the script to bash via stdin -
ssh-add ~/.ssh/id_ed25519_github— ssh-add reads the key file via argument
| Pattern | When | Example |
|---|---|---|
|
Command expects a file path argument |
|
|
Command reads single-line input from stdin |
|
|
Command reads multi-line input from stdin |
|
# WRONG — sends the string "~/.ssh/key" as stdin text, not as a file path
ssh-add <<< ~/.ssh/id_ed25519_github
# RIGHT — ssh-add reads the key file at this path
ssh-add ~/.ssh/id_ed25519_github
gh-auth() {
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_github
ssh-add -l
}
Using domus-captures as a CLI Reference Library
The documentation tree contains 900+ .adoc files with real commands from real investigations. Every example has context — the problem it solved, the output it produced, the file it targeted. That corpus is more valuable than any cheatsheet. These commands extract from it.
Extract complete source blocks by tool name
The fundamental operation: pull entire [source,bash] blocks that contain a specific command, not just the matching line.
find with contextawk '
/\[source,bash\]/{block=""; capture=1; next}
capture && /^----$/ && !inside {inside=1; next}
capture && inside && /^----$/ {
if (block ~ /find/) printf "── %s:%d\n%s\n", FILENAME, NR, block
capture=0; inside=0; block=""
next
}
capture && inside {block = block $0 "\n"}
' docs/modules/ROOT/partials/codex/**/*.adoc
This is an awk state machine with three states: scanning, entered block header, inside block. It accumulates lines until the closing ----, then tests the whole block against the pattern. Only complete blocks print — never orphaned lines.
docsearch() {
local pattern="${1:?usage: docsearch PATTERN [DIR]}"
local dir="${2:-docs/modules/ROOT}"
find "$dir" -name '*.adoc' -exec awk -v pat="$pattern" '
/\[source,bash\]/{b=""; c=1; next}
c && /^----$/ && !d {d=1; next}
c && d && /^----$/ {
if (b ~ pat) printf "\033[36m── %s:%d\033[0m\n%s\n", FILENAME, NR, b
c=0; d=0; b=""
next
}
c && d {b = b $0 "\n"}
' {} +
}
docsearch 'xargs.*-P' # parallel xargs patterns
docsearch 'find.*-exec.*\+' # batched find -exec
docsearch 'awk.*NR==\|FNR' # awk line addressing
docsearch 'sed.*-i' # in-place sed edits
docsearch 'jq.*select' # jq filter patterns
docsearch 'curl.*-sS' docs/modules/ROOT/partials/codex/apis # scoped to apis codex
Build a tool frequency index from source blocks
Not "which files mention grep" — which tools actually appear inside executable code blocks, ranked by how often you reach for them.
find docs/modules/ROOT -name '*.adoc' -exec awk '
/\[source,bash\]/{c=1; next}
c && /^----$/ && !d {d=1; next}
c && d && /^----$/ {c=0; d=0; next}
c && d {
for (i=1; i<=NF; i++) {
w=$i; gsub(/[^a-z0-9_-]/, "", w)
if (w ~ /^(awk|sed|grep|find|xargs|curl|jq|yq|stat|sort|cut|tr|wc|diff|tee|nc|dig|ss|ip|openssl)$/)
tools[w]++
}
}
END {for (t in tools) printf "%4d %s\n", tools[t], t}
' {} + | sort -rn
This scans only inside [source,bash] blocks. Prose mentions of grep don’t count — only executable invocations. The output shows what you actually use, not what you write about.
Find commands you wrote but never turned into codex entries
Cross-reference: commands appearing in daily-notes but absent from codex.
comm -23 \
<(find docs/modules/ROOT/partials/worklog/daily-notes -name '*.adoc' \
-exec awk '/\[source,bash\]/,/^----$/{print}' {} + \
| grep -oP '^\s*\K(find|grep|awk|sed|xargs|curl|jq)\b[^|;]+' \
| sed 's/\s\+/ /g' | sort -u) \
<(find docs/modules/ROOT/partials/codex -name '*.adoc' \
-exec awk '/\[source,bash\]/,/^----$/{print}' {} + \
| grep -oP '^\s*\K(find|grep|awk|sed|xargs|curl|jq)\b[^|;]+' \
| sed 's/\s\+/ /g' | sort -u)
comm -23 prints lines present in file 1 (daily-notes) but absent from file 2 (codex). Process substitution feeds both without temp files. These are your candidates for codex graduation — commands you reached for in the field but never documented formally.
Find the most complex pipelines
Pipe count as a proxy for complexity — surfaces your most composed commands.
find docs/modules/ROOT -name '*.adoc' -exec awk '
/\[source,bash\]/{c=1; next}
c && /^----$/ && !d {d=1; next}
c && d && /^----$/ {c=0; d=0; next}
c && d {
pipes=gsub(/\|/, "|")
if (pipes >= 3) printf "%d│ %s:%d│ %s\n", pipes, FILENAME, NR, $0
}
' {} + | sort -t'│' -k1 -rn | head -30 | column -t -s'│'
Every line inside a bash block with 3+ pipes, ranked by pipe count. The output is your most sophisticated pipeline compositions — the ones worth studying and extracting.
Diff your tool usage across time periods
Compare which tools you used last week vs this week — shows learning trajectory.
tool_usage() {
find "$1" -name '*.adoc' -exec awk '
/\[source,bash\]/,/^----$/{
for(i=1;i<=NF;i++){
w=$i; gsub(/[^a-z]/, "", w)
if(w ~ /^(awk|sed|grep|find|xargs|jq|curl|stat|sort|cut|tr|comm|paste|diff|tee)$/)
t[w]++
}
}
END {for(k in t) printf "%s\t%d\n", k, t[k]}
' {} +
}
paste \
<(tool_usage docs/modules/ROOT/partials/worklog/daily-notes/2026-06-1{0..3} 2>/dev/null | sort) \
<(tool_usage docs/modules/ROOT/partials/worklog/daily-notes/2026-06-1{7..20} 2>/dev/null | sort) \
| awk -F'\t' '{printf "%-8s %4s → %4s\n", $1, $2, $4}'
Two paste`d process substitutions, each running the same `awk extractor on different date ranges. The output shows your drift: did you use more awk this week? Less grep -P? comm for the first time?
Extract .Title labels with their associated commands
Your source blocks use .Title labels. Pull them as a structured index.
find docs/modules/ROOT/partials/codex -name '*.adoc' -exec awk '
/^\.[A-Z]/{title=$0; next}
/\[source,bash\]/{capture=1; next}
capture && /^----$/ && !inside {inside=1; next}
capture && inside && /^----$/ {
if (title != "") printf "%s\n ── %s:%d\n %s\n\n", title, FILENAME, NR, firstline
title=""; capture=0; inside=0; firstline=""
next
}
capture && inside && firstline=="" {firstline=$0}
' {} + | head -60
Output: every titled source block with its first command line and file location. This is your codex table of contents — built from the source files, not maintained by hand.
Where the patterns live
| Directory | Density |
|---|---|
|
12 partials — exec-patterns, time-size, security, pipelines, multi-predicate, archiving, cleanup, monitoring, permissions |
|
20+ partials — PCRE lookaround, pipeline combinations, log analysis, security patterns, context flags, conditional scripting |
|
Highest volume — real-world usage from live investigations under time pressure |
|
Verification commands — |
|
The only tier directly executable — pipe to |
The meta-lesson
The same find | grep | awk chains you practice on log files work identically on .adoc files. Every search you run against your documentation is itself a drill in the tools you’re documenting. The corpus validates itself.
Commands Personally Leveraged
ls $(find docs -type f -name '*.adoc' -mmin -60 -exec grep -IlE 'find|grep|mtime|mmin' {} +)
docs/modules/ROOT/partials/worklog/daily-notes/2026-06/2026-06-20/vim-sed-duality.adoc
Violin Lesson
Lesson day. Photographed all current repertoire and scale material from phone to workstation via MTP (gvfs-mtp, ADB was not enumerating).
-
No. 1: Gavotte — P. Martini
-
No. 2: Minuet — J.S. Bach
-
No. 3: Gavotte in G Minor — J.S. Bach
-
No. 4: Humoresque — A. Dvorak (50 bpm, SBS work)
-
No. 5: Gavotte — J. Becker (60 bpm)
-
No. 6: Gavotte in D Major — J.S. Bach
-
No. 7: Bourree — J.S. Bach
-
Tonalization (G/C Major/Minor)
-
Vibrato exercises
-
Shifting: 2nd Position (all strings)
-
String changing exercises
-
Key of G — full complement: Major, Melodic/Harmonic Minor, Chromatic, Octaves, Thirds, Sixths, Fingered Octaves, Tenths, Harmonics
-
Practice suggestions: Sevcik/Flesch/Ysaye systems, Left Hand Acceleration, Arpeggios
-
Piece(s) worked on:
-
Instructor feedback:
-
Practice assignment:
Violin Music Project — data/d000/education/music/violin/
All sheet music lives outside Antora as LilyPond source (.ly), reference photos, and practice logs. Three books currently transcribed.
data/d000/education/music/violin/
├── Makefile # make all | make schradieck | make barber | make humoresque
├── README.adoc
├── practice-log.adoc
└── pieces/
├── schradieck-book1/
│ ├── schradieck-book1.adoc # photo index, exercise descriptions
│ ├── photos/ # 4 phone photos of the book
│ └── ly/
│ └── section-01-one-string.ly # 25 exercises — NEEDS NOTE VERIFICATION
├── barber-scales/
│ ├── barber-scales.adoc
│ ├── photos/ # 11 photos
│ └── ly/
│ └── key-of-g.ly # G Major, Melodic Minor, Harmonic Minor
└── suzuki-v3/
├── suzuki-v3.adoc
├── photos/ # 18 photos
└── ly/
└── 04-humoresque.ly # first 8 measures at 50 bpm
LilyPond workflow
All commands assume working directory is data/d000/education/music/violin/.
.ly sources into PDFscd ~/atelier/_bibliotheca/domus-captures/data/d000/education/music/violin
for f in pieces/*/ly/*.ly; do lilypond -o "${f%.ly}" "$f"; done
${f%.ly} is parameter expansion: strips the .ly suffix so -o writes section-01-one-string.pdf instead of section-01-one-string.ly.pdf.
# Schradieck only
for f in pieces/schradieck-book1/ly/*.ly; do lilypond -o "${f%.ly}" "$f"; done
# Barber only
for f in pieces/barber-scales/ly/*.ly; do lilypond -o "${f%.ly}" "$f"; done
for f in pieces/*/ly/*.ly; do lilypond -o "${f%.ly}" "$f" && zathura "${f%.ly}.pdf" & done
Each PDF opens in zathura as soon as its build finishes. The & backgrounds each viewer so the loop continues to the next file.
zathura pieces/schradieck-book1/ly/section-01-one-string.pdf &
zathura ~/Downloads/Schradieck-The-School-of-Violin-Technics-BOOK-1-EX-1-Partitura-completa.pdf &
Compare exercise by exercise. Each exercise is its own variable in the .ly file (exerciseOne, exerciseTwo, …, exerciseTwentyFive), so corrections are isolated — change the notes, rebuild, check.
.ly files from the terminal (no editor needed)# See what's in exercise 4 (print just that variable block)
sed -n '/^exerciseFour/,/^}/p' pieces/schradieck-book1/ly/section-01-one-string.ly
# Replace a wrong note sequence in exercise 4 (verify before → change → verify after)
grep 'a16 b cis d cis b a b' pieces/schradieck-book1/ly/section-01-one-string.ly
sed -i 's/a16 b cis d cis b a b/a16 b cis b a b cis b/' pieces/schradieck-book1/ly/section-01-one-string.ly
grep 'a16 b cis b a b cis b' pieces/schradieck-book1/ly/section-01-one-string.ly
# Change tempo globally
sed -i 's/\\tempo 4 = 72/\\tempo 4 = 60/' pieces/schradieck-book1/ly/section-01-one-string.ly
# Extract all exercise variable names
awk '/^exercise[A-Z]/{print NR": "$0}' pieces/schradieck-book1/ly/section-01-one-string.ly
# Count exercises
grep -c '^exercise' pieces/schradieck-book1/ly/section-01-one-string.ly
# Show just the note content (strip lilypond markup, keep only note lines)
awk '/^ [a-g]/{print NR": "$0}' pieces/schradieck-book1/ly/section-01-one-string.ly
# Diff your .ly against a backup after edits
diff <(git show HEAD:data/d000/education/music/violin/pieces/schradieck-book1/ly/section-01-one-string.ly) \
pieces/schradieck-book1/ly/section-01-one-string.ly
# Replace one exercise's notes entirely (exercise 6, lines between markers)
sed -n '/^exerciseSix/,/^}/p' pieces/schradieck-book1/ly/section-01-one-string.ly # inspect first
sed -i '/^exerciseSix/,/^}/{
s/old note sequence/new note sequence/
}' pieces/schradieck-book1/ly/section-01-one-string.ly
# Batch rename a note across the whole file (e.g., every 'gis' → 'g')
sed -i 's/\bgis\b/g/g' pieces/schradieck-book1/ly/section-01-one-string.ly
lilypond -o pieces/schradieck-book1/ly/section-01-one-string \
pieces/schradieck-book1/ly/section-01-one-string.ly
zathura pieces/schradieck-book1/ly/section-01-one-string.pdf &
make all # every .ly in pieces/
make schradieck # just Schradieck
make barber # just Barber scales
make humoresque # just Humoresque
make clean # delete all generated .pdf, .midi, .mid
Build artifacts — gitignored
LilyPond generates .midi, .mid, and .pdf alongside each .ly source. These are build artifacts — regenerated by lilypond or make on every build. They are gitignored globally:
# .gitignore (repo root) — LilyPond artifacts
*.midi
*.mid
# data/**/*.pdf already covers PDFs under data/
make clean removes all generated files:
make clean
# runs: find pieces -name '*.pdf' -delete
# find pieces -name '*.midi' -delete
# find pieces -name '*.mid' -delete
LilyPond concepts to know
\relative c''-
All notes are relative to the previous note. If the interval is a fourth or less, no octave mark needed. Fifths and wider need
'(up) or,(down). \repeat volta 2 { }-
Creates repeat barlines. Content plays twice. Notes after the block play only after the final repeat.
\mark "1."-
Rehearsal mark — labels each exercise number above the staff.
\break-
Forces a new system (line of music) — one exercise per line.
16-
Sixteenth note duration. Stays in effect until a new duration appears. So
a16 b cis dmeans all four are sixteenths.
Phone-to-workstation photo transfer
ADB was not enumerating (ZFold 7 in MTP-only mode). Used gvfs-mtp instead:
# List MTP mounts
gio mount -li | awk '/activation_root/{print $NF}'
# Mount the device
gio mount 'mtp://SAMSUNG_SAMSUNG_Android_R3GYB0J7YHY/'
# Copy photos (today's date filter)
find /run/user/1000/gvfs/mtp*/Internal\ storage/DCIM/Camera/ \
-name '20260620*' -exec cp {} /tmp/violin-photos/ \;
To get ADB working: enable USB Debugging in Developer Options on the phone, then adb devices -l should enumerate.
Vim Adventures — Resume and Complete
Vim Adventures — the game that teaches Vim motions through gameplay. Started previously, not completed.
Vim motions are the shared substrate across nvim, tmux copy-mode, less, man, and every readline-compatible tool. The game builds muscle memory for w, b, e, f, t, %, gg, G, /{pattern} without the cognitive overhead of editing real files.
-
Started — level unknown (check browser history or account)
-
Motions already in daily use:
hjkl,w,b,dd,yy,p,/,n -
Gaps likely in:
ci",da(,gf, marks (ma,'a), macros (qa)
-
All levels finished
-
New motions captured in
partials/codex/vim/motions-quick-reference.adoc
Status: Pending — schedule a 30-minute block.
Ideas
Idea: systemd-Style Dependencies for Daily Captures
Exploring whether systemd’s dependency model applies to daily task captures. Instead of priority labels (want/need/required), express what blocks what.
// Requires: dataconnect-working, golive-validation
// After: tcp-clocks-meeting
// Before: 2026-06-30
// Conflicts: —
| Directive | Meaning |
|---|---|
|
Cannot proceed without this — hard dependency |
|
Would benefit from this, but can proceed without it |
|
Ordering — do this after X completes |
|
Deadline — must complete before this date or event |
|
Mutually exclusive — cannot run alongside X |
submit-annual-review
Requires=cissp-scheduling-confirmed
Before=2026-06-30
tcp-timeclock-meeting
Requires=dataconnect-working
After=golive-validation
quijote-i039
Wants=pedro-session-notes
After=work-complete
submit-peoplesoft
Before=monday
The association engine already models blocks, requires, depends-on — same graph, different notation. This would be a lightweight inline version for daily notes that don’t warrant full association entries.
Open questions:
-
Is this useful enough to formalize, or does the triage table already cover it?
-
Could an
awkscript parse these directives and build a dependency-ordered task list? -
Does this converge with the association engine, or is it a parallel system that creates maintenance burden?
Status: Idea — needs a real day of usage to evaluate.
Idea: Terminal Access to Browser Search History
Surface browser search queries from the terminal — use your own search history as a retrieval tool without opening a browser.
Browser search history is locked inside SQLite databases per browser profile. You search for something at work, close the tab, and two hours later can’t remember the query. The browser history UI is mouse-driven and unsearchable from a pipeline.
# Firefox — places.sqlite
find ~/.mozilla/firefox -name 'places.sqlite' 2>/dev/null
# Chromium/Brave — History (SQLite)
find ~/.config/{chromium,google-chrome,BraveSoftware} -name 'History' 2>/dev/null
# Firefox locks the DB while running — copy first
cp ~/.mozilla/firefox/*.default-release/places.sqlite /tmp/places.sqlite
sqlite3 /tmp/places.sqlite "
SELECT datetime(last_visit_date/1000000, 'unixepoch', 'localtime') AS visited,
url
FROM moz_places
WHERE url LIKE '%google.com/search%'
OR url LIKE '%duckduckgo.com/?q%'
ORDER BY last_visit_date DESC
LIMIT 20
" | column -t -s'|'
sqlite3 /tmp/places.sqlite "
SELECT url FROM moz_places
WHERE url LIKE '%google.com/search%'
ORDER BY last_visit_date DESC LIMIT 20
" | grep -oP '[?&]q=\K[^&]+' | python3 <<'EOF'
import sys, urllib.parse
for line in sys.stdin:
print(urllib.parse.unquote_plus(line.strip()))
EOF
# Concept — pipe decoded queries into fzf, open selected in browser
sqlite3 /tmp/places.sqlite "SELECT url FROM moz_places ORDER BY last_visit_date DESC LIMIT 500" \
| fzf --preview 'echo {}' \
| xargs -I{} xdg-open "{}"
Open questions:
-
Which browser is primary on P16g? Path differs per browser.
-
Could this become a shell function in dots-quantum (
browsearch)? -
Privacy: extracts URLs to plaintext. Pipe to
wl-copyand clear, or write to tmpfs only.
Status: Idea — needs browser identification and a working prototype.
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. 06-09: Architecture decision — rsyslog (CHLXSYSLOG01) as collection tier → Monad → Sentinel. ISE lab → rsyslog → Monad 6-step execution guide created with 10 API calls. ASA lab logs already flowing through rsyslog. DCR still needed — Victor + Mauricio.
-
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 — 6-sheet Standard Report ready. Migration window 05-04 to 05-30 CLOSED. Confirm final report status and next steps with team. 6,227 MSCHAPv2 devices, 14,249 EAP-TLS/TEAP (70% migrated).
-
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 — Batch 1: 7 clocks validated (OUI 40:AC:8D). Batch 2 (06-09): 9 new MACs (OUI 40:AC:BD) added via ERS. 1 one-off reassigned. New switch deployed without RADIUS/AAA — clocks can’t authenticate. Switch onboarding template + 3 validation queries documented. ERS queries self-contained with
ersfunction. -
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. 06-15: Assembler build fixed (26 errors → 0). Segmentation document extension to 06-16.
d001 open linux-researchto work on it. -
Abnormal Security — CR-2026-05-07. Implemented 05-13. 06-09 update: Full policy review — 20-section EOP validation commands rebuilt, Hoxhunt SCL-1 investigation (intentional bypass confirmed), sclizer junk folder triage (~800 emails), Outlook reactions audit added, Connect-ExchangeOnline msalruntime fix documented. ESA migration expansion in progress — priority to move off ESA to full environment.
-
Team: Cox/William, Landeros/Jason, Rosado/Evan, Naranjo/Mauricio, Sandoval/Carlos
-
-
ASA VPN: Okta RADIUS → Entra SAML — (NEW 06-09) 5-phase migration plan built. ASA baseline captured (2 tunnel groups: CHLA_CORPORATE_USERS, CHLA_BYOD_USERS). 6 ISE policy screenshots. Tony Sun (ASA), Justin Halbmann (Entra/Okta), Evan (ISE). VPN cert expires 07-28. PDF deliverable ready. Share with team this week.
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 Controller Segmentation (MIGRATED — 06-09)
-
BMS Controller Segmentation — Full migration from Principia LaTeX to d001. 12 partials, 5 Mermaid diagrams, 4 legacy PDFs, ISE screenshots.
d001 open bms-controller. Completed 2026-06-09.
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). 92 days. Blocks Wazuh indexer recovery → blocks SIEM visibility. Decide: test or defer to Q3.
-
Strongline Gateway VLAN fix — 8 devices wrong identity group (origin: 2026-03-16). 85 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.
Search daily notes — find commands, builds, and patterns across worklogs
Source: 2026-06-22 — searching for build-antora-page invocations and theme usage across partials
# Find files — filenames only
grep -rl 'build-antora-page' docs/modules/ROOT/partials/worklog/
# 3 lines of context around each hit
grep -rn -C3 'build-antora-page' docs/modules/ROOT/partials/worklog/
grep -rPn 'theme\s+(light-cyan|catppuccin|mocha)' docs/modules/ROOT/partials/
find docs/modules/ROOT/partials/worklog/daily-notes -name '*.adoc' \
-exec grep -l 'build-antora-page\|build-adoc\|--theme\|pdf' {} \;
find docs/modules/ROOT/partials/worklog/daily-notes -name '*.adoc' \
-exec awk '/build-antora-page|build-adoc|--theme/{print FILENAME": "$0}' {} \;
find docs/modules/ROOT/partials -name '*.adoc' -exec \
awk '/^\[source,bash\]/{block=1; buf=""} \
block{buf=buf"\n"$0} \
/^----$/ && block>1{if(buf~/build-antora-page/) print FILENAME":"buf; block=0} \
block{block++}' {} \;
The awk state machine: [source,bash] sets block=1 and starts buffering. Each line appends to buf. When the closing ---- arrives (and block>1 to skip the opening fence), check if the buffer contains the target command. If yes, print filename + entire block. Reset. One pass, arbitrary block size, no temp files.
find docs/modules/ROOT/partials/worklog -name '*.adoc' -exec \
sed -n '/\[source,bash\]/,/^----$/{/build-antora-page/p}' {} +
grep -rn 'build-antora-page\|build-adoc' data/ --include='*.adoc'
grep -rn 'build-antora-page' docs/modules/ROOT/partials/worklog/daily-notes/ \
| awk -F: '{print $1, $3}' | sort
Pattern escalation: grep -rl → "where is it". grep -rn -C3 → "what’s around it". find -exec awk → "extract the structured block". sed address ranges → "print between delimiters". Each tool has a different affordance — grep finds, awk extracts structure, sed filters ranges, find -exec scales across trees.
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 >.
Sort find results by modification time (newest first)
find discovers files but has no sort. Chain -printf with sort to order by mtime.
awk '{print $2}' truncates filenames with spaces — Familia Romana_ Lingva… becomes Familia. Always use the null-safe or sub() variants below for real data.
|
# Sort by mtime, strip epoch prefix — handles spaces in filenames
find ~/Downloads -maxdepth 1 -name '*.pdf' -printf '%T@ %p\n' | sort -rn | awk '{sub(/^[^ ]+ /,""); print}'
sub(/[ ]+ /,"") removes everything up to and including the first space (the epoch). {print $2} would split on every space — fatal for Familia Romana_ Lingva Latina.
# ISO 8601 timestamps — readable and lexicographically sortable
find ~/Downloads -maxdepth 1 -name '*.pdf' -printf '%T+ %p\n' | sort -r | head -20
%T+ renders YYYY-MM-DD+HH:MM:SS — no epoch math needed, still sorts correctly as text.
# Null-delimited: survives any filename (newlines, quotes, unicode)
find ~/Downloads -maxdepth 1 -name '*.pdf' -printf '%T@\t%p\0' | sort -zrn | awk -v RS='\0' -F'\t' '{print $2}'
-printf '%T@\t%p\0' — tab separates epoch from path, null terminates. sort -z sorts null-delimited records. awk -v RS='\0' -F'\t' reads null-terminated, splits on tab — $2 is now the full path regardless of spaces.
# GNU stat equivalent — works where -printf is unavailable
find ~/Downloads -maxdepth 1 -name '*latin*' -exec stat --format='%Y %n' {} + | sort -rn | awk '{sub(/^[^ ]+ /,""); print}'
-exec … {} + batches all files into one stat call (faster than \;). On macOS, use stat -f '%m %N' instead of --format='%Y %n'.
File intelligence — size, type, duplicates, age
Beyond finding files — interrogating them.
# Size in bytes (-printf %s), human-readable via numfmt
find ~/Downloads -type f -printf '%s\t%p\n' | sort -rn | head -10 | numfmt --to=iec --field=1
numfmt --to=iec --field=1 converts the first field from bytes to K/M/G. sort -rn on raw bytes is exact — ls -lhS rounds and sometimes mis-sorts.
# Files sharing a byte count — likely duplicates (confirm with md5sum)
find ~/Downloads -type f -printf '%s %p\n' | awk '{seen[$1]++; files[$1]=files[$1] "\n " $0} END {for (s in seen) if (seen[s]>1) print files[s]}'
# md5sum only files with duplicate sizes (two-pass: fast then precise)
find ~/Downloads -type f -printf '%s\n' | sort | uniq -d | while read -r size; do
find ~/Downloads -type f -size "${size}c" -exec md5sum {} +
done | sort | uniq -w32 -D
Two-pass: first find duplicate sizes (cheap), then md5sum only those (expensive). uniq -w32 -D compares first 32 chars (the hash) and prints all duplicates.
# Count files by MIME type (not extension — extensions lie)
find ~/Downloads -type f -exec file --mime-type -b {} + | sort | uniq -c | sort -rn
file --mime-type -b reports actual content type. -b suppresses filename. A .pdf that’s really text/html is a failed download.
# Files not accessed in 30 days — candidates for cleanup
find ~/Downloads -maxdepth 1 -type f -atime +30 -printf '%A+ %s\t%p\n' | sort | numfmt --to=iec --field=2
-atime 30` = access time older than 30 days. `-printf '%A' shows last access. Useful for Downloads cleanup without deleting something you just renamed.
# Which subdirectories consume the most space?
find . -maxdepth 1 -type d -exec du -sh {} + 2>/dev/null | sort -rh | head -20
Batch operations — rename, move, transform
# Dry run — show what would change (remove echo to execute)
find ~/Downloads -maxdepth 1 -type f -name '* *' -print0 | while IFS= read -r -d '' f; do
dir=$(dirname "$f")
base=$(basename "$f" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
echo mv "$f" "$dir/$base"
done
IFS= read -r -d '' — the holy trinity for null-safe filename reading. IFS= prevents whitespace trimming. -r prevents backslash interpretation. -d '' reads until null.
# Sort Downloads chaos into folders by type
find ~/Downloads -maxdepth 1 -type f -print0 | while IFS= read -r -d '' f; do
ext="${f##*.}"
case "$ext" in
pdf|epub) dest="books" ;;
jpg|png|svg) dest="images" ;;
sh|py|rb) dest="scripts" ;;
*) dest="other" ;;
esac
mkdir -p ~/Downloads/"$dest"
echo mv "$f" ~/Downloads/"$dest"/
done
${f##.} — parameter expansion: strip longest match of . from front, leaving only the extension. No basename or awk needed.
# Convert all epubs in a directory to asciidoc via pandoc
find . -name '*.epub' -type f -exec sh -c '
for epub; do
adoc="${epub%.epub}.adoc"
pandoc -f epub -t asciidoc "$epub" -o "$adoc" \
&& printf " → %s (%s lines)\n" "$adoc" "$(wc -l < "$adoc")" \
|| printf " ✗ failed: %s\n" "$epub"
done
' _ {} +
-exec sh -c '…' _ {} + — batch mode. _ fills $0 (script name, discarded). All matched files become $1, $2, … iterated by for epub. One sh invocation, not one per file.
xargs power patterns
# Checksum all PDFs in parallel (4 processes)
find ~/Downloads -name '*.pdf' -print0 | xargs -0 -P4 md5sum
-P4 runs 4 md5sum processes simultaneously. -print0 | xargs -0 is the null-safe pipeline — no filename can break it.
# Compare files pairwise with diff
find . -name '*.adoc' -print0 | xargs -0 -n2 diff --brief
-n2 feeds two arguments per invocation. Useful for pairwise comparisons, copy operations (-n2 with cp), or any command taking exactly two args.
# Backup every config file: cp <file> <file>.bak
find /etc -maxdepth 1 -name '*.conf' -print0 | xargs -0 -I{} cp {} {}.bak
-I{} replaces {} with each filename. Slower than + batching (one cp per file) but necessary when the filename must appear in a specific position.
Process substitution — diff without temp files
# What files exist in study-A but not study-B?
diff <(find data/d000/education/ciceron-study -type f -name '*.adoc' | sort) \
<(find data/d000/education/latin-study -type f -name '*.adoc' | sort)
<(cmd) creates a file descriptor from command output. diff sees two "files" — no temp files created, no cleanup needed.
# Side-by-side: file type census of two directories
paste <(find dir1 -type f -exec file --mime-type -b {} + | sort | uniq -c | sort -rn) \
<(find dir2 -type f -exec file --mime-type -b {} + | sort | uniq -c | sort -rn)
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
sed — line-targeted replacement (verify-before / change / verify-after)
# 1. LOCATE: find the line number
grep -n 'adoc-pdf' zsh/.zshrc
# 2. VALIDATE: read the exact line before changing
awk 'NR==1760' zsh/.zshrc
# 3. CHANGE: target by line number — only hits that line
sed -i '1760s/alias adoc-pdf=/alias build-adoc=/' zsh/.zshrc
# 4. VERIFY: confirm change AND check for collateral
grep -n 'build-adoc\|adoc-pdf' zsh/.zshrc
Without the line number prefix (1760s/), sed replaces every match in the file — a shotgun. With it, surgical. The line number comes from grep -n.
awk 'NR==1218 || NR==1760' zsh/.zshrc
# grep found the error at line 44164 — read 50 lines of context
awk 'NR>=44160 && NR<=44210' session-dump.adoc
No head | tail chains. No sed -n '44160,44210p'. One awk, two numbers.
grep -oP with \K — value extraction from key-value logs
# ISE syslog — extract failure reasons
grep -oP 'FailureReason=\K[^,;]+' /var/log/syslog | sort | uniq -c | sort -rn
# ISE — extract MAC addresses
grep -oP 'Calling-Station-ID=\K[0-9A-Fa-f:.-]+' /var/log/syslog | sort -u
# ISE — extract NAS IPs
grep -oP 'NAS-IP-Address=\K[0-9.]+' /var/log/syslog | sort -u
# ISE — extract device names
grep -oP 'NetworkDeviceName=\K[^,;]+' /var/log/syslog | sort -u
\K resets the match start — everything before \K is required context but excluded from output. [^,;]+ captures until the next delimiter. Pipe to sort -u for unique, sort | uniq -c | sort -rn for counted frequency.
# Generic form — works for any key=value log format
grep -oP 'FIELD_NAME=\K[^,;]+' logfile | sort | uniq -c | sort -rn | head -20
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
d000 study builds
for d in p1-cap-03{7,8,9}; do
for f in data/d000/education/quijote-study/notas/$d/*.adoc; do
d000 build "$d/$(basename "$f" .adoc)" html --variant light-cyan
done
done
d000 build p1-cap-038/texto-anotado html --variant light-cyan
d000 build p1-cap-038/texto-anotado pdf --theme light-cyan
for d in p1-cap-03{7,8,9}; do
for f in data/d000/education/quijote-study/notas/$d/*.adoc; do
d000 build "$d/$(basename "$f" .adoc)" pdf --theme light-cyan
done
done
firefox data/d000/education/quijote-study/notas/p1-cap-03{7,8,9}/output/*.html &
firefox data/d000/education/quijote-study/notas/p1-cap-03{7,8,9}/output/*.pdf &
lp data/d000/education/quijote-study/notas/p1-cap-03{7,8,9}/output/*.pdf
d000 build annotated-text pdf --theme light-cyan
d000 build lpl-study/notas/texto-anotado pdf --theme light-cyan
d000 build de-oratore/libro-i/texto-anotado html --variant light-cyan
Available themes
ls ~/atelier/_bibliotheca/domus-asciidoc-build/themes/pdf/ | sed 's/-theme\.yml//'
# base blue burgundy catppuccin creative dark don-quijote green
# learning light-cyan navy operations orange purple reference royal
~/atelier/_bibliotheca/domus-asciidoc-build/docinfo/compose.sh --list
# light dark catppuccin royal light-cyan
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
ISE eval rotation — backup & restore
# SSH to ISE
ssh admin@ise-02.inside.domusdigitalis.dev
# Verify NAS repo
show repository nas-01
# Get encryption key (on workstation)
dsource d000 dev/storage
echo $ISE_BACKUP_KEY
# Run backup
backup pre-rotation-2026-06 repository nas-01 ise-config encryption-key plain <KEY>
ssh admin@ise-02.inside.domusdigitalis.dev
show repository nas-01
configure terminal
repository nas-01
url nfs://10.50.1.70:/volume1/ise_backups
exit
restore <backup-filename> repository nas-01 encryption-key plain <KEY>
VyOS — VRRP & VLAN inspection
show vrrp
show configuration commands | grep vrrp | grep 'address'
show configuration commands | grep 'firewall zone' | grep 'member'
show dhcp server leases
show arp
show interfaces
CUPS printing — validation & setup
command -v lpstat && echo "CUPS present" || echo "CUPS not installed"
lpstat -r # scheduler running?
lpstat -p -d # printers + default
sudo systemctl enable --now cups # start + persist
lpinfo -v # available backends/URIs
lpinfo -m | grep -i <brand> # available drivers
sudo lpadmin -p <name> -v <uri> -m everywhere -E
lpoptions -d <name>
lp file.pdf # default printer
lp -d <name> -o sides=two-sided-long-edge file.pdf
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
WSL ↔ Windows — Cross-Environment Commands
From zsh (WSL) — control Windows
pwsh -NoLogo -Command 'Get-Date'
pwsh -NoLogo -Command "$(cat <<'PS'
$procs = Get-Process | Where-Object { $_.WorkingSet64 -gt 100MB }
$procs | Sort-Object WorkingSet64 -Descending |
Select-Object ProcessName, Id, @{N="MB";E={[math]::Round($_.WorkingSet64/1MB)}} |
Format-Table -AutoSize
PS
)"
# Open in default Windows app
wslview /mnt/c/Users/erosado/Documents/report.pdf
# Open Explorer to current WSL directory
explorer.exe .
# Open specific Windows path
explorer.exe 'C:\Users\erosado\Downloads'
# Pipe anything to Windows clipboard
cat file.txt | clip.exe
# Copy a command's output
pwsh -NoLogo -Command 'Get-TransportRule | Format-List Name, State' | clip.exe
# Windows C: drive is at /mnt/c
ls /mnt/c/Users/erosado/Downloads/
# Copy from Windows to WSL
cp /mnt/c/Users/erosado/Downloads/report.pdf ~/atelier/
# Watch a Windows directory for new files
find /mnt/c/Users/erosado/Downloads -maxdepth 1 -mmin -5 -type f -printf '%T+ %p\n' | sort -r
From PowerShell — control WSL
wsl -e bash -c 'grep -rn "Ghost-Sender" ~/atelier/_bibliotheca/domus-captures/docs/'
$result = wsl -e bash -c 'git -C ~/atelier/_bibliotheca/domus-captures log --oneline -5'
$result
Process Management — Windows Side
pwsh -NoLogo -Command '
Get-Process | Sort-Object WorkingSet64 -Descending |
Select-Object -First 20 ProcessName, Id,
@{N="MB";E={[math]::Round($_.WorkingSet64/1MB)}},
@{N="CPU(s)";E={[math]::Round($_.CPU,1)}},
@{N="Handles";E={$_.HandleCount}} |
Format-Table -AutoSize'
pwsh -NoLogo -Command 'Get-Process | Where-Object { $_.ProcessName -like "*teams*" } |
Select-Object ProcessName, Id, @{N="MB";E={[math]::Round($_.WorkingSet64/1MB)}} |
Format-Table -AutoSize'
pwsh -NoLogo -Command 'Stop-Process -Name "Teams" -Force -ErrorAction SilentlyContinue'
pwsh -NoLogo -Command 'Stop-Process -Id 12345 -Force'
pwsh -NoLogo -Command 'Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess,
@{N="Process";E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
Sort-Object LocalPort | Format-Table -AutoSize'
pwsh -NoLogo -Command 'Get-NetTCPConnection -LocalPort 8080 -ErrorAction SilentlyContinue |
Select-Object LocalAddress, LocalPort, RemoteAddress, State,
@{N="Process";E={(Get-Process -Id $_.OwningProcess).ProcessName}}'
Services — Windows Side
pwsh -NoLogo -Command 'Get-Service | Where-Object { $_.Status -eq "Running" } |
Sort-Object DisplayName | Format-Table Name, DisplayName, Status -AutoSize'
pwsh -NoLogo -Command 'Get-Service -Name "WinRM" | Format-List Name, DisplayName, Status, StartType'
Restart-Service -Name "WinRM" -Force
System Info — Quick Health from zsh
pwsh -NoLogo -Command '
Write-Host "=== Windows System ===" -ForegroundColor Cyan
Write-Host "Hostname: $env:COMPUTERNAME"
Write-Host "User: $env:USERNAME"
Write-Host "OS: $((Get-CimInstance Win32_OperatingSystem).Caption)"
Write-Host "Uptime: $((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime)"
Write-Host "RAM: $([math]::Round((Get-CimInstance Win32_OperatingSystem).TotalVisibleMemorySize/1MB))GB total, $([math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory/1MB))GB free"
Write-Host "CPU: $((Get-CimInstance Win32_Processor).Name)"
Write-Host "Disk C: $([math]::Round((Get-PSDrive C).Free/1GB))GB free of $([math]::Round(((Get-PSDrive C).Used + (Get-PSDrive C).Free)/1GB))GB"'
pwsh -NoLogo -Command 'Get-PSDrive -PSProvider FileSystem |
Select-Object Name, @{N="Used(GB)";E={[math]::Round($_.Used/1GB,1)}},
@{N="Free(GB)";E={[math]::Round($_.Free/1GB,1)}},
@{N="Total(GB)";E={[math]::Round(($_.Used+$_.Free)/1GB,1)}} |
Format-Table -AutoSize'
Exchange Online — Connect from zsh
pwsh -NoLogo -Command 'Connect-ExchangeOnline -UserPrincipalName erosado@chla.usc.edu'
MFA prompt opens in the Windows browser. After auth, the session persists in the pwsh process. For multi-command sessions, start pwsh interactively instead of one-shot commands.
|
pwsh -NoLogo
# Then inside pwsh:
# Connect-ExchangeOnline
# Get-TransportRule | Format-List Name, State
# exit
File Transfer Patterns
# WSL → Windows Downloads
cp ~/atelier/_bibliotheca/domus-captures/output/report.pdf /mnt/c/Users/erosado/Downloads/
# Windows → WSL (glob)
cp /mnt/c/Users/erosado/Downloads/*.{png,pdf,jpg} ~/atelier/_staging/
# Bulk move with null safety
find /mnt/c/Users/erosado/Downloads -maxdepth 1 -name '*.pdf' -mmin -60 -print0 |
xargs -0 -I{} cp {} ~/atelier/_staging/
inotifywait -m /mnt/c/Users/erosado/Downloads -e create -e moved_to |
awk '{printf "%s %s\n", strftime("%H:%M:%S"), $3}'
inotifywait requires inotify-tools. Install with sudo pacman -S inotify-tools if not present.
|
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
KVM — VM & ISO management
ssh kvm-01 "sudo virsh list --all"
ssh kvm-02 "sudo virsh list --all"
ssh kvm-01 "ls -lh /mnt/nas/isos/*[Ii][Ss][Ee]* /var/lib/libvirt/images/*[Ii][Ss][Ee]* /mnt/onboard-ssd/isos/*[Ii][Ss][Ee]* 2>/dev/null"
ssh kvm-02 "ls -lh /mnt/nas/isos/*[Ii][Ss][Ee]* /mnt/ssd/libvirt/images/*[Ii][Ss][Ee]* 2>/dev/null"
sudo virsh console <vm-name> # Escape: Ctrl+]
ssh kvm-01 "mount | grep nas; ls /mnt/"
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
USB-C / Thunderbolt Charging Diagnostics
{
echo "=== Power Supply ==="
cat /sys/class/power_supply/*/status
echo ""
cat /sys/class/power_supply/*/type
echo ""
echo "=== UPower ==="
upower -d | grep -E 'state|percentage|energy-rate|voltage'
echo ""
echo "=== dmesg (typec/thunderbolt/PD) ==="
sudo dmesg | grep -iE 'typec|thunderbolt|ucsi|PD|power.delivery|charging' | tail -20
echo ""
echo "=== Pacman log (kernel/typec) ==="
grep -iE 'thunderbolt|typec|ucsi|^.*upgraded linux ' /var/log/pacman.log | tail -20
} | tee /tmp/INC-$(date +%F)-usbc-charging.txt
Pattern: { } groups commands into a single stdout stream. tee writes to file AND displays on screen. Reusable for any multi-command evidence capture — change the commands inside, keep the structure.
pacman — package inspection
Source: 2026-06-25 — curl error 77 investigation, checking for package upgrades
# Check package version and install date (awk field filter)
pacman -Qi curl | awk '/^Version|^Install Date/'