Compare commits
No commits in common. "main" and "we-have-go-2" have entirely different histories.
main
...
we-have-go
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
13
Cargo.toml
|
@ -9,14 +9,13 @@ repository = "https://github.com/Xe/site"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.5", features = ["headers"] }
|
||||
axum = "0.5"
|
||||
axum-macros = "0.2"
|
||||
axum-extra = "0.3"
|
||||
color-eyre = "0.6"
|
||||
chrono = "0.4"
|
||||
comrak = "0.14.0"
|
||||
comrak = "0.12.1"
|
||||
derive_more = "0.99"
|
||||
dirs = "4"
|
||||
envy = "0.4"
|
||||
estimated_read_time = "1"
|
||||
futures = "0.3"
|
||||
|
@ -28,13 +27,11 @@ kankyo = "0.3"
|
|||
lazy_static = "1.4"
|
||||
log = "0.4"
|
||||
lol_html = "0.3"
|
||||
maud = { version = "0.23.0", features = ["axum"] }
|
||||
mime = "0.3.0"
|
||||
prometheus = { version = "0.13", default-features = false, features = ["process"] }
|
||||
rand = "0"
|
||||
regex = "1"
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
serde_dhall = "0.11.2"
|
||||
serde_dhall = "0.11.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_yaml = "0.8"
|
||||
sitemap = "0.4"
|
||||
|
@ -48,11 +45,9 @@ xml-rs = "0.8"
|
|||
url = "2"
|
||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||
|
||||
xesite_types = { path = "./lib/xesite_types" }
|
||||
|
||||
# workspace dependencies
|
||||
cfcache = { path = "./lib/cfcache" }
|
||||
xe_jsonfeed = { path = "./lib/jsonfeed" }
|
||||
jsonfeed = { path = "./lib/jsonfeed" }
|
||||
mi = { path = "./lib/mi" }
|
||||
patreon = { path = "./lib/patreon" }
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ tags:
|
|||
---
|
||||
|
||||
[*Last time in the christine dot website cinematic
|
||||
universe:*](https://xeiaso.net/blog/unix-domain-sockets-2021-04-01)
|
||||
universe:*](https://christine.website/blog/unix-domain-sockets-2021-04-01)
|
||||
|
||||
*Unix sockets started to be used to grace the cluster. Things were at peace.
|
||||
Then, a realization came through:*
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
---
|
||||
title: "My Stance on Toxicity About Programming Languages"
|
||||
date: 2022-05-23
|
||||
tags:
|
||||
- toxicity
|
||||
- culture
|
||||
---
|
||||
|
||||
I have been toxic and hateful in the past about programming language choice. I
|
||||
now realize this is a mistake. I am sorry if my being toxic about programming
|
||||
languages has harmed you.
|
||||
|
||||
By toxic, I mean doing things or saying things that imply people are lesser for
|
||||
having different experience and preferences about programming languages. I have
|
||||
seen people imply that using languages like PHP or Node.js means that they are
|
||||
idiots or similar. This is toxic behavior and I do not want to be a part of it
|
||||
in the future.
|
||||
|
||||
I am trying to not be toxic about programming languages in the future. Each
|
||||
programming language is made to solve the tasks it was designed to solve and
|
||||
being toxic about it helps nobody. By being toxic about programming languages
|
||||
like this, I only serve to spread toxicity and then see it be repeated as the
|
||||
people that look up to me as a role model will then strive to repeat my
|
||||
behavior. This cannot continue. I do not want my passion projects to become
|
||||
synonymous with toxicity and vitriol. I do not want to be known as the person
|
||||
that hates $PROGRAMMING_LANGUAGE. I want to break the cycle.
|
||||
|
||||
With this, I want to confirm that I will not write any more attack articles
|
||||
about programming languages. I am doing my best to ensure that this will also
|
||||
spread to my social media actions, conference talks and as many other things as
|
||||
I can.
|
||||
|
||||
I challenge all of you readers to take this challenge too. Don't spread toxicity
|
||||
about programming languages. All of the PHP hate out there is a classic example
|
||||
of this. PHP is a viable programming language that is used by a large percentage
|
||||
of the internet. By insinuating that everyone using PHP is inferior (or worse)
|
||||
you only serve to push people away and worst case cause them to be toxic about
|
||||
the things you like. Toxicity breeds toxicity and the best way to stop it is to
|
||||
be the one to break the cycle and have others follow in your footsteps.
|
||||
|
||||
I have been incredibly toxic about PHP in the past. PHP is one of if not the
|
||||
most widely used programming languages for writing applications that run on a
|
||||
web server. Its design makes it dead simple to understand how incoming HTTP
|
||||
requests relate to files on the disk. There is no compile step. The steps to
|
||||
make a change are to open the file on the server, make the change you want to
|
||||
see and press F5. This is a developer experience that is unparalleled in most
|
||||
HTTP frameworks that I've seen in other programming environments. PHP users
|
||||
deserve better than to be hated on. PHP is an incredibly valid choice and I'm
|
||||
sure that with the right linters and human review in the mix it can be as secure
|
||||
as "properly written" services in Go, Java and Rust.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="enby">Take the "don't be toxic about programming
|
||||
languages" challenge! Just stop with the hate, toxicity and vitriol. Our jobs
|
||||
are complicated enough already. Being toxic to eachother about how we decide to
|
||||
solve problems is a horrible life decision at the least and actively harmful to
|
||||
people's careers at most. Just stop.</xeblog-conv>
|
||||
|
||||
---
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">This post is not intended as a sub-blog.
|
||||
If you feel that this post is calling you out, please don't take this
|
||||
personally. There is a lot of toxicity out there and it will take a long time to
|
||||
totally disarm it, even with people dedicated to doing it. This is an adaptation
|
||||
of [this twitter
|
||||
thread](https://twitter.com/theprincessxena/status/1527765025561186304).</xeblog-conv>
|
|
@ -1,175 +0,0 @@
|
|||
---
|
||||
title: "Anbernic Win600 First Impressions"
|
||||
date: 2022-07-14
|
||||
series: reviews
|
||||
---
|
||||
|
||||
Right now PC gaming is largely a monopoly centered around Microsoft Windows.
|
||||
Many PC games only support Windows and a large fraction of them use technical
|
||||
means to prevent gamers on other platforms from playing those games. In 2021,
|
||||
Valve introduced the [Steam Deck](https://www.steamdeck.com/en/) as an
|
||||
alternative to that monopoly. There's always been a small, underground market
|
||||
for handheld gaming PCs that let you play PC games on the go, but it's always
|
||||
been a very niche market dominated by a few big players that charge a lot of
|
||||
money relative to the game experience they deliver. The Steam Deck radically
|
||||
changed this equation and it's still on backorder to this day. This has made
|
||||
other manufacturers take notice and one of them was Anbernic.
|
||||
|
||||
[Anbernic](https://anbernic.com/) is a company that specializes in making retro
|
||||
emulation handheld gaming consoles. Recently they released their
|
||||
[Win600](https://anbernic.com/products/new-anbernic-win600) handheld. It has a
|
||||
Radeon Silver 3020e or a Radeon Silver 3050e and today I am going to give you my
|
||||
first impressions of it. I have the 3050e version.
|
||||
|
||||
<xeblog-conv name="Mara" mood="happy">A review of the Steam Deck is coming up
|
||||
soon!</xeblog-conv>
|
||||
|
||||
One of the real standout features of this device is that Anbernic has been
|
||||
working with Valve to allow people to run SteamOS on it! This makes us all one
|
||||
step closer to having a viable competitor to Windows for gaming. SteamOS is
|
||||
fantastic and has revolutionized gaming on Linux. It's good to see it coming to
|
||||
more devices.
|
||||
|
||||
## Out of the box
|
||||
|
||||
I ordered my Win600 about 3 hours after sales opened. It arrived in a week and
|
||||
came in one of those china-spec packages made out of insulation. If you've ever
|
||||
ordered things from AliExpress you know what I'm talking about. It's just a
|
||||
solid mass of insulation.
|
||||
|
||||
[![The console siting on my desk with its charging brick and included cable](https://cdn.xeiaso.net/file/christine-static/img/FXozAEjUsAQEg9d-smol.jpeg)](https://cdn.xeiaso.net/file/christine-static/img/FXozAEjUsAQEg9d.jpeg)
|
||||
|
||||
The unboxing experience was pretty great. The console came with:
|
||||
|
||||
* The console
|
||||
* A box containing the charger and cable
|
||||
* A slip of paper telling you how to set up windows without a wifi connection
|
||||
* A screen protector and cleaning cloth (my screen protector was broken in the
|
||||
box, so much for all that insulation lol)
|
||||
* A user manual that points out obvious things about your device
|
||||
|
||||
One of the weirder things about this device is the mouse/gamepad slider on the
|
||||
side. It changes the USB devices on the system and makes the gamepad either act
|
||||
like an xinput joypad or a mouse and keyboard. The mouse and keyboard controls
|
||||
are strange. Here are the controls I have discovered so far:
|
||||
|
||||
* R1 is right click
|
||||
* L1 is left click
|
||||
* A is enter
|
||||
* The right stick very slowly skitters the mouse around the screen
|
||||
* The left stick is a super aggressive scroll wheel
|
||||
|
||||
Figuring out these controls on the fly without any help from the manual meant
|
||||
that I had taken long enough in the setup screen that [Cortana started to pipe
|
||||
up](https://youtu.be/yn6bSm9HXFg) and guided me through the setup process. This
|
||||
was not fun. I had to connect an external keyboard to finish setup.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="coffee">This is probably not Anbernic's fault.
|
||||
Windows is NOT made for smaller devices like this and oh god it
|
||||
shows.</xeblog-conv>
|
||||
|
||||
## Windows 10 "fun"
|
||||
|
||||
There is also a keyboard button on the side. When you are using windows this
|
||||
button summons a soft keyboard. Not the nice to use modern soft keyboard though,
|
||||
the legacy terrible soft keyboard that Microsoft has had for forever and never
|
||||
really updated. Using it is grating, like rubbing sandpaper all over your hands.
|
||||
This made entering in my Wi-Fi password an adventure. It took my husband and I
|
||||
15 minutes to get the device to connect to Wi-Fi. 15 minutes to connect to
|
||||
Wi-Fi.
|
||||
|
||||
Once it was connected to Wi-Fi, I tried to update the system to the latest
|
||||
version of windows. The settings update crashed. Windows Update's service also
|
||||
crashed. Windows Update also randomly got stuck trying to start the installation
|
||||
process for updates. Once updates worked and finished installing, I rebooted.
|
||||
|
||||
I tried to clean up the taskbar by disabling all of the random icons that
|
||||
product managers at Microsoft want you to see. The Cortana button was stuck on
|
||||
and I was unable to disable it. Trying to hide the Windows meet icon crashed
|
||||
explorer.exe. I don't know what part of this is Windows going out of its way to
|
||||
mess with me (I'm cursed) and what part of it is Windows really not being
|
||||
optimized for this hardware in any sense of the way.
|
||||
|
||||
Windows is really painful on this device. It's obvious that Windows was not made
|
||||
with this device in mind. There are buttons to hack around this (but not as far
|
||||
as the task manager button I've seen on other handhelds), but overall trying to
|
||||
use Windows with a game console is like trying to saw a log with a pencil
|
||||
sharpener. It's just the wrong tool for the job. Sure you _can_ do it, but _can_
|
||||
and _should_ are different words in English.
|
||||
|
||||
Another weird thing about Windows on this device is that the screen only reports
|
||||
a single display mode: 1280x720. It has no support for lower resolutions to run
|
||||
older games that only work on those lower resolutions. In most cases this will
|
||||
be not an issue, but if you want to lower the resolution of a game to squeeze
|
||||
more performance out then you may have issues.
|
||||
|
||||
## Steam
|
||||
|
||||
In a moment of weakness, I decided to start up Steam. Steam defaulted to Big
|
||||
Picture mode and its first-time-user-experience made me set up Wi-Fi again.
|
||||
There was no way to bypass it. I got out my moonlander again and typed in my
|
||||
Wi-Fi password again, and then I downloaded Sonic Adventure 2 as a test for how
|
||||
games feel on it. Sonic Adventure 2 is a very lightweight game (you can play it
|
||||
for like 6.5 hours on a full charge of the Steam Deck) and I've played it to
|
||||
_death_ over the years. I know how the game _should_ feel.
|
||||
|
||||
[![The starting screen of City Escape in Sonic Adventure 2, with the console propped up with a Steam Controller](https://cdn.xeiaso.net/file/christine-static/img/FXpIjhwUIAUEujg-smol.jpeg)](https://cdn.xeiaso.net/file/christine-static/img/FXpIjhwUIAUEujg.jpeg)
|
||||
|
||||
City Escape ran at a perfect 60 FPS at the device's native resolution. The main
|
||||
thing I noticed though was the position of the analog sticks. Based on the
|
||||
design of the device, I'm pretty sure they were going for something with a
|
||||
PlayStation DualShock 4 layout with the action buttons on the top and the sticks
|
||||
on the bottom. The sticks are too far down on the device. Playing Sonic
|
||||
Adventure 2 was kind of painful.
|
||||
|
||||
## SteamOS
|
||||
|
||||
So I installed SteamOS on the device. Besides a weird issue with 5 GHZ Wi-Fi not
|
||||
working and updates requiring me to reboot the device IMMEDIATELY after
|
||||
connecting to Wi-Fi, it works great. I can install games and they run. The DPI
|
||||
for SteamOS is quite wrong though. All the UI elements are painfully small. For
|
||||
comparison, I put my Steam Deck on the same screen as I had on the Win600. The
|
||||
Steam Deck is on top and the Win600 is on the bottom.
|
||||
|
||||
[![The game overview for Sonic Adventure 2 on both the Steam Deck and Anbernic Win600](https://f001.backblazeb2.com/file/christine-static/img/FXqSz_tVsAAU0wf-smol.jpeg)](https://f001.backblazeb2.com/file/christine-static/img/FXqSz_tVsAAU0wf.jpeg)
|
||||
|
||||
Yeah. It leaves things to be desired.
|
||||
|
||||
When I had SteamOS set up, I did find something that makes the Win600 slightly
|
||||
better than the Steam Deck. When you are adding games to Steam with Emulation
|
||||
Station you need to close the Steam client to edit the leveldb files that Steam
|
||||
uses to track what games you can launch. On the Steam Deck, the Steam client
|
||||
also enables the built-in controllers to act as a keyboard and mouse. This means
|
||||
that you need to poke around and pray with the touchscreen to get EmuDeck games
|
||||
up and running. The mouse/controller switch on the Win600 makes this slightly
|
||||
more convenient because the controllers can always poorly act as a mouse and
|
||||
keyboard.
|
||||
|
||||
When you are in KDE on the Win600, you don't get a soft keyboard at all. This is
|
||||
mildly inconvenient, but can be fixed with the moonlander yet again. Here's a
|
||||
screenshot of what my KDE desktop on the Win600 looks like:
|
||||
|
||||
[![My SteamOS desktop on the Win600, showing Crossette from Xenoblade Chronicles 2 center frame](https://f001.backblazeb2.com/file/christine-static/img/Screenshot_20220714_144655-smol.jpg)](https://f001.backblazeb2.com/file/christine-static/img/Screenshot_20220714_144655.png)
|
||||
|
||||
Overall, SteamOS is a lot more ergonomic in my opinion and will let you play
|
||||
games to your heart's content.
|
||||
|
||||
The D-pad feels really good. I love how it responds. When I did a little bit of
|
||||
Sonic Mania I never felt like I was inaccurate. There were some weird audio
|
||||
hitches on Sonic Mania though where the music would cut out randomly. Not sure
|
||||
what's going on with that. I could play through entire Pokemon games with that
|
||||
D-pad.
|
||||
|
||||
## Conclusions for now
|
||||
|
||||
Overall I'm getting the feeling that this device is _okay_. It's not great, it's
|
||||
not terrible, but it's okay. I need to get some more experience with it, but so
|
||||
far it seems that this device really does have a weight class and oh god if you
|
||||
play a game outside its weight class your UX goes to shit instantly. The battery
|
||||
life leaves _a lot_ to be desired so far. However it does work. It's hard to not
|
||||
compare this to the Steam Deck, but it's so much less in comparison to the Steam
|
||||
Deck.
|
||||
|
||||
I don't know how I feel about this device. I'm not sure it's worth the money. I
|
||||
need to get more experience with it. I'll have a better sense of all this when I
|
||||
write my full review. Stay tuned for that!
|
|
@ -21,7 +21,7 @@ up being the _worst_ experience that I have using an aarch64 MacBook.
|
|||
[This website](https://github.com/Xe/site) is a fairly complicated webapp
|
||||
written in Rust. As such it makes for a fairly decent compile stress test. I'm
|
||||
going to do a compile test against my [Ryzen
|
||||
3600](https://xeiaso.net/blog/nixos-desktop-flow-2020-04-25) with this M1
|
||||
3600](https://christine.website/blog/nixos-desktop-flow-2020-04-25) with this M1
|
||||
MacBook Air.
|
||||
|
||||
My tower is running this version of Rust:
|
||||
|
|
|
@ -181,7 +181,7 @@ server, my kubernetes cluster and my dokku server:
|
|||
- hlang -> https://h.christine.website
|
||||
- mi -> https://mi.within.website
|
||||
- printerfacts -> https://printerfacts.cetacean.club
|
||||
- xesite -> https://xeiaso.net
|
||||
- xesite -> https://christine.website
|
||||
- graphviz -> https://graphviz.christine.website
|
||||
- idp -> https://idp.christine.website
|
||||
- oragono -> ircs://irc.within.website:6697/
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
---
|
||||
title: "Site Update: The Big Domain Move To xeiaso.net"
|
||||
date: 2022-05-28
|
||||
tags:
|
||||
- dns
|
||||
---
|
||||
|
||||
Hello all!
|
||||
|
||||
If you take a look in the URL bar of your browser (or on the article URL section
|
||||
of your feed reader), you should see that there is a new domain name! Welcome to
|
||||
[xeiaso.net](https://xeiaso.net)!
|
||||
|
||||
Hopefully nothing broke in the process of moving things over, I tried to make
|
||||
sure that everything would forward over and today I'm going to explain how I did
|
||||
that.
|
||||
|
||||
I have really good SEO on my NixOS articles, and for my blog in general. I did
|
||||
not want to risk tanking that SEO when I moved domain names, so I have been
|
||||
putting this off for the better part of a year. As for why now? I got tired of
|
||||
internets complaning that the URL was "christine dot website" when I wanted to
|
||||
be called "Xe". Now you have no excuse.
|
||||
|
||||
So the first step was to be sure that everything got forwarded over to the new
|
||||
domain. After buying the domain name and setting everything up in Cloudflare
|
||||
(including moving my paid plan over), I pointed the new domain at my server and
|
||||
then set up a new NixOS configuration block to have that domain name point to my
|
||||
site binary:
|
||||
|
||||
```nix
|
||||
services.nginx.virtualHosts."xeiaso.net" = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://unix:${toString cfg.sockPath}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
forceSSL = cfg.useACME;
|
||||
useACMEHost = "xeiaso.net";
|
||||
extraConfig = ''
|
||||
access_log /var/log/nginx/xesite.access.log;
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
After that was working, I then got a list of all the things that probably
|
||||
shouldn't be redirected from. In most cases, most HTTP clients should do the
|
||||
right thing when getting a permanent redirect to a new URL. However, we live in
|
||||
a fallen world where we cannot expect clients to do the right thing. Especially
|
||||
RSS feed readers.
|
||||
|
||||
So I made a list of all the things that I was afraid to make permanent redirects
|
||||
for and here it is:
|
||||
|
||||
* `/jsonfeed` - a JSONFeed package for Go
|
||||
([docs](https://pkg.go.dev/christine.website/jsonfeed)), I didn't want to
|
||||
break builds by issuing a permanent redirect that would not match the
|
||||
[go.mod](https://tulpa.dev/Xe/jsonfeed/src/branch/master/go.mod) file.
|
||||
* `/.within/health` - the healthcheck route used by monitoring. I didn't want to
|
||||
find out if NodePing blew up on a 301.
|
||||
* `/.within/website.within.xesite/new_post` - the URL used by the [Android
|
||||
app](https://play.google.com/store/apps/details?id=website.christine.xesite)
|
||||
widget to let you know when a new post is published. I didn't want to find out
|
||||
if Android's HTTP library handles redirects properly or not.
|
||||
* `/blog.rss` - RSS feed readers are badly implemented. I didn't want to find
|
||||
out if it would break people's feeds entirely. I actually care about people
|
||||
that read this blog over RSS and I'm sad that poorly written feed readers
|
||||
punish this server so much.
|
||||
* `/blog.atom` - See above.
|
||||
* `/blog.json` - See above.
|
||||
|
||||
Now that I have the list of URLs to not forward, I can finally write the small
|
||||
bit of Nginx config that will set up permanent forwards (HTTP status code 301)
|
||||
for every link pointing to the old domain. It will look something like this:
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
return 301 https://xeiaso.net$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">Note that it's using `$request_uri` and
|
||||
not just `$uri`. If you use `$uri` you run the risk of [CRLF
|
||||
injection](https://reversebrain.github.io/2021/03/29/The-story-of-Nginx-and-uri-variable/),
|
||||
which will allow any random attacker to inject HTTP headers into incoming
|
||||
requests. This is not a good thing to have happen, to say the
|
||||
least.</xeblog-conv>
|
||||
|
||||
So I wrote a little bit of NixOS config that automatically bridges the gap:
|
||||
|
||||
```nix
|
||||
services.nginx.virtualHosts."christine.website" = let proxyOld = {
|
||||
proxyPass = "http://unix:${toString cfg.sockPath}";
|
||||
proxyWebsockets = true;
|
||||
}; in {
|
||||
locations."/jsonfeed" = proxyOld;
|
||||
locations."/.within/health" = proxyOld;
|
||||
locations."/.within/website.within.xesite/new_post" = proxyOld;
|
||||
locations."/blog.rss" = proxyOld;
|
||||
locations."/blog.atom" = proxyOld;
|
||||
locations."/blog.json" = proxyOld;
|
||||
locations."/".extraConfig = ''
|
||||
return 301 https://xeiaso.net$request_uri;
|
||||
'';
|
||||
forceSSL = cfg.useACME;
|
||||
useACMEHost = "christine.website";
|
||||
extraConfig = ''
|
||||
access_log /var/log/nginx/xesite_old.access.log;
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
This will point all the scary paths to the site itself and have
|
||||
`https://christine.website/whatever` get forwarded to
|
||||
`https://xeiaso.net/whatever`, this makes sure that every single link that
|
||||
anyone has ever posted will get properly forwarded. This makes link rot
|
||||
literally impossible, and helps ensure that I keep my hard-earned SEO.
|
||||
|
||||
I also renamed my email address to `me@xeiaso.net`. Please update your address
|
||||
books and spam filters accordingly. Also update my name to `Xe Iaso` if you
|
||||
haven't already.
|
||||
|
||||
I've got some projects in the back burner that will make this blog even better!
|
||||
Stay tuned and stay frosty.
|
||||
|
||||
What was formerly known as the "christine dot website cinematic universe" is now
|
||||
known as the "xeiaso dot net cinematic universe".
|
|
@ -78,7 +78,7 @@ for this:
|
|||
|
||||
```
|
||||
Xe Iaso (zi ai-uh-so)
|
||||
https://xeiaso.net
|
||||
https://christine.website
|
||||
|
||||
.i la budza pu cusku lu
|
||||
<<.i ko snura .i ko kanro
|
||||
|
|
|
@ -36,7 +36,7 @@ Your website should include at least the following things:
|
|||
- Links to or words about projects of yours that you are proud of
|
||||
- Some contact information (an email address is a good idea too)
|
||||
|
||||
If you feel comfortable doing so, I'd also suggest putting your [resume](https://xeiaso.net/resume)
|
||||
If you feel comfortable doing so, I'd also suggest putting your [resume](https://christine.website/resume)
|
||||
on this site too. Even if it's just got your foodservice jobs or education
|
||||
history (including your high school diploma if need be).
|
||||
|
||||
|
@ -47,7 +47,7 @@ not.
|
|||
## Make a Tech Blog On That Site
|
||||
|
||||
This has been the single biggest thing to help me grow professionally. I regularly
|
||||
put [articles](https://xeiaso.net/blog) on my blog, sometimes not even about
|
||||
put [articles](https://christine.website/blog) on my blog, sometimes not even about
|
||||
technology topics. Even if you are writing about your take on something people have
|
||||
already written about, it's still good practice. Your early posts are going to be
|
||||
rough. It's normal to not be an expert when starting out in a new skill.
|
||||
|
|
|
@ -54,7 +54,7 @@ by it. That attempt to come out failed and I was put into Christian
|
|||
writing down my thoughts in a journal to this day.
|
||||
|
||||
So that day I hit "send" on [the
|
||||
email](https://xeiaso.net/blog/coming-out-2015-12-01) was mortally
|
||||
email](https://christine.website/blog/coming-out-2015-12-01) was mortally
|
||||
terrifying. All that fear from so long ago came raging up to the surface and I
|
||||
was left in a crying and vulnerable state. However it ended up being a good kind
|
||||
of cry, the healing kind.
|
||||
|
|
|
@ -21,7 +21,7 @@ named [dyson][dyson] in order to help me manage Terraform as well as create
|
|||
Kubernetes manifests from [a template][template]. This works for the majority of
|
||||
my apps, but it is difficult to extend at this point for a few reasons:
|
||||
|
||||
[cultk8s]: https://xeiaso.net/blog/the-cult-of-kubernetes-2019-09-07
|
||||
[cultk8s]: https://christine.website/blog/the-cult-of-kubernetes-2019-09-07
|
||||
[dyson]: https://github.com/Xe/within-terraform/tree/master/dyson
|
||||
[template]: https://github.com/Xe/within-terraform/blob/master/dyson/src/dysonPkg/deployment_with_ingress.yaml
|
||||
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
---
|
||||
title: Writing Coherently At Scale
|
||||
date: 2022-06-29
|
||||
tags:
|
||||
- writing
|
||||
vod:
|
||||
youtube: https://youtu.be/pDOoqqu06-8
|
||||
twitch: https://www.twitch.tv/videos/1513874389
|
||||
---
|
||||
|
||||
As someone who does a lot of writing, I have been asked how to write about
|
||||
things. I have been asked about it enough that I am documenting this here so you
|
||||
can all understand my process. This is not a prescriptive system that you must
|
||||
do in order to make Quality Content™️, this is what I do.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="coffee">I honestly have no idea if this is a
|
||||
"correct" way of doing things, but it seems to work well enough. Especially so
|
||||
if you are reading this.</xeblog-conv>
|
||||
|
||||
<xeblog-hero file="great-wave-cyberpunk" prompt="the great wave off of kanagawa, cyberpunk, hanzi inscription"></xeblog-hero>
|
||||
|
||||
## The Planning Phase
|
||||
|
||||
To start out the process of writing about something, I usually like to start
|
||||
with the end goal in mind. If I am writing about an event or technology thing,
|
||||
I'll start out with a goal that looks something like this:
|
||||
|
||||
> Explain a split DNS setup and its advantages and weaknesses so that people can
|
||||
> make more informed decisions about their technical setups.
|
||||
|
||||
It doesn't have to be very complicated or intricate. Most of the complexity
|
||||
comes up naturally during the process of writing the intermediate steps. Think
|
||||
about the end goal or what you want people to gain from reading the article.
|
||||
|
||||
I've also found it helps to think about the target audience and assumed skills
|
||||
of the reader. I'll usually list out the kind of person that would benefit from
|
||||
this the most and how it will help them. Here's an example:
|
||||
|
||||
> The reader is assumed to have some context about what DNS is and wants to help
|
||||
> make their production environment more secure, but isn't totally clear on how
|
||||
> it helps and what tradeoffs are made.
|
||||
|
||||
State what the reader is to you and how the post benefits them. Underthink it.
|
||||
It's tempting to overthink this, but really don't. You can overthink the
|
||||
explanations later.
|
||||
|
||||
### The Outline
|
||||
|
||||
Once I have an end goal and the target audience in mind, then I make an outline
|
||||
of what I want the post to contain. This outline will have top level items for
|
||||
generic parts of the article or major concepts/steps and then I will go in and
|
||||
add more detail inside each top level item. Here is an example set of top level
|
||||
items for that split DNS post:
|
||||
|
||||
```markdown
|
||||
- Introduction
|
||||
- Define split DNS
|
||||
- How split DNS is different
|
||||
- Where you can use split DNS
|
||||
- Advantages of split DNS
|
||||
- Tradeoffs of split DNS
|
||||
- Conclusion
|
||||
```
|
||||
|
||||
Each step should build on the last and help you reach towards the end goal.
|
||||
|
||||
After I write the top level outline, I start drilling down into more detail. As
|
||||
I drill down into more detail about a thing, the bullet points get nested
|
||||
deeper, but when topics change then I go down a line. Here's an example:
|
||||
|
||||
```markdown
|
||||
- Introduction
|
||||
- What is DNS?
|
||||
- Domain Name Service
|
||||
- Maps names to IP addresses
|
||||
- Sometimes it does other things, but we're not worrying about that today
|
||||
- Distributed system
|
||||
- Intended to have the same data everywhere in the world
|
||||
- It can take time for records to be usable from everywhere
|
||||
```
|
||||
|
||||
Then I will go in and start filling in the bullet tree with links and references
|
||||
to each major concept or other opinions that people have had about the topic.
|
||||
For example:
|
||||
|
||||
```markdown
|
||||
- Introduction
|
||||
- What is DNS?
|
||||
- Domain Name Service
|
||||
- https://datatracker.ietf.org/doc/html/rfc1035
|
||||
- Maps names to IP addresses
|
||||
- Sometimes it does other things, but we're not worrying about that today
|
||||
- Distributed system
|
||||
- Intended to have the same data everywhere in the world
|
||||
- It can take time for records to be usable from everywhere
|
||||
- https://jvns.ca/blog/2021/12/06/dns-doesn-t-propagate/
|
||||
```
|
||||
|
||||
These help me write about the topic and give me links to add to the post so that
|
||||
people can understand more if they want to. You should spend most of your time
|
||||
writing the outline. The rest is really just restating the outline in sentences.
|
||||
|
||||
## Writing The Post
|
||||
|
||||
After each top level item is fleshed out enough, I usually pick somewhere to
|
||||
start and add some space after a top level item. Then I just start writing. Each
|
||||
top level item usually maps to a few paragraphs / a section of the post. I
|
||||
usually like to have each section have its own little goal / context to it so
|
||||
that readers start out from not understanding something and end up understanding
|
||||
it better. Here's an example:
|
||||
|
||||
> If you have used a computer in the last few decades or so, you have probably
|
||||
> used the Domain Name Service (DNS). DNS maps human-readable names (like
|
||||
> `google.com`) to machine-readable IP addresses (like `182.48.247.12`). Because
|
||||
> of this, DNS is one of the bedrock protocols of the modern internet and it
|
||||
> usually is the cause of most failures in big companies.
|
||||
>
|
||||
> DNS is a globally distributed system without any authentication or way to
|
||||
> ensure that only authorized parties can query IP addresses for specific domain
|
||||
> names. As a consequence of this, this means that anyone can get the IP address
|
||||
> of a given server if they have the DNS name for it. This also means that
|
||||
> updating a DNS record can take a nontrivial amount of time to be visible from
|
||||
> everywhere in the world.
|
||||
>
|
||||
> Instead of using public DNS records for internal services, you can set up a
|
||||
> split DNS configuration so that you run an internal DNS server that has your
|
||||
> internal service IP addresses obscured away from the public internet. This
|
||||
> means that attackers can't get their hands on the IP addresses of your
|
||||
> services so that they are harder to attack. In this article, I'm going to
|
||||
> spell out how this works, the advantages of this setup, the tradeoffs made in
|
||||
> the process and how you can implement something like this for yourself.
|
||||
|
||||
In the process of writing, I will find gaps in the outline and just fix it by
|
||||
writing more words than the outline suggested. This is okay, and somewhat
|
||||
normal. Go with the flow.
|
||||
|
||||
I expand each major thing into its component paragraphs and will break things up
|
||||
into sections with markdown headers if there is a huge change in topics. Adding
|
||||
section breaks can also help people stay engaged with the post. Giant walls of
|
||||
text are hard to read and can make people lose focus easily.
|
||||
|
||||
Another trick I use to avoid my posts being giant walls of text is what I call
|
||||
"conversation snippets". These look like this:
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">These are words and I am saying
|
||||
them!</xeblog-conv>
|
||||
|
||||
I use them for both creating [Socratic
|
||||
dialogue](https://en.wikipedia.org/wiki/Socratic_dialogue) and to add prose
|
||||
flair to my writing. I am more of a prose writer [by
|
||||
nature](https://xeiaso.net/blog/the-oasis), and I find that this mix allows me
|
||||
to keep both technical and artistic writing up to snuff.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="enby">Amusingly, I get asked if the characters
|
||||
in my blog are separate people all giving their input into things. They are
|
||||
characters, nothing more. If you ever got an impression otherwise, then I have
|
||||
done my job as a writer _incredibly well_.</xeblog-conv>
|
||||
|
||||
Just flesh things out and progressively delete parts of the outline as you go.
|
||||
It gets easier.
|
||||
|
||||
### Writing The Conclusion
|
||||
|
||||
I have to admit, I really suck at writing conclusions. They are annoying for me
|
||||
to write because I usually don't know what to put there. Sometimes I won't even
|
||||
write a conclusion at all and just end the article there. This doesn't always
|
||||
work though.
|
||||
|
||||
A lot of the time when I am describing how to do things I will end the article
|
||||
with a "call to action". This is a few sentences that encourages the reader to
|
||||
try the thing that I've been writing about out for themselves. If I was turning
|
||||
that split DNS article from earlier into a full article, the conclusion
|
||||
could look something like this:
|
||||
|
||||
> ---
|
||||
>
|
||||
> If you want an easy way to try out a split DNS configuration, install
|
||||
> [Tailscale](https://tailscale.com/) on a couple virtual machines and enable
|
||||
> [MagicDNS](https://tailscale.com/kb/1081/magicdns/). This will set up a split
|
||||
> DNS configuration with a domain that won't resolve globally, such as
|
||||
> `hostname.example.com.beta.tailscale.net`, or just `hostname` for short.
|
||||
>
|
||||
> I use this in my own infrastructure constantly. It has gotten to the point
|
||||
> where I regularly forget that Tailscale is involved at all, and become
|
||||
> surprised when I can't just access machines by name.
|
||||
>
|
||||
> A split DNS setup isn't a security feature (if anything, it's more of an
|
||||
> obscurity feature), but you can use it to help administrate your systems by
|
||||
> making your life easier. You can update records on your own schedule and you
|
||||
> don't have to worry about outside attackers getting the IP addresses of your
|
||||
> services.
|
||||
|
||||
I don't like giving the conclusion a heading, so I'll usually use a [horizontal
|
||||
rule (`---` or `<hr
|
||||
/>`)](https://www.coffeecup.com/help/articles/what-is-a-horizontal-rule/) to
|
||||
break it off.
|
||||
|
||||
---
|
||||
|
||||
This is how I write about things. Do you have a topic in mind that you have
|
||||
wanted to write about for a while? Try this system out! If you get something
|
||||
that you like and want feedback on how to make it shine, email me at
|
||||
`iwroteanarticle at xeserv dot us` with either a link to it or the draft
|
||||
somehow. I'll be sure to read it and reply back with both what I liked and some
|
||||
advice on how to make it even better.
|
|
@ -82,7 +82,7 @@ terrible idea. Microservices architectures are not planned. They are an
|
|||
evolutionary result, not a fully anticipated feature.
|
||||
|
||||
Finally, don’t “design for the future”. The future [hasn’t happened
|
||||
yet](https://xeiaso.net/blog/all-there-is-is-now-2019-05-25). Nobody
|
||||
yet](https://christine.website/blog/all-there-is-is-now-2019-05-25). Nobody
|
||||
knows how it’s going to turn out. The future is going to happen, and you can
|
||||
either adapt to it as it happens in the Now or fail to. Don’t make things overly
|
||||
modular, that leads to insane things like dynamically linking parts of an
|
||||
|
|
|
@ -279,7 +279,7 @@ step.
|
|||
The deploy step does two small things. First, it installs
|
||||
[dhall-yaml](https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-yaml)
|
||||
for generating the Kubernetes manifest (see
|
||||
[here](https://xeiaso.net/blog/dhall-kubernetes-2020-01-25)) and then
|
||||
[here](https://christine.website/blog/dhall-kubernetes-2020-01-25)) and then
|
||||
runs
|
||||
[`scripts/release.sh`](https://tulpa.dev/cadey/printerfacts/src/branch/master/scripts/release.sh):
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ Hopefully Valve can improve the state of VR on Linux with the "deckard".
|
|||
|
||||
2021 has had some banger releases. Halo Infinite finally dropped. Final Fantasy
|
||||
7 Remake came to PC. [Metroid
|
||||
Dread](https://xeiaso.net/blog/metroid-dread-review-2021-10-10) finally
|
||||
Dread](https://christine.website/blog/metroid-dread-review-2021-10-10) finally
|
||||
came out after being rumored for more than half of my lifetime. Forza Horizon 5
|
||||
raced out into the hearts of millions. Overall, it was a pretty good year to be
|
||||
a gamer.
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
---
|
||||
title: "Fly.io: the Reclaimer of Heroku's Magic"
|
||||
date: 2022-05-15
|
||||
tags:
|
||||
- flyio
|
||||
- heroku
|
||||
vod:
|
||||
twitch: https://www.twitch.tv/videos/1484123245
|
||||
youtube: https://youtu.be/BAgzkKpLVt4
|
||||
---
|
||||
|
||||
Heroku was catalytic to my career. It's been hard to watch the fall from grace.
|
||||
Don't get me wrong, Heroku still _works_, but it's obviously been in maintenance
|
||||
mode for years. When I worked there, there was a goal that just kind of grew in
|
||||
scope over and over without reaching an end state: the Dogwood stack.
|
||||
|
||||
In Heroku each "stack" is the substrate the dynos run on. It encompasses the AWS
|
||||
runtime, the HTTP router, the logging pipeline and a bunch of the other
|
||||
infrastructure like the slug builder and the deployment infrastructure. The
|
||||
three stacks Heroku has used are named after trees: Aspen, Bamboo and Cedar.
|
||||
Every Heroku app today runs on the Cedar stack, and compared to Bamboo it was a
|
||||
generational leap in capability. Cedar was what introduced buildpacks and
|
||||
support for any language under the sun. Prior stacks railroaded you into Ruby on
|
||||
Rails (Heroku used to be a web IDE for making Rails apps). However there were
|
||||
always plans to improve with another generational leap. This ended up being
|
||||
called the "Dogwood stack", but Dogwood never totally materialized because it
|
||||
was too ambitious for Heroku to handle post-acquisition. Parts of Dogwood's
|
||||
roadmap ended up being used in the implementation of Private Spaces, but as a
|
||||
whole I don't expect Dogwood to materialize in Heroku in the way we all had
|
||||
hoped.
|
||||
|
||||
However, I can confidently say that [fly.io](https://fly.io) seems like a viable
|
||||
inheritor of the mantle of responsibility that Heroku has left into the hands of
|
||||
the cloud. fly.io is a Platform-as-a-Service that hosts your applications on top
|
||||
of physical dedicated servers run all over the world instead of being a reseller
|
||||
of AWS. This allows them to get your app running in multiple regions for a lot
|
||||
less than it would cost to run it on Heroku. They also use anycasting to allow
|
||||
your app to use the same IP address globally. The internet itself will load
|
||||
balance users to the nearest instance using BGP as the load balancing
|
||||
substrate.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="enby">People have been asking me what I would
|
||||
suggest using instead of Heroku. I have been unable to give a good option until
|
||||
now. If you are dissatisfied with the neglect of Heroku in the wake of the
|
||||
Salesforce acquisition, take a look at fly.io. Its free tier is super generous.
|
||||
I worked at Heroku and I am beyond satisfied with it. I'm considering using it
|
||||
for hosting some personal services that don't need something like
|
||||
NixOS.</xeblog-conv>
|
||||
|
||||
Applications can be built either using [cloud native
|
||||
buildpacks](https://fly.io/docs/reference/builders/), Dockerfiles or arbitrary
|
||||
docker images that you generated with something like Nix's
|
||||
`pkgs.dockerTools.buildLayeredImage`. This gives you freedom to do whatever you
|
||||
want like the Cedar stack, but at a fraction of the cost. Its default instance
|
||||
size is likely good enough to run the blog you are reading right now and would
|
||||
be able to do that for $2 a month plus bandwidth costs (I'd probably estimate
|
||||
that to be about $3-5, depending on how many times I get on the front page of
|
||||
Hacker News).
|
||||
|
||||
You can have persistent storage in the form of volumes, poke the internal DNS
|
||||
server fly.io uses for service discovery, run apps that use arbitrary TCP/UDP
|
||||
ports (even a DNS server!), connect to your internal network over WireGuard, ssh
|
||||
into your containers, and import Heroku apps into fly.io without having to
|
||||
rebuild them. This is what the Dogwood stack should have been. This represents a
|
||||
generational leap in the capabilities of what a Platform as a Service can do.
|
||||
|
||||
The stream VOD in the footer of this post contains my first impressions using
|
||||
fly.io to try and deploy an app written with [Deno](https://deno.land) to the
|
||||
cloud. I ended up creating a terrible CRUD app on stream using SQLite that
|
||||
worked perfectly beyond expectations. I was able to _restart the app_ and my
|
||||
SQLite database didn't get blown away. I could easily imagine myself combining
|
||||
something like [litestream](https://litestream.io) into my docker images to
|
||||
automate offsite backups of SQLite databases like this. It was magical.
|
||||
|
||||
<xeblog-conv name="Mara" mood="happy">If you've never really used Heroku, for
|
||||
context each dyno has a mutable filesystem. However that filesystem gets blown
|
||||
away every time a dyno reboots. Having something that is mutable and persistent
|
||||
is mind-blowing.</xeblog-conv>
|
||||
|
||||
Everything else you expect out of Heroku works like you'd expect in fly.io. The
|
||||
only things I can see missing are automated Redis hosting by the platform
|
||||
(however this seems intentional as fly.io is generic enough [to just run redis
|
||||
directly for you](https://fly.io/docs/reference/redis/)) and the marketplace.
|
||||
The marketplace being absent is super reasonable, seeing as Heroku's marketplace
|
||||
only really started existing as a result of them being the main game in town
|
||||
with all the mindshare. fly.io is a voice among a chorus, so it's understandable
|
||||
that it wouldn't have the same treatment.
|
||||
|
||||
Overall, I would rate fly.io as a worthy inheritor of Heroku's mantle as the
|
||||
platform as a service that is just _magic_. It Just Works™️. There was no
|
||||
fighting it at a platform level, it just worked. Give it a try.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="enby">Don't worry
|
||||
[@tqbf](https://twitter.com/tqbf), fly.io put in a good showing. I still wanna
|
||||
meet you at some conference.</xeblog-conv>
|
|
@ -8,7 +8,7 @@ series: conlangs
|
|||
|
||||
`h` is a conlang project that I have been working off and on for years. It is infinitely simply teachable, trivial to master and can be used to represent the entire scope of all meaning in any facet of the word. All with a single character.
|
||||
|
||||
This is a continuation from [this post](https://xeiaso.net/blog/the-origin-of-h-2015-12-14). If this post makes sense to you, please let me know and/or schedule a psychologist appointment just to be safe.
|
||||
This is a continuation from [this post](https://christine.website/blog/the-origin-of-h-2015-12-14). If this post makes sense to you, please let me know and/or schedule a psychologist appointment just to be safe.
|
||||
|
||||
## Phonology
|
||||
|
||||
|
|
|
@ -363,14 +363,14 @@ my blog's [JSONFeed](/blog.json):
|
|||
#!/usr/bin/env bash
|
||||
# xeblog-post.sh
|
||||
|
||||
curl -s https://xeiaso.net/blog.json | jq -r '.items[0] | "\(.title) \(.url)"'
|
||||
curl -s https://christine.website/blog.json | jq -r '.items[0] | "\(.title) \(.url)"'
|
||||
```
|
||||
|
||||
At the time of writing this post, here is the output I get from this command:
|
||||
|
||||
```
|
||||
$ ./xeblog-post.sh
|
||||
Anbernic RG280M Review https://xeiaso.net/blog/rg280m-review
|
||||
Anbernic RG280M Review https://christine.website/blog/rg280m-review
|
||||
```
|
||||
|
||||
What else could you do with pipes and redirection? The cloud's the limit!
|
||||
|
|
|
@ -16,7 +16,7 @@ it. This is a sort of spiritual successor to my old
|
|||
ecosystem since then, as well as my understanding of the language.
|
||||
|
||||
[go]: https://golang.org
|
||||
[gswg]: https://xeiaso.net/blog/getting-started-with-go-2015-01-28
|
||||
[gswg]: https://christine.website/blog/getting-started-with-go-2015-01-28
|
||||
|
||||
Like always, feedback is very welcome. Any feedback I get will be used to help
|
||||
make this book even better.
|
||||
|
|
|
@ -20,16 +20,16 @@ for browsers, but I've been using it for server-side tasks.
|
|||
|
||||
I have written more about/with WebAssembly in the past in these posts:
|
||||
|
||||
- https://xeiaso.net/talks/webassembly-on-the-server-system-calls-2019-05-31
|
||||
- https://xeiaso.net/blog/olin-1-why-09-1-2018
|
||||
- https://xeiaso.net/blog/olin-2-the-future-09-5-2018
|
||||
- https://xeiaso.net/blog/land-1-syscalls-file-io-2018-06-18
|
||||
- https://xeiaso.net/blog/templeos-2-god-the-rng-2019-05-30
|
||||
- https://christine.website/talks/webassembly-on-the-server-system-calls-2019-05-31
|
||||
- https://christine.website/blog/olin-1-why-09-1-2018
|
||||
- https://christine.website/blog/olin-2-the-future-09-5-2018
|
||||
- https://christine.website/blog/land-1-syscalls-file-io-2018-06-18
|
||||
- https://christine.website/blog/templeos-2-god-the-rng-2019-05-30
|
||||
|
||||
This is a continuation of the following two posts:
|
||||
|
||||
- https://xeiaso.net/blog/the-origin-of-h-2015-12-14
|
||||
- https://xeiaso.net/blog/formal-grammar-of-h-2019-05-19
|
||||
- https://christine.website/blog/the-origin-of-h-2015-12-14
|
||||
- https://christine.website/blog/formal-grammar-of-h-2019-05-19
|
||||
|
||||
All of the relevant code for h is [here](https://github.com/Xe/x/tree/master/cmd/h).
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ goes into hitting enter on christine.website and this website being loaded.
|
|||
|
||||
## Beginnings
|
||||
|
||||
The user types in `https://xeiaso.net` into the address bar and hits
|
||||
The user types in `https://christine.website` into the address bar and hits
|
||||
enter on the keyboard. This sends a signal over USB to the computer and the
|
||||
kernel polls the USB controller for a new message. It's recognized as from the
|
||||
keyboard. The input is then sent to the browser through an input driver talking
|
||||
|
|
|
@ -46,7 +46,7 @@ the Rust compiler.
|
|||
|
||||
[nixos]: https://nixos.org/nixos/
|
||||
[nix]: https://nixos.org/nix/
|
||||
[howistartnix]: https://xeiaso.net/blog/how-i-start-nix-2020-03-08
|
||||
[howistartnix]: https://christine.website/blog/how-i-start-nix-2020-03-08
|
||||
|
||||
## A new project
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ From time to time, I am outright wrong on my blog. This is one of those times.
|
|||
In my [last post about Nix][nixpost], I didn't see the light yet. I think I do
|
||||
now, and I'm going to attempt to clarify below.
|
||||
|
||||
[nixpost]: https://xeiaso.net/blog/thoughts-on-nix-2020-01-28
|
||||
[nixpost]: https://christine.website/blog/thoughts-on-nix-2020-01-28
|
||||
|
||||
Let's talk about a more simple scenario: writing a service in Go. This service
|
||||
will depend on at least the following:
|
||||
|
|
|
@ -453,7 +453,7 @@ module. Here's how I do it:
|
|||
|
||||
You can add this to your `imports` in your server's `configuration.nix` using
|
||||
[the layout I described in this
|
||||
post](https://xeiaso.net/blog/morph-setup-2021-04-25). This would go in
|
||||
post](https://christine.website/blog/morph-setup-2021-04-25). This would go in
|
||||
the host-specific configuration folder.
|
||||
|
||||
Once you've deployed this to a server, try to open the page in your browser:
|
||||
|
|
|
@ -308,19 +308,19 @@ And then you can register it in your `network.nix` like this:
|
|||
This should help you get your servers wrangled into a somewhat consistent state.
|
||||
From here the following articles may be useful to give you ideas:
|
||||
|
||||
- [Borg Backup Config](https://xeiaso.net/blog/borg-backup-2021-01-09)
|
||||
- [Borg Backup Config](https://christine.website/blog/borg-backup-2021-01-09)
|
||||
- [Nixops Services On Your Home
|
||||
Network](https://xeiaso.net/blog/nixops-services-2020-11-09) (just be
|
||||
Network](https://christine.website/blog/nixops-services-2020-11-09) (just be
|
||||
sure to ignore the part where it mentions `deployment.keys`, you can replace
|
||||
it with the semantically identical
|
||||
[`deployment.secrets`](https://github.com/DBCDK/morph/blob/master/examples/secrets.nix)
|
||||
as described in the morph documentation)
|
||||
- [Prometheus and
|
||||
Aegis](https://xeiaso.net/blog/aegis-prometheus-2021-04-05)
|
||||
Aegis](https://christine.website/blog/aegis-prometheus-2021-04-05)
|
||||
- [My Automagic NixOS Wireguard
|
||||
Setup](https://xeiaso.net/blog/my-wireguard-setup-2021-02-06)
|
||||
Setup](https://christine.website/blog/my-wireguard-setup-2021-02-06)
|
||||
- [Encrypted Secrets with
|
||||
NixOS](https://xeiaso.net/blog/nixos-encrypted-secrets-2021-01-20)
|
||||
NixOS](https://christine.website/blog/nixos-encrypted-secrets-2021-01-20)
|
||||
|
||||
Also feel free to dig around [the `common` folder of my `nixos-configs`
|
||||
repo](https://github.com/Xe/nixos-configs/tree/master/common). There's a bunch
|
||||
|
|
|
@ -3,12 +3,6 @@ title: My Career So Far in Dates/Titles/Salaries
|
|||
date: 2019-03-14
|
||||
---
|
||||
|
||||
<div class="warning"><xeblog-conv name="Cadey" mood="coffee">This post is
|
||||
outdated, see <a href="/salary-transparency">here</a> for more context on why
|
||||
this data is made public. The table on this page will be automatically updated
|
||||
to contain the data on my salary transparency page, but you should prefer that
|
||||
page over this one when possible.</xeblog-conv></div>
|
||||
|
||||
Let this be inspiration to whoever is afraid of trying, failing and being fired.
|
||||
Every single one of these jobs has taught me lessons I've used daily in my
|
||||
career.
|
||||
|
@ -32,7 +26,20 @@ might not want.
|
|||
The following table is a history of my software career by title, date and salary
|
||||
(company names are omitted).
|
||||
|
||||
<xeblog-salary-history></xeblog-salary-history>
|
||||
| Title | Start Date | End Date | Days Worked | Days Between Jobs | Salary | How I Left |
|
||||
|:----- |:---------- |:-------- |:----------- |:----------------- |:------ |:---------- |
|
||||
| Junior Systems Administrator | November 11, 2013 | January 06, 2014 | 56 days | n/a | $50,000/year | Terminated |
|
||||
| Software Engineering Intern | July 14, 2014 | August 27, 2014 | 44 days | 189 days | $35,000/year | Terminated |
|
||||
| Consultant | September 17, 2014 | October 15, 2014 | 28 days | 21 days | $90/hour | Contract Lapsed |
|
||||
| Consultant | October 27, 2014 | Feburary 9, 2015 | 105 days | 12 days | $90/hour | Contract Lapsed |
|
||||
| Site Reliability Engineer | March 30, 2015 | March 7, 2016 | 343 days | 49 days | $125,000/year | Demoted |
|
||||
| Systems Administrator | March 8, 2016 | April 1, 2016 | 24 days | 1 day | $105,000/year | Bad terms |
|
||||
| Member of Technical Staff | April 4, 2016 | August 3, 2016 | 121 days | 3 days | $135,000/year | Bad terms |
|
||||
| Software Engineer | August 24, 2016 | November 22, 2016 | 90 days | 21 days | $105,000/year | Terminated |
|
||||
| Consultant | Feburary 13, 2017 | November 13, 2017 | 273 days | 83 days | don't remember | Hired |
|
||||
| Senior Software Engineer | November 13, 2017 | March 8, 2019 | 480 days | 0 days | $150,000/year | Voulntary quit |
|
||||
| Senior Site Reliability Expert | May 6, 2019 | October 27, 2020 | 540 days | 48 days | CAD$115,000/year (about USD$ 80k and change) | Voluntary quit |
|
||||
| Software Designer | December 14, 2020 | *current* | n/a | n/a | CAD$135,000/year (about USD$ 105k and change) | n/a |
|
||||
|
||||
Even though I've been fired three times, I don't regret my career as it's been
|
||||
thus far. I've been able to work on experimental technology integrating into
|
||||
|
|
|
@ -17,7 +17,7 @@ One thing that I do a lot is run virtual machines. Some of these stick around, a
|
|||
lot of them are very ephemeral. I also like being able to get into these VMs
|
||||
quickly if I want to mess around with a given distribution or OS. Normally I'd
|
||||
run these on [my gaming
|
||||
tower](https://xeiaso.net/blog/nixos-desktop-flow-2020-04-25), however
|
||||
tower](https://christine.website/blog/nixos-desktop-flow-2020-04-25), however
|
||||
this makes my tower very load-bearing. I also want to play games sometimes on my
|
||||
tower, and even though there have been many strides in getting games to run well
|
||||
on Linux it's still not as good as I'd like it to be.
|
||||
|
|
|
@ -58,7 +58,7 @@ la budza pu cusku lu
|
|||
> May you be at peace. May you be happy.
|
||||
- Buddha
|
||||
|
||||
I will be reachable on the internet. See https://xeiaso.net/contact to
|
||||
I will be reachable on the internet. See https://christine.website/contact to
|
||||
see contact information that will help you reach out to me. If you can, please
|
||||
direct replies to me@christine.website, that way I can read them after this
|
||||
account gets disabled.
|
||||
|
@ -70,7 +70,7 @@ From my world to yours,
|
|||
--
|
||||
|
||||
Christine Dodrill
|
||||
https://xeiaso.net
|
||||
https://christine.website
|
||||
|
||||
```
|
||||
la budza pu cusku lu
|
||||
|
|
|
@ -3,7 +3,7 @@ title: New Site
|
|||
date: 2016-12-18
|
||||
---
|
||||
|
||||
This post is now being brought to you by the new and improved [https://xeiaso.net](https://xeiaso.net).
|
||||
This post is now being brought to you by the new and improved [https://christine.website](https://christine.website).
|
||||
This content is [markdown](/api/blog/post?name=new-site-2016-12-18) rendered by
|
||||
[Purescript](http://www.purescript.org/). The old [site](https://github.com/Xe/christine.website)
|
||||
is now being retired in favor of [this one](https://github.com/Xe/site). The old
|
||||
|
|
|
@ -275,13 +275,13 @@ project is using the same tools.
|
|||
project folder I do not have any development tools
|
||||
available.](conversation://Cadey/enby)
|
||||
|
||||
Flakes has the ability to specify this using the `devShells` flake output. You
|
||||
Flakes has the ability to specify this using the `devShell` flake output. You
|
||||
can add it to your `flake.nix` using this:
|
||||
|
||||
```nix
|
||||
# after apps
|
||||
# after defaultApp
|
||||
|
||||
devShells = forAllSystems (system:
|
||||
devShell = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system};
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
|
@ -422,7 +422,7 @@ world. To use a private repo, your flake input URL should look something like
|
|||
this:
|
||||
|
||||
```
|
||||
git+ssh://git@github.com/user/repo?ref=main
|
||||
git+ssh://git@github.com:user/repo
|
||||
```
|
||||
|
||||
[I'm pretty sure you could use private git repos outside of flakes, however it
|
||||
|
|
|
@ -72,7 +72,7 @@ Everything else we'll cover today will build on top of this.
|
|||
Let's look back at the Go [example
|
||||
package](https://github.com/Xe/gohello/blob/caf54cdff7d8dd9bd9df4b3b783a72fe75c9a11e/flake.nix#L31-L54)
|
||||
I walked us through in [the last
|
||||
post](https://xeiaso.net/blog/nix-flakes-1-2022-02-21):
|
||||
post](https://christine.website/blog/nix-flakes-1-2022-02-21):
|
||||
|
||||
```nix
|
||||
# ...
|
||||
|
|
|
@ -140,5 +140,5 @@ for more information.
|
|||
---
|
||||
|
||||
Also happy December! My site has the [snow
|
||||
CSS](https://xeiaso.net/blog/let-it-snow-2018-12-17) loaded for the
|
||||
CSS](https://christine.website/blog/let-it-snow-2018-12-17) loaded for the
|
||||
month. Enjoy!
|
||||
|
|
|
@ -6,7 +6,7 @@ author: ectamorphic
|
|||
|
||||
Recently I got a new VR setup that uses my tower directly instead of the [wifi
|
||||
streaming
|
||||
catastrophe](https://xeiaso.net/blog/convoluted-vrchat-gchat-setup-2021-02-24).
|
||||
catastrophe](https://christine.website/blog/convoluted-vrchat-gchat-setup-2021-02-24).
|
||||
I have a [Valve Index](https://store.steampowered.com/valveindex) and an [AMD
|
||||
RX6700XT](https://www.amd.com/en/products/graphics/amd-radeon-rx-6700-xt) GPU.
|
||||
Some huge advantages of this setup include:
|
||||
|
|
|
@ -5,10 +5,10 @@ date: 2019-01-17
|
|||
|
||||
I found an old backup that contained a few articles from my old [Medium](https://medium.com/@theprincessxena) blog. I have converted them to markdown and added them to the blog archives:
|
||||
|
||||
- 2014-11-28 - [Web Application Development with Beego](https://xeiaso.net/blog/beego-2014-11-28)
|
||||
- 2014-11-20 - [Dependency Hell](https://xeiaso.net/blog/dependency-hell-2014-11-20)
|
||||
- 2014-11-18 - [My Experience with Atom as A Vim User](https://xeiaso.net/blog/atom-as-vim-2014-11-18)
|
||||
- 2014-10-24 - [Instant Development Environments in Docker](https://xeiaso.net/blog/dev-2014-10-24)
|
||||
- 2014-10-20 - [MPD Via Docker](https://xeiaso.net/blog/mpd-docker-2014-10-20)
|
||||
- 2014-11-28 - [Web Application Development with Beego](https://christine.website/blog/beego-2014-11-28)
|
||||
- 2014-11-20 - [Dependency Hell](https://christine.website/blog/dependency-hell-2014-11-20)
|
||||
- 2014-11-18 - [My Experience with Atom as A Vim User](https://christine.website/blog/atom-as-vim-2014-11-18)
|
||||
- 2014-10-24 - [Instant Development Environments in Docker](https://christine.website/blog/dev-2014-10-24)
|
||||
- 2014-10-20 - [MPD Via Docker](https://christine.website/blog/mpd-docker-2014-10-20)
|
||||
|
||||
I hope these are at all useful.
|
||||
|
|
|
@ -4,7 +4,7 @@ date: 2018-09-05
|
|||
series: olin
|
||||
---
|
||||
|
||||
This post is a continuation of [this post](https://xeiaso.net/blog/olin-1-why-09-1-2018).
|
||||
This post is a continuation of [this post](https://christine.website/blog/olin-1-why-09-1-2018).
|
||||
|
||||
Suppose you are given the chance to throw out the world and start from scratch
|
||||
in a minimal environment. You can then work up from nothing and build the world
|
||||
|
|
|
@ -13,7 +13,7 @@ tags:
|
|||
Over the last week or so I've been doing a _lot_ of improvements to [Olin][olin] in order to make it ready to be the kernel for the minimum viable product of [wasmcloud][wasmcloud-hello-world]. Here's an overview of the big things that have happened from version [0.1.1][olin-0.1.1] to version [0.4.0][olin-0.4.0].
|
||||
|
||||
[olin]: https://github.com/Xe/olin
|
||||
[wasmcloud-hello-world]: https://xeiaso.net/blog/wasmcloud-progress-2019-12-08
|
||||
[wasmcloud-hello-world]: https://christine.website/blog/wasmcloud-progress-2019-12-08
|
||||
[olin-0.1.1]: https://github.com/Xe/olin/releases/tag/v0.1.1
|
||||
[olin-0.4.0]: https://github.com/Xe/olin/releases/tag/v0.4.0
|
||||
|
||||
|
@ -31,7 +31,7 @@ As Olin is just a kernel, it needs some work in order to really shine as a true
|
|||
|
||||
Here is what has been done since the [last Olin post][last-olin-post]:
|
||||
|
||||
[last-olin-post]: https://xeiaso.net/blog/olin-2-the-future-09-5-2018
|
||||
[last-olin-post]: https://christine.website/blog/olin-2-the-future-09-5-2018
|
||||
|
||||
* An official, automated build of the example Olin components has been published to the Docker Hub
|
||||
* The Go ABI has been deprecated for the moment
|
||||
|
|
|
@ -13,7 +13,7 @@ In my [last post][pahihelloworld] I mentioned that pa'i was faster than Olin's
|
|||
cwa binary written in go without giving any benchmarks. I've been working on new
|
||||
ways to gather and visualize these benchmarks, and here they are.
|
||||
|
||||
[pahihelloworld]: https://xeiaso.net/blog/pahi-hello-world-2020-02-22
|
||||
[pahihelloworld]: https://christine.website/blog/pahi-hello-world-2020-02-22
|
||||
|
||||
Benchmarking WebAssembly implementations is slightly hard. A lot of existing
|
||||
benchmark tools simply do not run in WebAssembly as is, not to mention inside
|
||||
|
|
|
@ -115,7 +115,7 @@ production-facing servers should probably only be able to be connected to over a
|
|||
VPN of some kind.
|
||||
|
||||
If you want to see more about how to set up WireGuard on NixOS, see
|
||||
[here](https://xeiaso.net/blog/my-wireguard-setup-2021-02-06) for more
|
||||
[here](https://christine.website/blog/my-wireguard-setup-2021-02-06) for more
|
||||
information.
|
||||
|
||||
## Locking Down the Hatches
|
||||
|
@ -130,7 +130,7 @@ I am going to use the word "service" annoyingly vague here. In this world, a
|
|||
"service" is a human-oriented view of "computer does the thing I want it to do".
|
||||
This website you're reading this post on could be one service, and it should
|
||||
have a separate account from other services. See
|
||||
[here](https://xeiaso.net/blog/nixops-services-2020-11-09) for more
|
||||
[here](https://christine.website/blog/nixops-services-2020-11-09) for more
|
||||
information on how to set this up.
|
||||
|
||||
### Lock Down Services Within Systemd
|
||||
|
@ -433,7 +433,7 @@ where I show you how to automatically create an ISO that does all this for you.
|
|||
### Repeatable Base Image with an ISO
|
||||
|
||||
Using the setup I mentioned [in a past
|
||||
post](https://xeiaso.net/blog/my-homelab-2021-06-08), you can create an
|
||||
post](https://christine.website/blog/my-homelab-2021-06-08), you can create an
|
||||
automatic install ISO that will take a blank disk to a state where you can SSH
|
||||
into it and configure it further using a tool like
|
||||
[morph](https://github.com/DBCDK/morph). Take a look at [this
|
||||
|
|
|
@ -9,7 +9,7 @@ tags:
|
|||
- r13y
|
||||
---
|
||||
|
||||
In [the last post](https://xeiaso.net/blog/paranoid-nixos-2021-07-18) we
|
||||
In [the last post](https://christine.website/blog/paranoid-nixos-2021-07-18) we
|
||||
covered a lot of the base groundwork involved in making a paranoid NixOS setup.
|
||||
Today we're gonna throw this into prod by making a base NixOS image with it.
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ closest friends that I can talk about anything with, even what would normally
|
|||
violate an NDA. My closest friends are so close that language isn't even as much
|
||||
of a barrier as it would be otherwise.
|
||||
|
||||
As I've mentioned in the past, [I have tulpas](https://xeiaso.net/blog/what-its-like-to-be-me-2018-06-14).
|
||||
As I've mentioned in the past, [I have tulpas](https://christine.website/blog/what-its-like-to-be-me-2018-06-14).
|
||||
They are people that live with me like roommates inside my body. It really does
|
||||
sound strange or psychotic; but you'll just have to trust me when I say they
|
||||
fundamentally help me live my life, do my job and do other things people
|
||||
|
|
|
@ -14,7 +14,7 @@ My work laptop uses KDE, so I tried out
|
|||
really liked this. I think one of the major differences between how I've been
|
||||
failing at pomodoro in the past and why it's been working now is that I've
|
||||
worked it into my [daily note-taking/TODO
|
||||
workflow](https://xeiaso.net/blog/gtd-on-paper-2021-06-13). I label each
|
||||
workflow](https://christine.website/blog/gtd-on-paper-2021-06-13). I label each
|
||||
pomodoro (my notes call them "Pom" because that isn't something I write often in
|
||||
them) as a section in my notes and then include a few TODO items under it. I'll
|
||||
also add some notes to the pom in case I need them later.
|
||||
|
|
|
@ -49,12 +49,12 @@ Here is an example web app manifest [from my portfolio site](https://github.com/
|
|||
"background_color": "#fa99ca",
|
||||
"display": "standalone",
|
||||
"scope": "/",
|
||||
"start_url": "https://xeiaso.net/",
|
||||
"start_url": "https://christine.website/",
|
||||
"description": "Blog and Resume for Christine Dodrill",
|
||||
"orientation": "any",
|
||||
"icons": [
|
||||
{
|
||||
"src": "https://xeiaso.net/static/img/avatar.png",
|
||||
"src": "https://christine.website/static/img/avatar.png",
|
||||
"sizes": "1024x1024"
|
||||
}
|
||||
]
|
||||
|
@ -65,7 +65,7 @@ If you just want to create a manifest quickly, check out [this](https://app-mani
|
|||
|
||||
## Add Manifest to Your Base HTML Template
|
||||
|
||||
I suggest adding the HTML link for the manifest to the most base HTML template you can, or in the case of a purely client side web app its main `index.html` file, as it needs to be as visible by the client trying to install the app. Adding this is [simple](https://developer.mozilla.org/en-US/docs/Web/Apps/Progressive/Installable_PWAs), assuming you are hosting this manifest on [/static/manifest.json](https://xeiaso.net/static/manifest.json) – simply add it to the <head> section:
|
||||
I suggest adding the HTML link for the manifest to the most base HTML template you can, or in the case of a purely client side web app its main `index.html` file, as it needs to be as visible by the client trying to install the app. Adding this is [simple](https://developer.mozilla.org/en-US/docs/Web/Apps/Progressive/Installable_PWAs), assuming you are hosting this manifest on [/static/manifest.json](https://christine.website/static/manifest.json) – simply add it to the <head> section:
|
||||
|
||||
```html
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
@ -96,7 +96,7 @@ At a high level, consider what assets and pages you want users of your website t
|
|||
* Contact information for the person, company or service running the progressive web app
|
||||
* Any other pages or information you might find useful for users of your website
|
||||
|
||||
For example, I have the following precached for [my portfolio site](https://xeiaso.net):
|
||||
For example, I have the following precached for [my portfolio site](https://christine.website):
|
||||
|
||||
* My homepage (implicitly includes all of the CSS on the site) `/`
|
||||
* My blog index `/blog/`
|
||||
|
|
|
@ -14,7 +14,7 @@ language help people understand where the boundaries between syllables are. I
|
|||
will then describe my plans for the L'ewa orthography and how L'ewa is
|
||||
romanized. This is a response to the prompt made [here][rclm2prompt].
|
||||
|
||||
[rclm1]: https://xeiaso.net/blog/reconlangmo-1-name-ctx-history-2020-05-05
|
||||
[rclm1]: https://christine.website/blog/reconlangmo-1-name-ctx-history-2020-05-05
|
||||
[rclm2prompt]: https://www.reddit.com/r/conlangs/comments/gfp3hw/reconlangmo_2_phonology_writing/
|
||||
|
||||
## Phonology
|
||||
|
|
|
@ -15,7 +15,7 @@ making the vocabulary for L'ewa and I'll include an entire table of the
|
|||
dictionary words. This answers [this
|
||||
prompt](https://www.reddit.com/r/conlangs/comments/gojncp/reconlangmo_6_lexicon/).
|
||||
|
||||
[reconlangmo]: https://xeiaso.net/blog/series/reconlangmo
|
||||
[reconlangmo]: https://christine.website/blog/series/reconlangmo
|
||||
|
||||
## Word Distinctions
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ post will start to cover a lot of the softer skills behind L'ewa as well as
|
|||
cover some other changes I'm making under the hood. This is a response to [this
|
||||
prompt][rclm7].
|
||||
|
||||
[reconlangmo]: https://xeiaso.net/blog/series/reconlangmo
|
||||
[reconlangmo]: https://christine.website/blog/series/reconlangmo
|
||||
[rclm7]: https://www.reddit.com/r/conlangs/comments/gqo8jn/reconlangmo_7_discourse/
|
||||
|
||||
## Information Structure
|
||||
|
|
|
@ -103,7 +103,7 @@ this:
|
|||
|
||||
> I have no record of a "Christine Dodrill" at this email address. You may want
|
||||
> to look elsewhere. If you would like to proceed with me instead, here is
|
||||
> information about me: https://xeiaso.net.
|
||||
> information about me: https://christine.website.
|
||||
|
||||
Throw in your pronouns too to be safe.
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ As of [a recent commit](https://github.com/Xe/site/commit/b89387f6bbb010907dfa85
|
|||
to this site's code, it now generates RSS and Atom feeds for future posts on my
|
||||
blog.
|
||||
|
||||
For RSS: `https://xeiaso.net/blog.rss`
|
||||
For RSS: `https://christine.website/blog.rss`
|
||||
|
||||
For Atom: `https://christine.webiste/blog.atom`
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ my RTMP server. This means I could set it up to ingest via my [WireGuard
|
|||
VPN][sts-wireguard] with very little work. Here is the docker command I run on
|
||||
my VPN host:
|
||||
|
||||
[sts-wireguard]: https://xeiaso.net/blog/series/site-to-site-wireguard
|
||||
[sts-wireguard]: https://christine.website/blog/series/site-to-site-wireguard
|
||||
|
||||
```console
|
||||
$ docker run \
|
||||
|
|
|
@ -198,7 +198,7 @@ describes why functions fail to do what they intend. Rust has the [`Error`
|
|||
trait](https://doc.rust-lang.org/std/error/trait.Error.html) which lets you also
|
||||
create a type that describes why functions fail to do what they intend.
|
||||
|
||||
In [my last post](https://xeiaso.net/blog/TLDR-rust-2020-09-19) I
|
||||
In [my last post](https://christine.website/blog/TLDR-rust-2020-09-19) I
|
||||
described [`eyre`](https://docs.rs/eyre) and the Result type. However, this time
|
||||
we're going to dive into [`thiserror`](https://docs.rs/thiserror) for making our
|
||||
own error type. Let's add `thiserror` to our crate:
|
||||
|
|
|
@ -9,9 +9,9 @@ In this blogpost series I'm going to go over how I created a [site to site](http
|
|||
This series is going to be broken up into multiple posts about as follows:
|
||||
|
||||
- Part 1 - Names and Numbers (this post)
|
||||
- [Part 2 - DNS](https://xeiaso.net/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://xeiaso.net/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- [Part 4 - HTTPS](https://xeiaso.net/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- [Part 2 - DNS](https://christine.website/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- [Part 4 - HTTPS](https://christine.website/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- Setting up additional iOS, macOS, Android and Linux clients
|
||||
- Other future fun things (seamless tor2web routing, etc)
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ series: site-to-site-wireguard
|
|||
|
||||
This is the second in my Site to Site WireGuard VPN series. You can read the other articles here:
|
||||
|
||||
- [Part 1 - Names and Numbers](https://xeiaso.net/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- [Part 1 - Names and Numbers](https://christine.website/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- Part 2 - DNS (this post)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://xeiaso.net/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- [Part 4 - HTTPS](https://xeiaso.net/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- [Part 4 - HTTPS](https://christine.website/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- Setting up additional iOS, macOS, Android and Linux clients
|
||||
- Other future fun things (seamless tor2web routing, etc)
|
||||
|
||||
|
@ -230,7 +230,7 @@ $ dig @127.0.0.1 -x 10.55.0.1
|
|||
|
||||
### Using With the iOS WireGuard App
|
||||
|
||||
In order to configure [iOS WireGuard clients](https://itunes.apple.com/us/app/wireguard/id1441195209?mt=8) to use this DNS server, open the WireGuard app and tap the name of the configuration we created in the [last post](https://xeiaso.net/blog/site-to-site-wireguard-part-1-2019-04-02). Hit "Edit" in the upper right hand corner and select the "DNS Servers" box. Put `10.55.0.1` in it and hit "Save". Be sure to confirm the VPN is active, then open [LibTerm](https://itunes.apple.com/us/app/libterm/id1380911705?mt=8) and enter in the following:
|
||||
In order to configure [iOS WireGuard clients](https://itunes.apple.com/us/app/wireguard/id1441195209?mt=8) to use this DNS server, open the WireGuard app and tap the name of the configuration we created in the [last post](https://christine.website/blog/site-to-site-wireguard-part-1-2019-04-02). Hit "Edit" in the upper right hand corner and select the "DNS Servers" box. Put `10.55.0.1` in it and hit "Save". Be sure to confirm the VPN is active, then open [LibTerm](https://itunes.apple.com/us/app/libterm/id1380911705?mt=8) and enter in the following:
|
||||
|
||||
```
|
||||
$ dig oho.pele
|
||||
|
|
|
@ -6,10 +6,10 @@ series: site-to-site-wireguard
|
|||
|
||||
This is the third in my Site to Site WireGuard VPN series. You can read the other articles here:
|
||||
|
||||
- [Part 1 - Names and Numbers](https://xeiaso.net/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- [Part 2 - DNS](https://xeiaso.net/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- [Part 1 - Names and Numbers](https://christine.website/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- [Part 2 - DNS](https://christine.website/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- Part 3 - Custom TLS Certificate Authority (this post)
|
||||
- [Part 4 - HTTPS](https://xeiaso.net/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- [Part 4 - HTTPS](https://christine.website/blog/site-to-site-wireguard-part-4-2019-04-16)
|
||||
- Setting up additional iOS, macOS, Android and Linux clients
|
||||
- Other future fun things (seamless tor2web routing, etc)
|
||||
|
||||
|
@ -26,7 +26,7 @@ A TLS Certificate Authority is a certificate that is allowed to issue other cert
|
|||
|
||||
### Why Should I Create One?
|
||||
|
||||
Generally, it is useful to create a custom TLS certificate authority when there are custom DNS domains being used. This allows you to create `https://` links for your internal services (which can then act as [Progressive Web Apps](https://xeiaso.net/blog/progressive-webapp-conversion-2019-01-26)). This will also fully prevent the ["Not Secure"](https://versprite.com/blog/http-labeled-not-secure/) blurb from showing up in the URL bar.
|
||||
Generally, it is useful to create a custom TLS certificate authority when there are custom DNS domains being used. This allows you to create `https://` links for your internal services (which can then act as [Progressive Web Apps](https://christine.website/blog/progressive-webapp-conversion-2019-01-26)). This will also fully prevent the ["Not Secure"](https://versprite.com/blog/http-labeled-not-secure/) blurb from showing up in the URL bar.
|
||||
|
||||
Sometimes your needs may involve needing to see what an application is doing over TLS traffic. Having a custom TLS certificate authority already set up makes this a much faster thing to do.
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ series: site-to-site-wireguard
|
|||
|
||||
This is the fourth post in my Site to Site WireGuard VPN series. You can read the other articles here:
|
||||
|
||||
- [Part 1 - Names and Numbers](https://xeiaso.net/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- [Part 2 - DNS](https://xeiaso.net/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://xeiaso.net/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- [Part 1 - Names and Numbers](https://christine.website/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||||
- [Part 2 - DNS](https://christine.website/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||||
- [Part 3 - Custom TLS Certificate Authority](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||||
- Part 4 - HTTPS (this post)
|
||||
- Setting up additional iOS, macOS, Android and Linux clients
|
||||
- Other future fun things (seamless tor2web routing, etc)
|
||||
|
@ -85,7 +85,7 @@ This will allow only Caddy and root to manage certificates in that folder.
|
|||
|
||||
### Custom CA Certificate Permissions
|
||||
|
||||
In the [last post](https://xeiaso.net/blog/site-to-site-wireguard-part-3-2019-04-11), custom certificates were created at `/srv/within/certs`. Caddy is going to need to have the correct permissions in order to be able to read them.
|
||||
In the [last post](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11), custom certificates were created at `/srv/within/certs`. Caddy is going to need to have the correct permissions in order to be able to read them.
|
||||
|
||||
```shell
|
||||
#!/bin/sh
|
||||
|
|
|
@ -58,7 +58,7 @@ me](mailto:me@christine.website) and let me know them.
|
|||
|
||||
</noscript>
|
||||
|
||||
I want to use [Xeact](https://xeiaso.net/blog/xeact-0.0.69-2021-11-18)
|
||||
I want to use [Xeact](https://christine.website/blog/xeact-0.0.69-2021-11-18)
|
||||
more in my website. I am trying to hit a balance of avoiding structural
|
||||
JavaScript while also allowing me to experiment with new and interesting ways of
|
||||
doing things. To this end I have created a custom HTML element that allows me to
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
---
|
||||
title: "Site Update: Hero Images"
|
||||
date: 2022-06-08
|
||||
---
|
||||
|
||||
For a while I've been wondering how I can add dramatic flair to my website with
|
||||
so-called "hero images". These images are tools that let you describe the mood a
|
||||
website wants to evoke. I've been unsure how to best implement these on my
|
||||
website for a while, but with the advent of MidJourney and other image
|
||||
generation APIs/algorithms I think I have found a way to create these without
|
||||
too much effort on my part and the results are pretty fantastic:
|
||||
|
||||
<xeblog-hero file="secret-to-life" prompt="the secret to life, the universe and everything, concept art"></xeblog-hero>
|
||||
|
||||
I have generated a bunch of other images that I'm going to use for my other
|
||||
posts. I'll give out a desktop wallpaper sized version of each of these images
|
||||
on my [Patreon](https://patreon.com/cadey).
|
||||
|
||||
Under the hood this is powered by
|
||||
[lol_html](https://github.com/cloudflare/lol-html) and
|
||||
[Maud](https://maud.lambda.xyz/). The magic is mostly contained in a function
|
||||
that generates a `<figure>` HTML element (which I just learned exists today). I
|
||||
use a function that looks like this for generating the `<xeblog-hero>` snippets:
|
||||
|
||||
```rust
|
||||
pub fn xeblog_hero(file: String, prompt: Option<String>) -> Markup {
|
||||
html! {
|
||||
figure.hero style="margin:0" {
|
||||
picture style="margin:0" {
|
||||
source type="image/avif" srcset={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) ".avif"};
|
||||
source type="image/webp" srcset={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) ".webp"};
|
||||
img style="padding:0" alt={"hero image " (file)} src={"https://cdn.xeiaso.net/file/christine-static/hero/" (file) "-smol.png"};
|
||||
}
|
||||
figcaption { "Image generated by MidJourney" @if let Some(prompt) = prompt { " -- " (prompt) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
I have it wired up with lol_html like this:
|
||||
|
||||
```rust
|
||||
lol_html::element!("xeblog-hero", |el| {
|
||||
let file = el.get_attribute("file").expect("wanted xeblog-hero to contain file");
|
||||
el.replace(&crate::tmpl::xeblog_hero(file, el.get_attribute("prompt")).0, ContentType::Html);
|
||||
Ok(())
|
||||
})
|
||||
```
|
||||
|
||||
The result is that I can declare hero images with HTML fragments like this:
|
||||
|
||||
```html
|
||||
<xeblog-hero file="miku-dark-souls" prompt="hatsune miku, elden ring, dark souls, concept art, crowbar"></xeblog-hero>
|
||||
```
|
||||
|
||||
And I get this:
|
||||
|
||||
<xeblog-hero file="miku-dark-souls" prompt="hatsune miku, elden ring, dark souls, concept art, crowbar"></xeblog-hero>
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">This is powered by the
|
||||
[`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
|
||||
tag, which is a new discovery to us. This is probably one of the most useful
|
||||
tags we never knew about and removed the need to write a bunch of annoying CSS
|
||||
and HTML.</xeblog-conv>
|
||||
|
||||
The webp and AVIF versions of the hero images have a higher resolution version
|
||||
so that it looks nicer on retina screens. However, the png versions of these are
|
||||
locked to a resolution of 800x356 pixels because I was unable to crush them
|
||||
below a size of half a megabyte at full resolution. Realistically, this should
|
||||
only affect older browsers on slower hardware, so I don't expect this to have
|
||||
too much impact on most users.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="coffee">If you don't want to see these hero
|
||||
images, you can remove them with a userstyle like this:
|
||||
```css
|
||||
figure.hero {
|
||||
display: none;
|
||||
}
|
||||
```
|
||||
</xeblog-conv>
|
||||
|
||||
I'm likely going to convert over most of my website templates to use Maud. I'm
|
||||
very happy with it and I think it is incredibly useful to express your HTML in
|
||||
Rust instead of something that has to be compiled to Rust. In practice it
|
||||
reminds me of the Nim library [emerald](http://flyx.github.io/emerald/), which
|
||||
lets you write HTML using Nim functions similar to how you use Maud.
|
||||
|
||||
Here's a few more examples of hero images I have generated:
|
||||
|
||||
<xeblog-hero file="the-forbidden-shape" prompt="the forbidden shape"></xeblog-hero>
|
||||
|
||||
<xeblog-hero file="great-wave-cyberpunk" prompt="the great wave off of kanagawa, cyberpunk, hanzi inscription"></xeblog-hero>
|
||||
|
||||
Normally I will only have one image per post and it will usually be after the
|
||||
introduction paragraph. The prompt will usually be related to the article topic,
|
||||
but sometimes I will take artistic liberty. If you have suggestions for prompts,
|
||||
please [contact me](/contact) with those ideas.
|
||||
|
||||
I hope these updates on how I've been messing with my site are interesting. I'm
|
||||
trying to capture the spirit of how I'm implementing these changes as well as
|
||||
details of how everything fits together.
|
|
@ -1,117 +0,0 @@
|
|||
---
|
||||
title: "Site Update: I Fixed the Patron Page"
|
||||
date: 2022-05-18
|
||||
---
|
||||
|
||||
So I fixed [the patron page](https://xeiaso.net/patrons) and the
|
||||
underlying issue was stupid enough that I feel like explaining it so you all can
|
||||
learn from my mistake.
|
||||
|
||||
<xeblog-conv name="Numa" mood="delet">For those of you playing the christine dot
|
||||
website home game, look
|
||||
[here](https://github.com/Xe/site/commit/e2b9f384bf4033eddf321b5b5020ac4847609b37)
|
||||
to see the fix and play along!</xeblog-conv>
|
||||
|
||||
My blog is basically a thin wrapper around two basic things:
|
||||
|
||||
1. Markdown files (such as for this article you are reading right now)
|
||||
2. Static files (such as for the CSS that is making this article look nice)
|
||||
|
||||
When I create a package out of my blog's code, I have a layout that resembles
|
||||
the directory structure in my git repo:
|
||||
|
||||
```console
|
||||
$ ls -l /nix/store/crc94hqyb546w3w9fzdyr8zvz3xf3p1j-xesite-2.4.0
|
||||
total 64
|
||||
dr-xr-xr-x 2 root root 4096 Dec 31 1969 bin/
|
||||
dr-xr-xr-x 2 root root 20480 Dec 31 1969 blog/
|
||||
-r--r--r-- 24 root root 8663 Dec 31 1969 config.dhall
|
||||
dr-xr-xr-x 2 root root 4096 Dec 31 1969 css/
|
||||
dr-xr-xr-x 2 root root 4096 Dec 31 1969 gallery/
|
||||
-r--r--r-- 52 root root 5902 Dec 31 1969 signalboost.dhall
|
||||
dr-xr-xr-x 12 root root 4096 Dec 31 1969 static/
|
||||
dr-xr-xr-x 2 root root 4096 Dec 31 1969 talks/
|
||||
```
|
||||
|
||||
Here is my git repo for comparison:
|
||||
|
||||
```console
|
||||
$ ls -l
|
||||
total 188
|
||||
drwxr-xr-x 2 cadey users 20480 May 18 20:21 blog/
|
||||
-rw-r--r-- 1 cadey users 77521 May 18 20:15 Cargo.lock
|
||||
-rw-r--r-- 1 cadey users 1795 May 18 20:15 Cargo.toml
|
||||
-rw-r--r-- 1 cadey users 198 Oct 30 2020 CHANGELOG.md
|
||||
-rw-r--r-- 1 cadey users 2779 Apr 5 20:32 config.dhall
|
||||
drwxr-xr-x 2 cadey users 4096 Apr 16 11:56 css/
|
||||
-rw-r--r-- 1 cadey users 1325 Jan 15 2021 default.nix
|
||||
drwxr-xr-x 2 cadey users 4096 Mar 15 2020 docs/
|
||||
drwxr-xr-x 2 cadey users 4096 Mar 21 20:23 examples/
|
||||
-rw-r--r-- 1 cadey users 1882 Apr 30 16:13 flake.lock
|
||||
-rw-r--r-- 1 cadey users 6547 Apr 24 20:35 flake.nix
|
||||
drwxr-xr-x 2 cadey users 4096 Jun 17 2020 gallery/
|
||||
drwxr-xr-x 6 cadey users 4096 Mar 21 20:23 lib/
|
||||
-rw-r--r-- 1 cadey users 887 Jan 1 2021 LICENSE
|
||||
drwxr-xr-x 2 cadey users 4096 Dec 18 00:06 nix/
|
||||
-rw-r--r-- 1 cadey users 1467 Feb 21 20:39 README.md
|
||||
drwxr-xr-x 2 cadey users 4096 Mar 21 21:21 scripts/
|
||||
-rw-r--r-- 1 cadey users 5902 May 18 16:44 signalboost.dhall
|
||||
drwxr-xr-x 5 cadey users 4096 Apr 5 20:32 src/
|
||||
drwxr-xr-x 12 cadey users 4096 Jan 10 17:22 static/
|
||||
drwxr-xr-x 2 cadey users 4096 Nov 10 2021 talks/
|
||||
drwxr-xr-x 4 cadey users 4096 Apr 16 09:56 target/
|
||||
drwxr-xr-x 2 cadey users 4096 May 15 07:59 templates/
|
||||
```
|
||||
|
||||
The main problem is that my site expects all of this to be in the current
|
||||
working directory. In my site's systemd unit I have a launch script that looks
|
||||
like this:
|
||||
|
||||
```nix
|
||||
script = let site = packages.default;
|
||||
in ''
|
||||
export SOCKPATH=${cfg.sockPath}
|
||||
export DOMAIN=${toString cfg.domain}
|
||||
cd ${site}
|
||||
exec ${site}/bin/xesite
|
||||
'';
|
||||
```
|
||||
|
||||
However the Nix store isn't writable by user code. My patreon API client looked
|
||||
for its credentials in the current working directory. When I set it up on the
|
||||
target server I put the credentials in `/srv/within/xesite/.patreon.json`,
|
||||
thinking that the `WorkingDirectory` setting would make it Just Work:
|
||||
|
||||
```nix
|
||||
WorkingDirectory = "/srv/within/xesite";
|
||||
```
|
||||
|
||||
But this was immediately blown away by the `cd` command on line 4 of the script.
|
||||
|
||||
I have fixed this by making my Patreon client put its credentials in the home
|
||||
directory explicitly with this fragment of code:
|
||||
|
||||
```rust
|
||||
let mut p = dirs::home_dir().unwrap_or(".".into());
|
||||
p.push(".patreon.json");
|
||||
```
|
||||
|
||||
This will make the Patreon credentials get properly stored in the service's home
|
||||
directory (which is writable). This will also make the patrons page work
|
||||
persistently without having to manually rotate secrets every month.
|
||||
|
||||
Here's a good lesson for you all, make sure to print out the absolute path of
|
||||
everything in error messages. For the longest time I had to debug this from this
|
||||
error message:
|
||||
|
||||
```
|
||||
patrons: xesite::app: ".patreon.json" does not exist
|
||||
```
|
||||
|
||||
I was looking at the directory `/srv/within/xesite` and I saw it existing right
|
||||
in front of my eyes. This made me feel like I was going crazy and I've been
|
||||
putting off fixing it because of that. However, it's a simple fix and I was
|
||||
blind.
|
||||
|
||||
<xeblog-conv name="Cadey"
|
||||
mood="coffee">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</xeblog-conv>
|
|
@ -1,42 +0,0 @@
|
|||
---
|
||||
title: "Site Update: Salary Transparency Page Added"
|
||||
date: 2022-06-14
|
||||
author: Sephie
|
||||
---
|
||||
|
||||
<xeblog-hero file="miku-dark-souls" prompt="hatsune miku, elden ring, dark souls, concept art, crowbar"></xeblog-hero>
|
||||
|
||||
I have added a [salary transparency
|
||||
page](https://xeiaso.net/salary-transparency) to the blog. This page lists my
|
||||
salary for every job I've had in tech. I have had this data open to the public
|
||||
for years, but I feel this should be more prominently displayed on my website.
|
||||
|
||||
As someone who has seen pay discrimination work in action first-hand, data is
|
||||
one of the ways that we can end this pointless hiding of information that leads
|
||||
to people being uninformed and hurt by their lack of knowledge. By laying my
|
||||
hand out in the open like this, I hope to ensure that people are better informed
|
||||
about how much money they can make, so that they can be paid equally for equal
|
||||
work.
|
||||
|
||||
Raw, machine processable data (including employer names) is available at
|
||||
`/api/salary_transparency.json`. The JSON format is not stable. Do not treat it as
|
||||
such. I reserve the right to change the formatting or semantics of the JSON
|
||||
format at any time without warning. The raw data is in `/dhall/jobHistory.dhall`
|
||||
in my site's git repository.
|
||||
|
||||
I have also taken the time to make sure that the [old
|
||||
post](https://xeiaso.net/blog/my-career-in-dates-titles-salaries-2019-03-14)
|
||||
maintains an up-to-date list. I do not want to break semantics on my website
|
||||
without a very good reason. By leaving the old post un-updated, I feel it would
|
||||
be doing a disservice to the community.
|
||||
|
||||
Please consider publishing your salary data like this as well. By open,
|
||||
voluntary transparency we can help to end stigmas around discussing pay and help
|
||||
ensure that the next generations of people in tech are treated fairly. Stigmas
|
||||
thrive in darkness but die in the light of day. You can help end the stigma by
|
||||
playing your cards out in the open like this.
|
||||
|
||||
It can be scary to do this; however every person that does it will make it that
|
||||
much more easy for the next person to do it.
|
||||
|
||||
Don't be afraid.
|
|
@ -8,13 +8,13 @@ tags:
|
|||
---
|
||||
|
||||
I made a little interactive fiction story! You can find it
|
||||
[here](https://xeiaso.net/static/stories/spaceship.html). This was
|
||||
[here](https://christine.website/static/stories/spaceship.html). This was
|
||||
written as a result of a terrible idea I had after watching some QuakeCon
|
||||
announcements.
|
||||
|
||||
I wonder if I can get away with using an `<iframe>` in 2021:
|
||||
|
||||
<iframe src="https://xeiaso.net/static/stories/spaceship.html" width="100%" height=500></iframe>
|
||||
<iframe src="https://christine.website/static/stories/spaceship.html" width="100%" height=500></iframe>
|
||||
|
||||
This is adapted from [a twitter
|
||||
thread](https://twitter.com/theprincessxena/status/1428479144699088903).
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
---
|
||||
title: "Spearphishing: it can happen to you too"
|
||||
date: 2022-07-09
|
||||
tags:
|
||||
- linkedin
|
||||
- infosec
|
||||
---
|
||||
|
||||
<xeblog-hero file="the-fool" prompt="The Fool in a woodcut tarot card style"></xeblog-hero>
|
||||
|
||||
For some reason, LinkedIn has become the de-facto social network for
|
||||
professionals. It is viewed as a powerful networking and marketing site that
|
||||
lets professionals communicate, find new opportunities and source talent at
|
||||
eye-watering speed and rates. However, at the same time this also means that
|
||||
LinkedIn becomes a treasure trove of data to enable spearphising attacks.
|
||||
|
||||
Let's consider [this attack against popular "play to earn" game Axie
|
||||
Infinity](https://www.theblock.co/post/156038/how-a-fake-job-offer-took-down-the-worlds-most-popular-crypto-game).
|
||||
The attackers had PDF based malware that allowed them to get access to a target
|
||||
computer, so they needed someone to open a PDF to trigger the exploit chain that
|
||||
let them gain a foothold. But they specifically wanted people that likely had
|
||||
access to the crypto wallets that enable control of the blockchain. LinkedIn let
|
||||
them filter by employees at the company behind Axie Infinity that were
|
||||
developers and likely started spearphishing by role and seniority. The details
|
||||
of the attack spell out that the attackers had set up a whole fake interview
|
||||
process to convince the marks that the process was legitimate and they put the
|
||||
malware in the offer letter. The attackers later gained access to the validator
|
||||
wallets and then they were able to make off with over half a billion dollars
|
||||
worth of cryptocurrency.
|
||||
|
||||
<xeblog-conv name="Numa" mood="delet">Maybe, just maybe you shouldn't store a
|
||||
majority of the keys required to validate something on _the same computer_.
|
||||
Especially if those keypairs control assets worth close to _half a billion
|
||||
dollars_. Holy heck.</xeblog-conv>
|
||||
|
||||
The malware was in the offer letter. This is the kind of social engineering
|
||||
attack that I bet any one of you reading this article could fall for. Hell, I'd
|
||||
probably fall for this. This may be the wrong kind of take to have, but I'm
|
||||
really starting to wonder if using LinkedIn so much is actually bad for
|
||||
security. It's not just recruiters reading through LinkedIn anymore, it's also
|
||||
threat actors that are trying to break in and do God knows what. Maybe we as an
|
||||
industry should stop feeding all of that data into LinkedIn. Not only would it
|
||||
give you less recruiter spam, maybe it'll make spearphishing attacks more
|
||||
difficult too.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="coffee">Also, yes we can't trust PDFs anymore,
|
||||
especially after exploits like
|
||||
[FORCEDENTRY](https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html)
|
||||
became a thing.</xeblog-conv>
|
||||
|
||||
Either way, I may end up getting a disposable machine for dealing with reading
|
||||
PDFs from unknown sources in the future. I could use a virtual machine for this,
|
||||
but if my threat model includes PDFs having exploits in them then I probably
|
||||
can't trust a virtual machine to be a reasonable security barrier. I don't know.
|
||||
It sucks that we can't trust people anymore.
|
||||
|
||||
I kinda wish we could.
|
||||
|
||||
---
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">Fun fact: the tarot card "The Fool"
|
||||
doesn't actually imply idiocy in a malicious way. The major arcana of the tarot
|
||||
is a bunch of memes that describe the story of The Fool's journey through magick
|
||||
and learning how the world works. The Fool is not an idiot, The Fool is just
|
||||
someone that is unaware of the difficulties they are going to face in life and
|
||||
treats things optimistically. Think a free spirit as opposed to someone that is
|
||||
foolhardy (though foolhardiness is the meaning of The Fool when the card is
|
||||
inverted).</xeblog-conv>
|
|
@ -26,7 +26,7 @@ problems that require deep thought and consideration.
|
|||
|
||||
I was originally gonna release this by the end of the year as a cohesive novel,
|
||||
however it looks like the cards aren't falling that way. I want to instead shift
|
||||
[Spellblade](https://xeiaso.net/blog/spellblade-plans-2021-08-16) into a
|
||||
[Spellblade](https://christine.website/blog/spellblade-plans-2021-08-16) into a
|
||||
web novel, which I am defining as something that I'll release in big chunks like
|
||||
this every month or so. I don't want to compromise any of the artistic vision or
|
||||
whatever, I just want each "chunk" to be a lot more finely scoped than "the
|
||||
|
|
|
@ -64,7 +64,7 @@ def get_feed(feed_url):
|
|||
con.commit()
|
||||
print("got feed %s" % (feed_url))
|
||||
|
||||
get_feed("https://xeiaso.net/blog.json")
|
||||
get_feed("https://christine.website/blog.json")
|
||||
```
|
||||
|
||||
So now let's play with the data! Let's load the database schema in with the
|
||||
|
@ -76,14 +76,14 @@ $ sqlite3 data.db < schema.sql
|
|||
|
||||
[The less-than symbol there is a redirect, it loads the data from `schema.sql`
|
||||
as standard input to the `sqlite` command. See <a
|
||||
href="https://xeiaso.net/blog/fun-with-redirection-2021-09-22">here</a>
|
||||
href="https://christine.website/blog/fun-with-redirection-2021-09-22">here</a>
|
||||
for more information on redirections.](conversation://Mara/hacker)
|
||||
|
||||
Then run that python script to populate the database:
|
||||
|
||||
```console
|
||||
$ python ./jsonfeedfetch.py
|
||||
got feed https://xeiaso.net/blog.json
|
||||
got feed https://christine.website/blog.json
|
||||
```
|
||||
|
||||
Then open up the SQLite command line:
|
||||
|
@ -179,7 +179,7 @@ And run that python script again, then the data should automatically show up:
|
|||
|
||||
```
|
||||
sqlite3> SELECT * FROM jsonfeed_metadata;
|
||||
https://xeiaso.net/blog.json|Xe's Blog|My blog posts and rants about various technology things.|https://xeiaso.net|2022-01-04
|
||||
https://christine.website/blog.json|Xe's Blog|My blog posts and rants about various technology things.|https://christine.website|2022-01-04
|
||||
```
|
||||
|
||||
It's like magic!
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
---
|
||||
title: "The Stanley Parable: Ultra Deluxe Review"
|
||||
date: 2022-07-25
|
||||
series: reviews
|
||||
---
|
||||
|
||||
Every so often a game comes around that is genuinely hard to review. Especially
|
||||
when you are trying to avoid spoiling the magic of the game in that review. This
|
||||
is a game that is even harder to review than normal because it's an absolute
|
||||
philosophical document. This game absolutely riffs at the games industry super
|
||||
hard and it really shows. I'm going to try to avoid spoilers in this article,
|
||||
except for a few I made up.
|
||||
|
||||
<xeblog-conv name="Cadey" mood="coffee">I was going to include screenshots in
|
||||
this article, but it's difficult for me to get them without spoiling the subtle
|
||||
comedy at hand, so I'm going to leave this as a text-only review.</xeblog-conv>
|
||||
|
||||
The Stanley Parable: Ultra Deluxe is either the second or third game in the
|
||||
series. At first this game was a Half Life 2 mod that came out of nowhere and
|
||||
was one of the most beloved mods ever released. Then they made it a proper game
|
||||
on the Source engine and expanded it a bit. After a while they wanted to
|
||||
continue the parable and expand it even more, but they weren't able to get it on
|
||||
consoles with it still being a Source engine game. So they ported it to Unity
|
||||
and the end result is The Stanley Parable: Ultra Deluxe. It is one of my
|
||||
favorite games of all time.
|
||||
|
||||
It is a deeply limited game, you only can move around and interact with things.
|
||||
The story is about an office drone named Stanley that pushes buttons based on
|
||||
instructions from his computer. The big thing that this game does though is make
|
||||
you realize the inherent paradoxes in its own design.
|
||||
|
||||
<xeblog-conv name="Mara" mood="happy">Being mechanically limited like this is
|
||||
not actually a bad thing like the phrasing might imply. This means that the main
|
||||
focus of the gameplay is not on the micro actions the player can take. In this
|
||||
case the main focus is on how the player interacts with the story and not how
|
||||
the player interacts with their controller or puzzles or tactics. Additionally,
|
||||
the mechanical limitations of the gameplay are thematically aligned with the
|
||||
story's premise of being an office drone in ways it can play with. Think
|
||||
dramatic irony taken to its logical conclusion.</xeblog-conv>
|
||||
|
||||
Endings that make you look like you had exercised your free will actually boil
|
||||
down to your actions being controlled by following the narrator's voices. This
|
||||
is absolutely taking the piss out of how most modern AAA game design works,
|
||||
guiding you with an invisible hand and making it _seem_ like you had the free
|
||||
will to choose what was going on when in fact you were really just following the
|
||||
invisible guidance the whole time.
|
||||
|
||||
However I think one of the best examples of how The Stanley Parable riffs at
|
||||
mainstream game design is via the Adventure Line™️ that shows up in one branch of
|
||||
the game. The Line™️ is an obvious riff on games like Dead Space where you can
|
||||
summon a line to tell you where to go at any time. It shows how _boring_ modern
|
||||
game design is by making you _see_ the consequences of it. If you follow the
|
||||
narrator's voice, you get boring endings.
|
||||
|
||||
In many modern AAA games, you have the free will to choose to follow the main
|
||||
story and finish all the quests or whatever, but not much else. Consider Call of
|
||||
Duty or Battlefield. You are John America and you have to kill the enemies to
|
||||
death before they kill you to death by throwing bullets at you. You get to the
|
||||
end of the level and blow up the brown people some more or something and then
|
||||
it's suddenly a victory for America. But what did you really accomplish? You
|
||||
just followed the line. Walk outside of the intended playable area? 10 second
|
||||
timer until the game kills you. Shoot a person with the wrong skin color? The
|
||||
game kills you.
|
||||
|
||||
<xeblog-conv name="Numa" mood="delet">If you manage to clip out of bounds in the
|
||||
escape ending, the screen will fade to black and you will be transported to a
|
||||
temperate climate. Then a t-posing model in terrible armor will tell you that it
|
||||
used to be an adventurer until they took an arrow to the knee. Hope that's not a
|
||||
marriage proposal!</xeblog-conv>
|
||||
|
||||
However in The Stanley Parable you can defy the narrator and that's where the
|
||||
game really opens up. It's great to get in the area where the game is unfinished
|
||||
and then have the narrator complain about deadlines, scheduling delays, investor
|
||||
funding and them wanting to avoid having to stuff it to the gills with
|
||||
microtransactions. You can legitimately glitch your way out of bounds and then
|
||||
the game will reward you with a new ending you didn't know was possible. The
|
||||
game takes the concept of the illusion of free will and plays with it.
|
||||
|
||||
The game makes you think about what games _can_ be. It makes you wonder if the
|
||||
potted plant soliloquy after the broom closet ending speaks to the mental state
|
||||
of the author more than anything. Of all of the artistic endeavors that games as
|
||||
a medium _can_ have, we end up seeing very few or none of them in mainstream
|
||||
gaming. Sure you get your occasional 4k120fps robot killer waifu with a bow and
|
||||
a whacky stick, but none of it really _revolutionizes_ video games as an art
|
||||
form. It's all just derivative of the generic "unalive bad guy and save earth"
|
||||
trope.
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">If you want some games that really
|
||||
revolutionize what games can be, check out
|
||||
[Celeste](https://mattmakesgames.itch.io/celeste), [Secret Little
|
||||
Haven](https://ristar.itch.io/secret-little-haven), [Baba Is
|
||||
You](https://hempuli.itch.io/baba), and [Glittermitten
|
||||
Grove](https://twinbeard.itch.io/glittermitten-grove). All of these games really
|
||||
challenge what games can be and experiment with radically different kinds of
|
||||
art. You never will see mainstream games be as risk-taking as this because art
|
||||
is fundamentally risky and capitalism wants line to go up, so they go out of
|
||||
their way to make sure that mainstream games are as safe and likely to sell many
|
||||
copies as possible.</xeblog-conv>
|
||||
|
||||
I made up the thing about the potted plant, but if you had played the game then
|
||||
you'd probably have started the game up to look for it just to see what was
|
||||
there. I wonder if I made someone stand at that potted plant for like 5 minutes
|
||||
or something. This game sparks creativity in ways that other mainstream games
|
||||
just fundamentally don't. If you've been looking for something different in your
|
||||
video game diet, I really suggest you give it a try. Go in as blind as possible.
|
||||
I'm not paid in any way to say this, I genuinely think this is really good.
|
|
@ -4,7 +4,7 @@ date: 2019-05-30
|
|||
series: templeos
|
||||
---
|
||||
|
||||
The [last post](https://xeiaso.net/blog/templeos-1-installation-and-basic-use-2019-05-20) covered a lot of the basic usage of TempleOS. This post is going to be significantly different, as I'm going to be porting part of the TempleOS kernel to WebAssembly as a live demo.
|
||||
The [last post](https://christine.website/blog/templeos-1-installation-and-basic-use-2019-05-20) covered a lot of the basic usage of TempleOS. This post is going to be significantly different, as I'm going to be porting part of the TempleOS kernel to WebAssembly as a live demo.
|
||||
|
||||
This post may contain words used in ways and places that look blasphemous at first glance. No blasphemy is intended, though it is an unfortunate requirement for covering this part of TempleOS' kernel. It's worth noting that Terry Davis [legitimately believed that TempleOS is a temple of the Lord Yahweh](https://templeos.holyc.xyz/Wb/Doc/Charter.html):
|
||||
|
||||
|
|
|
@ -1,344 +0,0 @@
|
|||
---
|
||||
title: The Oasis
|
||||
date: 2022-06-03
|
||||
series: malto
|
||||
tags:
|
||||
- furry
|
||||
---
|
||||
|
||||
Tosen did a final check of his backpack. It was a very hot day in Tashei, but
|
||||
the river radiated an aura of cool air that protected everyone from the heat of
|
||||
the harsh sun. He had his backup cloak, a hydroflask and some fish jerkey, not
|
||||
to mention the package for the client. *Not exactly the best equipment but this
|
||||
will work. Riltash is a half day away at worst,* Tosen thought to himself. He
|
||||
squatted down and fit his arms into the pack's straps. The pack easily weighed a
|
||||
quarter of what he did, but as he regained his catlike balance he secured the
|
||||
waistband and got ready to head out.
|
||||
|
||||
The oracle predicted that there would be a sandstorm late in the evening, but it
|
||||
wasn't even noon yet. He pulled out his compass, let it settle and then set out
|
||||
to the southeast.
|
||||
|
||||
Walking in the desert always has its own unique rhythm to it. With the
|
||||
unrelenting heat of the sun pounding down on the sand, the ground itself can
|
||||
feel like a million angry daggers with every step. Tosen thought ahead of this
|
||||
issue. He got himself a pair of sandshoes from the fancy magic item store. The
|
||||
only downside was that his main connection to the earth was significantly
|
||||
weakened. Chee paws are some of the most finely tuned sensory organs on Malto
|
||||
(second only to Snep paws), and they were his main warning about sandstorms.
|
||||
*The oracle isn't wrong most of the time. I'm fine, I'm fine. I can't feel the
|
||||
desert but I'm fine.*
|
||||
|
||||
He kept walking past all different kinds of cacti. His favorite ones were the
|
||||
ones that were made up of a bunch of spiky ovals built on top of eachother. He'd
|
||||
never want to get stung by one and risk the wrath of the serrated needles, but
|
||||
he'd always thought that they had such a unique look. *If I had a house of my
|
||||
own, I'd grow one of them.*
|
||||
|
||||
As he continued walking he started to focus on the patterns of walking. Every
|
||||
step was taken one after the other. With every step, his foot slid to the side
|
||||
ever so slightly. The sand wrapped around his shoes and warmed his feet. The
|
||||
worst part of the sandshoes was when sand trickled into the back of them. This
|
||||
required him to stop every so often to purge the sand out of his shoes, because
|
||||
otherwise it would hurt a lot.
|
||||
|
||||
This continued for what felt like hours. He checked his compass every so often
|
||||
and made sure he was on the right path. It started to move a bit weird compared
|
||||
to normal. It was taking longer to find north. Normally this would be concerning
|
||||
to him, but the desert had entranced him. Left, right, left, right, left, right.
|
||||
Each step bringing him closer to his destination.
|
||||
|
||||
Then the sky changed color. The brilliant blue started to get stained with a
|
||||
light brown that worked its way across what Tosen could see. Tosen instantly
|
||||
noticed this change and pulled over his face veil. The sandstorm had started
|
||||
early. The oracle was wrong.
|
||||
|
||||
Tosen looked around for some kind of shelter but all he could see was the
|
||||
remains of a broken wagon that looked like its better days had seen better days.
|
||||
It was barely enough protection. With his spare robe to patch over the biggest
|
||||
holes just enough to ride out the storm. He took the leap and hunkered down.
|
||||
*It's only a level 2 storm. It'll be over in an hour. I'll make it to Riltash
|
||||
today. Everything will work out.*
|
||||
|
||||
As he sat down he reached for his compass and couldn't find it. He reached into
|
||||
the pocket that his compass normally lives in and felt it conspicuously empty.
|
||||
He looked up towards the path he walked in on and saw a golden glint in the
|
||||
sand. It was so close. If he could get to it, he'd know where to go. He'd find
|
||||
his way to Riltash.
|
||||
|
||||
But the sandstorm started to kick up. The sky started fading towards darker and
|
||||
darker shades of brown and he could feel the sand beat against his makeshift
|
||||
shelter. The hot sand was whipped up and he could hear it pitter and patter the
|
||||
wooden and cloth walls.
|
||||
|
||||
After an hour, the sandstorm started showing signs of slowing down. *This is
|
||||
nothing close to a level 2*, Tosen thought to himself. His spare robe was
|
||||
totally ruined, but he survived. As things died down, he remembered his compass
|
||||
and tore down enough of his shelter to be able to find it. It wasn't where it
|
||||
was before. *Okay, it's made of gold, it can't have gone that far*. He grabbed
|
||||
his pack, almost fell over from the sudden weight and started to scan around him
|
||||
in 360 degrees. He saw the familiar glint of its knob and walked over to its
|
||||
resting site. The looking glass was cracked. Rotating it did nothing. The
|
||||
compass was broken.
|
||||
|
||||
He was lost.
|
||||
|
||||
It took every ounce of strength Tosen had to avoid shouting out in anger. He
|
||||
needed to conserve the water. Miau was huge. He needs to extend his supplies to
|
||||
last as long as possible.
|
||||
|
||||
He couldn't resist the urge. He shouted out in anger for an instant before
|
||||
realizing what he did and covering his mouth.
|
||||
|
||||
It took a while for Tosen to regain his senses. The shock of the event wasn't
|
||||
sitting well with him. His mother's compass was destroyed. His rendezvous time
|
||||
with the client was surely shot. At least it wasn't the solar apex anymore.
|
||||
*Okay, I can deal with this. I should stay put until sunset. The sun sets to the
|
||||
east. I can go diagonally into the sunset to get to Riltash*.
|
||||
|
||||
He more confidently went back to his makeshift shelter. It was in worse
|
||||
condition after the storm, but at least it would give him shade. The sun was on
|
||||
its way down, but it was still a deadly laser that he needed to worry about.
|
||||
*It's just me and you, buddy.*
|
||||
|
||||
Some time passed and the sun very visibly was in the eastern portion of the sky.
|
||||
Tosen grabbed for his hydroflask and took a sip. *It was still cold. At least
|
||||
that oracle was good for SOMETHING.* He stood up and grabbed his pack. He left a
|
||||
bit of red cloth as a flag on the southeast side of his makeshift shelter to
|
||||
tell anyone looking for him where he went.
|
||||
|
||||
Then it was back to the rhythms of the desert. The desert felt confusing without
|
||||
the comforting pulse of nature under his paws. But, he continued taking steps
|
||||
and continued walking forwards.
|
||||
|
||||
Left. Right. Left. Right. Left. Right. Things felt more deliberate this time.
|
||||
There was a frustration to his walking. He was so frustrated at the whole
|
||||
situation. As he walked, he felt his emotions fuming over this whole debacle.
|
||||
|
||||
He walked and walked. The sunset had started to peek out its head and show Tosen
|
||||
a display of fantastic colors as he continued to walk. *This isn't right. I
|
||||
should have reached Riltash by now. It's only a few miles from Tashei.* He took
|
||||
another swig of his hydroflask and felt it notably lighter than it should be. He
|
||||
was low on water. This was especially dangerous out here. *This is going to be a
|
||||
long night, isn't it.*
|
||||
|
||||
The sunset continued and the colors gradually started to fade to the black night
|
||||
sky. Starts started to peek out without the sun to hide them. Tosen scanned over
|
||||
the constellations and found the North Star. From there he worked out that he
|
||||
was going to the southeast like he thought he was. He looked around and found a
|
||||
few miserable bushes to use for firewood, but they were in a sea of thorns. He
|
||||
had talents in fire magick, but he didn't trust using it with so many dry thorns
|
||||
nearby. *You know what, what's the worst that can happen? I get warm? It's going
|
||||
to be so cold soon, I need to do something.*
|
||||
|
||||
He held out his hand and mentally started to trace out the triangles like he
|
||||
learned from school. Each triangle stacked on top of each other and then built
|
||||
up into a viable casting circle glowing a brilliant orange in front of his hand.
|
||||
The area around him was illuminated from the magickal force, the thorns casting
|
||||
long evil shadows against cacti and other miserable little bushes.
|
||||
|
||||
"Toor sha!"
|
||||
|
||||
A weak puff of flame came out of his hand and tickled one of the thorny vines.
|
||||
There wasn't much of a response and it looked like the fire was going to go out
|
||||
so he cast a fireball in its place. The triangles shifted into squares and a
|
||||
baseball sized orb of energy started to form in his hand.
|
||||
|
||||
"Toor shaltel!"
|
||||
|
||||
The fireball formed around his fingers and he chucked it right into the pit of
|
||||
thorns. They were all set on fire simultaneously. After a brilliant blaze, the
|
||||
fire petered out into nothing as fast as it started. He looked over to see if
|
||||
the firewood was still there, his spell circle was still active as a flashlight
|
||||
but that kindling was nowhere to be seen. It was incinerated with everything
|
||||
else.
|
||||
|
||||
He had to resist shouting out in anger again. *Okay, okay, calm down. I set off
|
||||
a massive signal fire. That should alert someone. I can't keep this spell circle
|
||||
up, I'll mind down and then I'll be in worse trouble.* He killed off the spell
|
||||
with a flick of the wrist and the darkness crept in. He was alone. I need to
|
||||
keep walking. So he started walking, not realizing that he changed direction
|
||||
after the incident with the thorns.
|
||||
|
||||
Left! Right! Left! Right! Left! Right! Each step felt angry and defiant. Tosen
|
||||
started to feel legitimate anger at the desert. It was normally his home, he
|
||||
grew up in the sands of Miau, but tonight it was his enemy. He defiantly marched
|
||||
towards where he thought Riltash was, but got no closer.
|
||||
|
||||
It was a very long night walking towards town. It was a desperate, angry march.
|
||||
He stopped a few times to take a bite of jerkey and swig it down with the bare
|
||||
minimum of water he could get away with. He thought it would be colder, but it
|
||||
turns out all that fur ended up going towards something.
|
||||
|
||||
The night continued and was broken by the inklings of a sunrise. Tosen looked up
|
||||
in dismay. He had walked all night and he was nowhere closer to his destination.
|
||||
An overwhelming feeling of sadness blanketed him and he broke down to start
|
||||
crying.
|
||||
|
||||
He looked forward and saw something different. He saw what looked like the faint
|
||||
outline of Riltash's signal statue. His sadness was instantly transmuted to a
|
||||
mixture of relief and joy and his second wind started to hit. He trudged forward
|
||||
towards that statue. Towards his salvation. Towards his client. Towards his
|
||||
paycheck. Towards the next step to move out to Zhalram with his friends. Towards
|
||||
his future.
|
||||
|
||||
He kept up his pace and got closer. The statue looked wrong. Riltash has the
|
||||
visage of one of the water goddesses in the region. This looked different,
|
||||
almost like a Chee. He wasn't aware of any local Chee deities. He looked down
|
||||
and saw shimmers. It almost looked like a mirage, but then he remembered
|
||||
something. There were rumors of an oasis south of Riltash. Could this be that?
|
||||
Could there be water?
|
||||
|
||||
His second wind became a third and then a fourth wind. He got close enough to
|
||||
take a better look at everything and it was that oasis!
|
||||
|
||||
*Water!*
|
||||
|
||||
His walk became a sprint and the sand started to be diluted with grass. As he
|
||||
walked on the grass he suddenly felt an overwhelming sense of calm. It was as if
|
||||
all of the anger, all the vitriol, all the hatred towards the desert vanished in
|
||||
an instant. He paused for a moment but then continued on. The promise of fresh
|
||||
water was too great. He was so thirsty.
|
||||
|
||||
He put his pack down, took off his shoes and tested the water with a paw. It was
|
||||
cool to the touch, about 10 degrees celsius. It was the real deal. It was water.
|
||||
He took off his robe, folded it haphazardly next to his pack and grabbed his
|
||||
hydroflask. He opened it and shoved it under so it could be filled. Once he was
|
||||
satisfied that it was full, he bent over and started to lap up the water
|
||||
greedily.
|
||||
|
||||
A figure vaguely resembling the statue was watching from a nearby house. The
|
||||
figure chuckled to themselves. They decided they should intervene. They donned a
|
||||
white robe and walked out to the weary traveler.
|
||||
|
||||
Tosen was enamoured by the water. His exhaustion had finally caught up to him.
|
||||
He looked back at his pack and saw a figure walking towards him from some kind
|
||||
of house. He instantly jumped to alertness, but didn't feel the fear that
|
||||
generally came with being startled like that. The figure felt familiar yet alien
|
||||
somehow.
|
||||
|
||||
The figure looked at his pack and his visibly broken compass. They looked right
|
||||
into Tosen's eyes. "Rough day?"
|
||||
|
||||
Tosen stammered a few times and eventually managed to come up with a reply:
|
||||
"Y...yeah. I was caught in that sandstorm yesterday. I hid from it in a broken
|
||||
wagon."
|
||||
|
||||
The figure reached out a hand to him. "Come with me. You need a rest. I'll come
|
||||
back to take care of your things. I have a spare bed for travelers like you."
|
||||
|
||||
Tosen didn't have enough energy to argue with the stranger's offer of
|
||||
hospitality and followed them into their house. They guided Tosen to the guest
|
||||
room and sat on one of the chairs. Tosen collapsed on the most comfortable bed
|
||||
he had ever felt in his life. All he could get out was a weak "thank....youuuu"
|
||||
before his lost sleep caught up and he was out like a light. The figure pulled a
|
||||
blanket over him and closed the shades to make the room nice and dark.
|
||||
|
||||
Tosen was asleep until the late afternoon. The figure had moved his stuff
|
||||
inside, done his laundry, mended a hole in the pack and was lounging in a chair
|
||||
for a nap of their own.
|
||||
|
||||
Tosen woke up, stretched out and yawned loudly. He looked up at the ceiling and
|
||||
realized how unfamiliar it was. That angel in his dream was real. Had he
|
||||
actually walked through the night? The figure knocked at the door. "Hey, come
|
||||
and have a meal. You must be starving." He was. Tosen stood up and opened the
|
||||
door. The figure was wearing a white robe and a golden necklace. They looked
|
||||
like the archetypal vision of Chee beauty. Tosen noted that he was unable to
|
||||
refer to that figure with any pronoun but "they". *That's weird...*
|
||||
|
||||
The figure started to speak: "I am Shal'tash. I saw you hurting and I decided to
|
||||
intervene and help you. Come, I have some food almost ready." Shal'tash started
|
||||
to walk towards the kitchen and Tosen followed. He made his way to a rather
|
||||
ordinary looking wooden table and took a seat. His stuff was near the table and
|
||||
he was grateful for his host's gratuity.
|
||||
|
||||
They were making pancakes. The batter was being poured into a metal pan in
|
||||
little groups. Tosen noticed that the stove seemed to be powered by its own
|
||||
magic circle, a non-organic magic emitter was being used to create the fire
|
||||
needed for cooking. It was a weak burner, but it was enough for Shal'tash to
|
||||
cook with.
|
||||
|
||||
Tosen was befuddled. He had never seen such a thing in action. He got up and
|
||||
looked at it closely. Shal'tash looked back and smiled, "Never seen a stove
|
||||
burner before?"
|
||||
|
||||
"Not like that no, it looks like it's casting a weak fire spell, but
|
||||
constantly."
|
||||
|
||||
"This is a lot more efficient than the coal burning stoves you have. This lets
|
||||
you use the energy equivalent of a fireball to get a half hour of cooking heat,
|
||||
or an hour or two of torchlight. I'm surprised you didn't know about this."
|
||||
|
||||
Tosen looked confused. "You mean you can use the square level spell to
|
||||
supercharge the triangle level spell? No, they never taught us this. But how is
|
||||
the burner even working?"
|
||||
|
||||
Shal'tash laughed. "It's nothing special. I just rooted the circle under the pan
|
||||
instead of on my hand. Here, you try it." They flicked their wrist and banished
|
||||
the magic circle. "Now cast a fireball but focus on the pan instead of your
|
||||
hand, let it simmer a bit, and then kick off create fire."
|
||||
|
||||
Tosen was confused but nodded and tried to comply. After a moment Shal'tash
|
||||
piped in: "no, don't think about where the pan is relative to your hand. Think
|
||||
about where the pan is relative to the pan. You're so close. I know you can do
|
||||
it."
|
||||
|
||||
Tosen nodded and started over. The circle started to be inscribed below the pan
|
||||
and Shal'tash's face lit up like a Christmas tree. "Toor sha!"
|
||||
|
||||
The burner was lit. The fire was continuously burning and Tosen didn't feel the
|
||||
sting of a continuous cast. "Perfect. See how easy this is? Spend the mana on
|
||||
the fireball, then use it for the weaker spell. No need to waste any."
|
||||
|
||||
Tosen was astounded. It normally took him ages to learn magical skills, but here
|
||||
he was on the second try with this person and their vague instruction and he did
|
||||
two things he thought was impossible. It was like magic was all new all over
|
||||
again. Can I use this to make a bunch of fireballs when casting a firestorm? How
|
||||
far does this go?
|
||||
|
||||
"Be careful with this, you could really hurt someone if you do displacement
|
||||
foolishly. They must have stopped teaching it for a reason." Shal'tash finished
|
||||
the stack of pancakes and put the plate in the middle of the table. "Now let's
|
||||
eat!"
|
||||
|
||||
They shared a meal. It was just what Tosen needed.
|
||||
|
||||
The meal was finished. Shal'tash looked over to Tosen. "So where are you headed?
|
||||
I can point you in the right direction."
|
||||
|
||||
"Riltash, I have a delivery that I'm incredibly late for by now."
|
||||
|
||||
Shal'tash chuckled and pointed towards the statue. "The statue points towards
|
||||
Riltash. Just go straight north and you'll get there in 20 minutes."
|
||||
|
||||
Tosen looked incredulous. "I was really that close?"
|
||||
|
||||
"Yeah, though it looked like you needed to get lost. It can be good for you."
|
||||
|
||||
He didn't understand what they meant by that, but he didn't think he needed to.
|
||||
|
||||
Shal'tash walked with Tosen to the north side of the oasis. Tosen looked towards
|
||||
his saviour and was suddenly overcome with emotion. "Thank you so much. You
|
||||
saved me."
|
||||
|
||||
"You are welcome. I saved you because I was in a situation worse than yours when
|
||||
I found this oasis. I don't want anyone to experience the pain that I have felt,
|
||||
so I saved you before it could get that bad."
|
||||
|
||||
"What can I do to repay you?"
|
||||
|
||||
"You don't need to do anything right now. Just save someone else when you can.
|
||||
If you want, come back here and give me a visit. It'd be fun to catch up,
|
||||
Tosen."
|
||||
|
||||
"Thanks again! I'll be back!"
|
||||
|
||||
Tosen walked off towards his payday. He looked back every so often and the oasis
|
||||
became more distant and then faded completely from sight into the rest of the
|
||||
sands. He was alone again, but not in spirit.
|
||||
|
||||
He never noticed that they knew his name without him telling them his name.
|
||||
|
||||
Shal'tash walked back towards their house and stood by their cactus. They
|
||||
watched as Tosen faded into the sands and then headed inside. Their job was
|
||||
complete.
|
|
@ -3,7 +3,7 @@ title: The Origin of h
|
|||
date: 2015-12-14
|
||||
---
|
||||
|
||||
NOTE: There is a [second part](https://xeiaso.net/blog/formal-grammar-of-h-2019-05-19) to this article now with a formal grammar.
|
||||
NOTE: There is a [second part](https://christine.website/blog/formal-grammar-of-h-2019-05-19) to this article now with a formal grammar.
|
||||
|
||||
For a while I have been pepetuating a small joke between my friends, co-workers and community members of various communities (whether or not this has been beneficial or harmful is out of the scope of this post). The whole "joke" is that someone says "h", another person says "h" back.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ tags:
|
|||
---
|
||||
|
||||
EDIT(M02 20 2020): I've written a bit of a rebuttal to my own post
|
||||
[here](https://xeiaso.net/blog/i-was-wrong-about-nix-2020-02-10). I am
|
||||
[here](https://christine.website/blog/i-was-wrong-about-nix-2020-02-10). I am
|
||||
keeping this post up for posterity.
|
||||
|
||||
I don't really know how I feel about [Nix][nix]. It's a functional package
|
||||
|
|
|
@ -42,7 +42,7 @@ how things changed:
|
|||
As of the time of writing this post, it is January third, 2020 and the roadmap
|
||||
is apparently to release V 0.2 this month.
|
||||
|
||||
Let's see what's been fixed since [my last article](https://xeiaso.net/blog/v-vaporware-2019-06-23).
|
||||
Let's see what's been fixed since [my last article](https://christine.website/blog/v-vaporware-2019-06-23).
|
||||
|
||||
## Compile Speed
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ designing this, but I think the next character in my blog is going to be an
|
|||
anthro snow leopard named Alicia. I want Alicia to be a beginner that is very
|
||||
new to computer programming and other topics, which would then make Mara into
|
||||
more of a teacher type. I may also introduce my own OC Cadey (the orca looking
|
||||
thing you can see [here](https://xeiaso.net/static/img/avatar_large.png)
|
||||
thing you can see [here](https://christine.website/static/img/avatar_large.png)
|
||||
or in the favicon of my site) into the mix to reply to these questions in
|
||||
something more close to the Socratic method.
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ Be well.
|
|||
---
|
||||
|
||||
Every so often I like to check in on the [V Programming Language][vlang]. It's been
|
||||
about six months since [my last post](https://xeiaso.net/blog/v-vvork-in-progress-2020-01-03),
|
||||
about six months since [my last post](https://christine.website/blog/v-vvork-in-progress-2020-01-03),
|
||||
so I thought I'd take another look at it and see what progress has been done in six
|
||||
months.
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ job. TLS configuration is not its job. Its job is to run your code. Everything
|
|||
else should just be provided by the system.
|
||||
|
||||
I wrote a
|
||||
[blogpost](https://xeiaso.net/blog/land-1-syscalls-file-io-2018-06-18)
|
||||
[blogpost](https://christine.website/blog/land-1-syscalls-file-io-2018-06-18)
|
||||
about this work and even did a
|
||||
[talk at GoCon
|
||||
Canada](https://xeiaso.net/talks/webassembly-on-the-server-system-calls-2019-05-31)
|
||||
Canada](https://christine.website/talks/webassembly-on-the-server-system-calls-2019-05-31)
|
||||
about it.
|
||||
|
||||
And this worked for several months as I learned WebAssembly and started to
|
||||
|
@ -93,8 +93,8 @@ people understand low-level operating system development.
|
|||
|
||||
I've even written a few blogposts about Olin:
|
||||
|
||||
- [Olin: Why](https://xeiaso.net/blog/olin-1-why-09-1-2018)
|
||||
- [Olin: The Future](https://xeiaso.net/blog/olin-2-the-future-09-5-2018)
|
||||
- [Olin: Why](https://christine.website/blog/olin-1-why-09-1-2018)
|
||||
- [Olin: The Future](https://christine.website/blog/olin-2-the-future-09-5-2018)
|
||||
|
||||
But, this was great for running stuff interactively and via the command line. It
|
||||
left me wanting more. I wanted to have that mythical functions as a service
|
||||
|
@ -230,5 +230,5 @@ keep the dream alive!
|
|||
[olincwa]: https://github.com/Xe/olin/tree/master/docs/cwa-spec
|
||||
[olincwarust]: https://github.com/Xe/olin/tree/master/cwa/olin
|
||||
[olincwatest]: https://github.com/Xe/olin/blob/master/cwa/tests/src/main.rs
|
||||
[olintempleos]: https://xeiaso.net/blog/templeos-2-god-the-rng-2019-05-30
|
||||
[olintempleos]: https://christine.website/blog/templeos-2-god-the-rng-2019-05-30
|
||||
[wasmcloud]: https://tulpa.dev/within/wasmcloud
|
||||
|
|
|
@ -530,7 +530,7 @@ giving up when there is no more work to be done.
|
|||
inside the Google monorepo that escaped out into the world. They also claim to
|
||||
have an internal tool that makes
|
||||
[`context.TODO()`](https://pkg.go.dev/context#TODO) useful (probably by showing
|
||||
you the callsites above that function?), but they never released that tool as
|
||||
you the callsities above that function?), but they never released that tool as
|
||||
open source so it’s difficult to know where to use it without that added
|
||||
context.</xeblog-conv>
|
||||
|
||||
|
@ -592,7 +592,7 @@ You can attach this to an HTTP request by using
|
|||
[`http.NewRequestWithContext`](https://pkg.go.dev/net/http#NewRequestWithContext):
|
||||
|
||||
```go
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://xeiaso.net/.within/health", nil)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://christine.website/.within/health", nil)
|
||||
```
|
||||
|
||||
And then when you execute the request (such as with `http.DefaultClient.Do(req)`)
|
||||
|
@ -888,15 +888,9 @@ fuzzing, RISC-V support, binary/octal/hexadecimal/imaginary number literals,
|
|||
WebAssembly support, so many garbage collector improvements and more. This has
|
||||
added up to make Go a fantastic choice for developing server-side applications.
|
||||
|
||||
I, as some random person on the internet that is not associated with the Go
|
||||
team, think that if there was sufficient political will that they could probably
|
||||
label what we have as Go 2, but I don’t think that is going to happen any time
|
||||
soon. Until then, we still have a very great set of building blocks that allow
|
||||
you to make easy to maintain production quality services, and I don’t see that
|
||||
changing any time soon.
|
||||
|
||||
---
|
||||
|
||||
<xeblog-conv name="Mara" mood="happy">If you had subscribed to the
|
||||
[Patreon](https://patreon.com/cadey) you could have read this a week
|
||||
ago!</xeblog-conv>
|
||||
I, as some random person on the
|
||||
internet that is not associated with the Go team, think that if there was
|
||||
sufficient political will that they could probably label what we have as Go 2,
|
||||
but I don’t think that is going to happen any time soon. Until then, we still
|
||||
have a very great set of building blocks that allow you to make easy to maintain
|
||||
production quality services, and I don’t see that changing any time soon.
|
||||
|
|
|
@ -15,4 +15,4 @@ of that talk has been posted.
|
|||
I hope you enjoy! I have some more blogposts in the queue but I've been sleeping horribly lately. Here's hoping that clears up.
|
||||
|
||||
[goconcanada]: https://gocon.ca/
|
||||
[talklink]: https://xeiaso.net/talks/webassembly-on-the-server-system-calls-2019-05-31
|
||||
[talklink]: https://christine.website/talks/webassembly-on-the-server-system-calls-2019-05-31
|
||||
|
|
|
@ -31,7 +31,7 @@ $ curl https://mi.within.website/api/webmention/01ERGGEG7DCKRH3R7DH4BXZ6R9 | jq
|
|||
{
|
||||
"id": "01ERGGEG7DCKRH3R7DH4BXZ6R9",
|
||||
"source_url": "https://maya.land/responses/2020/12/01/i-think-this-blog-post-might-have-been.html",
|
||||
"target_url": "https://xeiaso.net/blog/toast-sandwich-recipe-2019-12-02",
|
||||
"target_url": "https://christine.website/blog/toast-sandwich-recipe-2019-12-02",
|
||||
"title": null
|
||||
}
|
||||
```
|
||||
|
|
|
@ -80,7 +80,7 @@ in one of a few ways:
|
|||
Some concepts are pulled in from various documents and ideas in a slightly
|
||||
[kasmakfa](https://write.as/excerpts/practical-kasmakfa) manner, but overall the
|
||||
most "confusing" thing to new readers is going to be related to this comment in
|
||||
the [anapana](https://xeiaso.net/blog/when-then-zen-anapana-2018-08-15)
|
||||
the [anapana](https://christine.website/blog/when-then-zen-anapana-2018-08-15)
|
||||
feature:
|
||||
|
||||
> Note: "the body" means the sack of meat and bone that you are currently living inside. For the purposes of explanation of this technique, please consider what makes you yourself separate from the body you live in.
|
||||
|
|
|
@ -32,7 +32,7 @@ This article is a more verbose version of [the correlating feature from when-the
|
|||
|
||||
The When Then Zen project aims to describe the finer points of meditative concepts in plain English. As such, we start assuming just about nothing and build fractally on top of concepts derived from common or plain English usage of the terms. Some of these techniques may be easier for people with a more intensive meditative background, but try things and see what works best for you. Meditation in general works a lot better when you have a curious and playful attitude about figuring things out.
|
||||
|
||||
I'm not perfect. I don't know what will work best for you. A lot of this is documenting both my practice and what parts of what books helped me "get it". If this works for you, [please let me know](https://xeiaso.net/contact). If this doesn't work for you, [please let me know](https://xeiaso.net/contact). I will use this information for making direct improvements to these documents.
|
||||
I'm not perfect. I don't know what will work best for you. A lot of this is documenting both my practice and what parts of what books helped me "get it". If this works for you, [please let me know](https://christine.website/contact). If this doesn't work for you, [please let me know](https://christine.website/contact). I will use this information for making direct improvements to these documents.
|
||||
|
||||
As for your practice, twist the rules into circles and scrape out the parts that don't work if it helps you. Find out how to integrate it into your life in the best manner and go with it.
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ tags:
|
|||
---
|
||||
|
||||
This website has been a progressive web app [for a long
|
||||
time](https://xeiaso.net/blog/progressive-webapp-conversion-2019-01-26).
|
||||
time](https://christine.website/blog/progressive-webapp-conversion-2019-01-26).
|
||||
This means that you can install my blog to your phone as if it was a normal app
|
||||
via the share menu in Safari on iOS or via other native prompts on other
|
||||
browsers. However, this is not enough. In the constant pursuit of advancement I
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
---
|
||||
title: How to Store an SSH Key on a Yubikey
|
||||
date: 2022-05-27
|
||||
series: howto
|
||||
tags:
|
||||
- yubikey
|
||||
- security
|
||||
---
|
||||
|
||||
SSH keys suck. They are a file on the disk and you can easily move it to other
|
||||
machines instead of storing them in hardware where they can't be exfiltrated.
|
||||
Using a password to encrypt the private key is a viable option, but the UX for
|
||||
that is hot garbage. It's allegedly the future, so surely we MUST have some way
|
||||
to make this all better, right?
|
||||
|
||||
<xeblog-conv name="Numa" mood="delet">\>implying there is a way to make anything
|
||||
security related better</xeblog-conv>
|
||||
|
||||
Luckily, there is actually something we can do for this! As of [OpenSSH
|
||||
8.2](https://www.openssh.com/releasenotes.html#8.2) (Feburary 14, 2020) you are
|
||||
able to store an SSH private key on a yubikey! Here's how to do it.
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">This should work on other FIDO keys like
|
||||
Google's Titan, but we don't have access to one over here and as such haven't
|
||||
tested it. Your mileage may vary. We are told that it works with the Google
|
||||
Titan key that is handed out to Go contributors.</xeblog-conv>
|
||||
|
||||
First install `yubikey-manager` (see
|
||||
[here](https://www.yubico.com/support/download/yubikey-manager/) for more
|
||||
information, or run `nix-shell -p yubikey-manager` to run it without installing
|
||||
it on NixOS), plug in your yubikey and run `ykman list`:
|
||||
|
||||
```console
|
||||
$ ykman list
|
||||
YubiKey 5C NFC (5.4.3) [OTP+FIDO+CCID] Serial: 4206942069
|
||||
```
|
||||
|
||||
If you haven't set a PIN for the yubikey yet, follow
|
||||
[this](https://docs.yubico.com/software/yubikey/tools/ykman/FIDO_Commands.html#ykman-fido-access-change-pin-options)
|
||||
to set a PIN of your choice. Once you do this, you can generate a new SSH key
|
||||
with the following command:
|
||||
|
||||
```
|
||||
ssh-keygen -t ed25519-sk -O resident
|
||||
```
|
||||
|
||||
<xeblog-conv name="Mara" mood="hacker">If that fails, try `ecdsa-sk`
|
||||
instead! Some hardware keys may not support storing the key on the key
|
||||
itself.</xeblog-conv>
|
||||
|
||||
Then enter in a super secret password (such as the Tongues you received as a kid
|
||||
when you were forced into learning the bible against your will) twice and then
|
||||
add that key to your agent with `ssh-add -K`. Then you can list your keys with
|
||||
`ssh-add -L`:
|
||||
|
||||
```console
|
||||
$ ssh-add -L
|
||||
sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIKgGePSwpBuHUhrFCRLch9Usqi7L0fKtgTRnh6F/R+ruAAAABHNzaDo= cadey@shachi
|
||||
```
|
||||
|
||||
Then you can copy this public key to GitHub or whatever and authenticate as
|
||||
normal. The private key is stored on your yubikey directly and you can add it
|
||||
with `ssh-add -K`. You can delete the ssh key stub at `~/.ssh/id_ed25519_sk` and
|
||||
then your yubikey will be the only thing holding that key.
|
|
@ -8,7 +8,7 @@ tags:
|
|||
---
|
||||
|
||||
As I mentioned
|
||||
[before](https://xeiaso.net/blog/colemak-layout-2020-08-15), I ordered a
|
||||
[before](https://christine.website/blog/colemak-layout-2020-08-15), I ordered a
|
||||
[ZSA Moonlander](https://zsa.io/moonlander) and it has finally arrived. I am
|
||||
writing this post from my Moonlander, and as such I may do a few more typos
|
||||
than normal, I'm still getting used to this.
|
||||
|
|
|
@ -22,7 +22,7 @@ no influence pushing me either way on this keyboard.
|
|||
desk](https://cdn.christine.website/file/christine-static/img/keeb/Elm3dN8XUAAYHws.jpg)
|
||||
|
||||
[That 3d printed brain is built from the 3D model that was made as a part of <a
|
||||
href="https://xeiaso.net/blog/brain-fmri-to-3d-model-2019-08-23">this
|
||||
href="https://christine.website/blog/brain-fmri-to-3d-model-2019-08-23">this
|
||||
blogpost</a>.](conversation://Mara/hacker)
|
||||
|
||||
## tl;dr
|
||||
|
@ -131,7 +131,7 @@ standard [Colemak](https://Colemak.com/) layout and it is currently the layer I
|
|||
type the fastest on. I have the RGB configured so that it is mostly pink with
|
||||
the homerow using a lighter shade of pink. The color codes come from my logo
|
||||
that you can see in the favicon [or here for a larger
|
||||
version](https://xeiaso.net/static/img/avatar_large.png).
|
||||
version](https://christine.website/static/img/avatar_large.png).
|
||||
|
||||
I also have a qwerty layer for gaming. Most games expect qwerty keyboards and
|
||||
this is an excellent stopgap to avoid having to rebind every game that I want to
|
||||
|
|
95
config.dhall
95
config.dhall
|
@ -1,11 +1,96 @@
|
|||
let xesite = ./dhall/types/package.dhall
|
||||
let Person =
|
||||
{ Type =
|
||||
{ name : Text
|
||||
, tags : List Text
|
||||
, gitLink : Optional Text
|
||||
, twitter : Optional Text
|
||||
}
|
||||
, default =
|
||||
{ name = ""
|
||||
, tags = [] : List Text
|
||||
, gitLink = None Text
|
||||
, twitter = None Text
|
||||
}
|
||||
}
|
||||
|
||||
let Config = xesite.Config
|
||||
let Author =
|
||||
{ Type =
|
||||
{ name : Text
|
||||
, handle : Text
|
||||
, picUrl : Optional Text
|
||||
, link : Optional Text
|
||||
, twitter : Optional Text
|
||||
, default : Bool
|
||||
, inSystem : Bool
|
||||
}
|
||||
, default =
|
||||
{ name = ""
|
||||
, handle = ""
|
||||
, picUrl = None Text
|
||||
, link = None Text
|
||||
, twitter = None Text
|
||||
, default = False
|
||||
, inSystem = False
|
||||
}
|
||||
}
|
||||
|
||||
let defaultPort = env:PORT ? 3030
|
||||
|
||||
let defaultWebMentionEndpoint =
|
||||
env:WEBMENTION_ENDPOINT
|
||||
? "https://mi.within.website/api/webmention/accept"
|
||||
|
||||
let Config =
|
||||
{ Type =
|
||||
{ signalboost : List Person.Type
|
||||
, authors : List Author.Type
|
||||
, port : Natural
|
||||
, clackSet : List Text
|
||||
, resumeFname : Text
|
||||
, webMentionEndpoint : Text
|
||||
, miToken : Text
|
||||
}
|
||||
, default =
|
||||
{ signalboost = [] : List Person.Type
|
||||
, authors =
|
||||
[ Author::{
|
||||
, name = "Xe Iaso"
|
||||
, handle = "xe"
|
||||
, picUrl = Some "/static/img/avatar.png"
|
||||
, link = Some "https://christine.website"
|
||||
, twitter = Some "theprincessxena"
|
||||
, default = True
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{
|
||||
, name = "Jessie"
|
||||
, handle = "Heartmender"
|
||||
, picUrl = Some
|
||||
"https://cdn.christine.website/file/christine-static/img/UPRcp1pO_400x400.jpg"
|
||||
, link = Some "https://heartmender.writeas.com"
|
||||
, twitter = Some "BeJustFine"
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{
|
||||
, name = "Ashe"
|
||||
, handle = "ectamorphic"
|
||||
, picUrl = Some
|
||||
"https://cdn.christine.website/file/christine-static/img/FFVV1InX0AkDX3f_cropped_smol.jpg"
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{ name = "Nicole", handle = "Twi", inSystem = True }
|
||||
, Author::{ name = "Mai", handle = "Mai", inSystem = True }
|
||||
]
|
||||
, port = defaultPort
|
||||
, clackSet = [ "Ashlynn" ]
|
||||
, resumeFname = "./static/resume/resume.md"
|
||||
, webMentionEndpoint = defaultWebMentionEndpoint
|
||||
, miToken = "${env:MI_TOKEN as Text ? ""}"
|
||||
}
|
||||
}
|
||||
|
||||
in Config::{
|
||||
, signalboost = ./dhall/signalboost.dhall
|
||||
, authors = ./dhall/authors.dhall
|
||||
, signalboost = ./signalboost.dhall
|
||||
, clackSet =
|
||||
[ "Ashlynn", "Terry Davis", "Dennis Ritchie", "Steven Hawking" ]
|
||||
, jobHistory = ./dhall/jobHistory.dhall
|
||||
}
|
||||
|
|
11
css/shim.css
11
css/shim.css
|
@ -44,6 +44,17 @@ img {
|
|||
padding-right: 1em;
|
||||
}
|
||||
|
||||
/* xeblog-conv:not(:defined) { */
|
||||
/* display: block; */
|
||||
/* border-left: 0.25ch solid green; */
|
||||
/* padding-left: 1.75ch; */
|
||||
/* } */
|
||||
|
||||
/* xeblog-conv:before:not(:defined) { */
|
||||
/* content: "<"attr(name)">"; */
|
||||
/* font-weight: bold; */
|
||||
/* } */
|
||||
|
||||
.warning {
|
||||
background-color: #282828;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ in pkgs.stdenv.mkDerivation {
|
|||
cp -rf $src/blog $out/blog
|
||||
cp -rf $src/css $out/css
|
||||
cp -rf $src/gallery $out/gallery
|
||||
cp -rf $src/signalboost.dhall $out/signalboost.dhall
|
||||
cp -rf $src/static $out/static
|
||||
cp -rf $src/talks $out/talks
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
let Author = ./types/Author.dhall
|
||||
|
||||
in [ Author::{
|
||||
, name = "Xe Iaso"
|
||||
, handle = "xe"
|
||||
, picUrl = Some "/static/img/avatar.png"
|
||||
, link = Some "https://christine.website"
|
||||
, twitter = Some "theprincessxena"
|
||||
, default = True
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{
|
||||
, name = "Jessie"
|
||||
, handle = "Heartmender"
|
||||
, picUrl = Some
|
||||
"https://cdn.christine.website/file/christine-static/img/UPRcp1pO_400x400.jpg"
|
||||
, twitter = Some "BeJustFine"
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{
|
||||
, name = "Ashe"
|
||||
, handle = "ectamorphic"
|
||||
, picUrl = Some
|
||||
"https://cdn.christine.website/file/christine-static/img/FFVV1InX0AkDX3f_cropped_smol.jpg"
|
||||
, inSystem = True
|
||||
}
|
||||
, Author::{ name = "Nicole", handle = "Twi", inSystem = True }
|
||||
, Author::{ name = "Mai", handle = "Mai", inSystem = True }
|
||||
, Author::{ name = "Sephira", handle = "Sephie", inSystem = True }
|
||||
]
|
|
@ -1,346 +0,0 @@
|
|||
let xesite = ./types/package.dhall
|
||||
|
||||
let Job = xesite.Job
|
||||
|
||||
let Salary = xesite.Salary
|
||||
|
||||
let Stock = xesite.Stock
|
||||
|
||||
let StockKind = xesite.StockKind
|
||||
|
||||
let Company = xesite.Company
|
||||
|
||||
let Location = xesite.Location
|
||||
|
||||
let annual = \(rate : Natural) -> Salary::{ amount = rate }
|
||||
|
||||
let hourly = \(rate : Natural) -> Salary::{ amount = rate, per = "hour" }
|
||||
|
||||
let annualCAD = \(rate : Natural) -> Salary::{ amount = rate, currency = "CAD" }
|
||||
|
||||
let mercerIsland =
|
||||
Location::{
|
||||
, city = "Mercer Island"
|
||||
, stateOrProvince = "WA"
|
||||
, country = "USA"
|
||||
}
|
||||
|
||||
let bellevue = mercerIsland // { city = "Bellevue" }
|
||||
|
||||
let mountainView =
|
||||
Location::{
|
||||
, city = "Mountain View"
|
||||
, stateOrProvince = "CA"
|
||||
, country = "USA"
|
||||
, remote = False
|
||||
}
|
||||
|
||||
let sf = mountainView // { city = "San Fransisco" }
|
||||
|
||||
let montreal =
|
||||
Location::{
|
||||
, city = "Montreal"
|
||||
, stateOrProvince = "QC"
|
||||
, country = "CAN"
|
||||
, remote = False
|
||||
}
|
||||
|
||||
let ottawa =
|
||||
Location::{ city = "Ottawa", stateOrProvince = "ON", country = "CAN" }
|
||||
|
||||
let imvu =
|
||||
Company::{
|
||||
, name = "IMVU"
|
||||
, url = Some "https://imvu.com"
|
||||
, tagline =
|
||||
"a company whose mission is to help people find and communicate with eachother. Their main product is a 3D avatar-based chat client and its surrounding infrastructure allowing creators to make content for the avatars to wear."
|
||||
, location = mountainView // { city = "Redwood City" }
|
||||
}
|
||||
|
||||
let tailscale =
|
||||
Company::{
|
||||
, name = "Tailscale"
|
||||
, url = Some "https://tailscale.com"
|
||||
, tagline =
|
||||
"a zero config VPN for building secure networks. Install on any device in minutes. Remote access from any network or physical location."
|
||||
, location = ottawa // { city = "Toronto" }
|
||||
}
|
||||
|
||||
in [ Job::{
|
||||
, company = Company::{
|
||||
, name = "Symplicity"
|
||||
, tagline =
|
||||
"a company that provides students with the tools and connections they need to enhance their employability while preparing to succeed in today's job market."
|
||||
, url = Some "https://www.symplicity.com"
|
||||
, location = Location::{
|
||||
, city = "Arlington"
|
||||
, stateOrProvince = "VA"
|
||||
, country = "USA"
|
||||
, remote = False
|
||||
}
|
||||
}
|
||||
, title = "Junior Systems Administrator"
|
||||
, startDate = "2013-11-11"
|
||||
, endDate = Some "2014-01-06"
|
||||
, daysWorked = Some 56
|
||||
, salary = annual 50000
|
||||
, leaveReason = Some "terminated"
|
||||
, locations =
|
||||
[ Location::{
|
||||
, city = "Arlington"
|
||||
, stateOrProvince = "VA"
|
||||
, country = "USA"
|
||||
, remote = False
|
||||
}
|
||||
]
|
||||
, highlights = [ "Python message queue processing" ]
|
||||
, hideFromResume = True
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "OpDemand"
|
||||
, defunct = True
|
||||
, tagline =
|
||||
"the company behind the open source project Deis, a distributed platform-as-a-service (PaaS) designed from the ground up to emulate Heroku but on privately owned servers."
|
||||
, location = Location::{
|
||||
, city = "Boulder"
|
||||
, stateOrProvince = "CO"
|
||||
, country = "USA"
|
||||
}
|
||||
}
|
||||
, title = "Software Engineering Intern"
|
||||
, startDate = "2014-07-14"
|
||||
, endDate = Some "2014-08-27"
|
||||
, daysWorked = Some 44
|
||||
, daysBetween = Some 189
|
||||
, salary = annual 35000
|
||||
, leaveReason = Some "terminated"
|
||||
, locations = [ mercerIsland ]
|
||||
, highlights =
|
||||
[ "Built new base image for Deis components"
|
||||
, "Research and development on a new builder component"
|
||||
]
|
||||
, hideFromResume = True
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "Appen"
|
||||
, url = Some "https://appen.com/"
|
||||
, tagline =
|
||||
"is a company that uses crowdsourcing to have its customers submit tasks to be done, similar to Amazon's Mechanical Turk."
|
||||
, location = mountainView // { city = "San Francisco", remote = True }
|
||||
}
|
||||
, title = "Consultant"
|
||||
, contract = True
|
||||
, startDate = "2014-09-17"
|
||||
, endDate = Some "2014-10-15"
|
||||
, daysWorked = Some 28
|
||||
, daysBetween = Some 21
|
||||
, salary = hourly 90
|
||||
, leaveReason = Some "contract not renewed"
|
||||
, locations = [ mercerIsland ]
|
||||
, highlights =
|
||||
[ "Research and development on scalable Linux deployments on AWS via CoreOS and Docker"
|
||||
, "Development of in-house tools to speed instance creation"
|
||||
, "Laid groundwork on the creation and use of better tools for managing large clusters of CoreOS and Fleet machines"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "VTCSecure"
|
||||
, url = Some "https://www.vtcsecure.com/"
|
||||
, tagline =
|
||||
"a company dedicated to helping with custom and standard audio/video conferencing solutions. They specialize in helping the deaf and blind communicate over today's infrastructure without any trouble on their end."
|
||||
, location = Location::{
|
||||
, city = "Clearwater"
|
||||
, stateOrProvince = "FL"
|
||||
, country = "USA"
|
||||
}
|
||||
}
|
||||
, title = "Consultant"
|
||||
, contract = True
|
||||
, startDate = "2014-10-27"
|
||||
, endDate = Some "2015-02-09"
|
||||
, daysWorked = Some 105
|
||||
, daysBetween = Some 12
|
||||
, salary = hourly 90
|
||||
, leaveReason = Some "contract not renewed"
|
||||
, locations = [ mercerIsland ]
|
||||
, highlights =
|
||||
[ "Started groundwork for a dynamically scalable infrastructure on a project for helping the blind see things"
|
||||
, "Developed a prototype of a new website for VTCSecure"
|
||||
, "Education on best practices using Docker and CoreOS"
|
||||
, "Learning Freeswitch"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = imvu
|
||||
, title = "Site Reliability Engineer"
|
||||
, startDate = "2015-03-30"
|
||||
, endDate = Some "2016-03-07"
|
||||
, daysWorked = Some 343
|
||||
, daysBetween = Some 49
|
||||
, salary = annual 125000 // { stock = Some Stock::{ amount = 20000 } }
|
||||
, leaveReason = Some "demoted"
|
||||
, locations = [ mountainView ]
|
||||
, highlights =
|
||||
[ "Wrote up technical designs"
|
||||
, "Implemented technical designs on an over 800 machine cluster"
|
||||
, "Continuous learning of a lot of very powerful systems and improving upon them when it is needed"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = imvu
|
||||
, title = "Systems Administrator"
|
||||
, startDate = "2016-03-08"
|
||||
, endDate = Some "2016-04-01"
|
||||
, daysWorked = Some 24
|
||||
, daysBetween = Some 1
|
||||
, salary = annual 105000
|
||||
, leaveReason = Some "quit"
|
||||
, locations = [ mountainView // { city = "Redwood City" } ]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "Pure Storage"
|
||||
, url = Some "https://www.purestorage.com/"
|
||||
, tagline =
|
||||
"a Mountain View, California-based enterprise data flash storage company founded in 2009. It is traded on the NYSE (PSTG)."
|
||||
, location = mountainView
|
||||
}
|
||||
, title = "Member of Technical Staff"
|
||||
, startDate = "2016-04-04"
|
||||
, endDate = Some "2016-08-03"
|
||||
, daysWorked = Some 121
|
||||
, daysBetween = Some 3
|
||||
, salary =
|
||||
annual 135000
|
||||
// { stock = Some Stock::{
|
||||
, amount = 5000
|
||||
, liquid = True
|
||||
, kind = StockKind.Grant
|
||||
}
|
||||
}
|
||||
, leaveReason = Some "quit"
|
||||
, locations = [ mountainView ]
|
||||
, highlights = [ "Python 2 code maintenance", "Working with Foone" ]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "Backplane.io"
|
||||
, defunct = True
|
||||
, location = sf
|
||||
}
|
||||
, title = "Software Engineer"
|
||||
, startDate = "2016-08-24"
|
||||
, endDate = Some "2016-11-22"
|
||||
, daysWorked = Some 90
|
||||
, daysBetween = Some 21
|
||||
, salary = annual 105000 // { stock = Some Stock::{ amount = 85000 } }
|
||||
, leaveReason = Some "terminated"
|
||||
, locations = [ sf ]
|
||||
, highlights =
|
||||
[ "Performance monitoring of production servers"
|
||||
, "Continuous deployment and development in Go"
|
||||
, "Learning a lot about HTTP/2 and load balancing"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "MBO Partners (Heroku)"
|
||||
, tagline = "a staffing agency used to contract me for Heroku."
|
||||
, location = Location::{
|
||||
, city = "Herndon"
|
||||
, stateOrProvince = "VA"
|
||||
, country = "USA"
|
||||
}
|
||||
}
|
||||
, title = "Consultant"
|
||||
, contract = True
|
||||
, startDate = "2017-02-13"
|
||||
, endDate = Some "2017-11-13"
|
||||
, daysWorked = Some 273
|
||||
, daysBetween = Some 83
|
||||
, salary = hourly 120
|
||||
, leaveReason = Some "hired"
|
||||
, locations = [ mountainView ]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "Heroku"
|
||||
, url = Some "https://heroku.com"
|
||||
, tagline =
|
||||
"a cloud Platform-as-a-Service (PaaS) that created the term 'platform as a service'. Heroku currently supports several programming languages that are commonly used on the web. Heroku, one of the first cloud platforms, has been in development since June 2007, when it supported only the Ruby programming language, but now supports Java, Node.js, Scala, Clojure, Python, PHP, and Go."
|
||||
, location = sf
|
||||
}
|
||||
, title = "Senior Software Engineer"
|
||||
, startDate = "2017-11-13"
|
||||
, endDate = Some "2019-03-08"
|
||||
, daysWorked = Some 480
|
||||
, daysBetween = Some 0
|
||||
, salary = annual 150000
|
||||
, leaveReason = Some "quit"
|
||||
, locations = [ mountainView, bellevue ]
|
||||
, highlights =
|
||||
[ "JVM Application Metrics"
|
||||
, "Go Runtime Metrics Agent"
|
||||
, "Other backend fixes and improvements on Threshold Autoscaling and Threshold Alerting"
|
||||
, "Public-facing blogpost writing"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = Company::{
|
||||
, name = "Lightspeed POS"
|
||||
, url = Some "https://lightspeedhq.com"
|
||||
, tagline =
|
||||
"a provider of retail, ecommerce and point-of-sale solutions for small and medium scale businesses."
|
||||
, location = montreal
|
||||
}
|
||||
, title = "Expert principal en fiabilité du site"
|
||||
, startDate = "2019-05-06"
|
||||
, endDate = Some "2020-11-27"
|
||||
, daysWorked = Some 540
|
||||
, daysBetween = Some 48
|
||||
, salary =
|
||||
annualCAD 115000
|
||||
// { stock = Some Stock::{ amount = 7500, liquid = True } }
|
||||
, leaveReason = Some "quit"
|
||||
, locations = [ montreal ]
|
||||
, highlights =
|
||||
[ "Migration from cloud to cloud"
|
||||
, "Work on the cloud platform initiative"
|
||||
, "Crafting reliable infrastructure for clients of customers"
|
||||
, "Creation of an internally consistent and extensible command line interface for internal tooling"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = tailscale
|
||||
, title = "Software Designer"
|
||||
, startDate = "2020-12-14"
|
||||
, endDate = Some "2022-03-01"
|
||||
, daysWorked = Some 442
|
||||
, daysBetween = Some 0
|
||||
, salary = annualCAD 135000
|
||||
, leaveReason = Some "raise"
|
||||
, locations = [ montreal // { remote = True }, ottawa ]
|
||||
, highlights =
|
||||
[ "Go programming"
|
||||
, "SQL integrations"
|
||||
, "Public-facing content writing"
|
||||
, "Customer support"
|
||||
]
|
||||
}
|
||||
, Job::{
|
||||
, company = tailscale
|
||||
, title = "Archmage of Infrastructure"
|
||||
, startDate = "2022-03-01"
|
||||
, salary = annualCAD 147150
|
||||
, locations = [ ottawa ]
|
||||
, highlights =
|
||||
[ "The first developer relations person at Tailscale"
|
||||
, "Public-facing content writing"
|
||||
, "Public speaking"
|
||||
, "Developing custom integration solutions and supporting them"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,38 +0,0 @@
|
|||
let xesite = ./types/package.dhall
|
||||
|
||||
let Resume = xesite.Resume
|
||||
|
||||
let Link = xesite.Link
|
||||
|
||||
in Resume::{
|
||||
, hnLinks =
|
||||
[ Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=29522941"
|
||||
, title = "'Open Source' is Broken"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=29167560"
|
||||
, title = "The Surreal Horror of PAM"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=27175960"
|
||||
, title = "Systemd: The Good Parts"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=26845355"
|
||||
, title = "I Implemented /dev/printerfact in Rust"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=25978511"
|
||||
, title = "A Model for Identity in Software"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=31390506"
|
||||
, title = "Fly.io: The reclaimer of Heroku's magic"
|
||||
}
|
||||
, Link::{
|
||||
, url = "https://news.ycombinator.com/item?id=31149801"
|
||||
, title = "Crimes with Go Generics"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{ Type =
|
||||
{ name : Text
|
||||
, handle : Text
|
||||
, picUrl : Optional Text
|
||||
, link : Optional Text
|
||||
, twitter : Optional Text
|
||||
, default : Bool
|
||||
, inSystem : Bool
|
||||
}
|
||||
, default =
|
||||
{ name = ""
|
||||
, handle = ""
|
||||
, picUrl = None Text
|
||||
, link = None Text
|
||||
, twitter = None Text
|
||||
, default = False
|
||||
, inSystem = False
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
let Location = ./Location.dhall
|
||||
|
||||
in { Type =
|
||||
{ name : Text
|
||||
, url : Optional Text
|
||||
, tagline : Text
|
||||
, location : Location.Type
|
||||
, defunct : Bool
|
||||
}
|
||||
, default =
|
||||
{ name = ""
|
||||
, url = None Text
|
||||
, tagline = ""
|
||||
, location = Location::{=}
|
||||
, defunct = False
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
let Person = ./Person.dhall
|
||||
|
||||
let Author = ./Author.dhall
|
||||
|
||||
let Job = ./Job.dhall
|
||||
|
||||
let defaultPort = env:PORT ? 3030
|
||||
|
||||
let defaultWebMentionEndpoint =
|
||||
env:WEBMENTION_ENDPOINT
|
||||
? "https://mi.within.website/api/webmention/accept"
|
||||
|
||||
in { Type =
|
||||
{ signalboost : List Person.Type
|
||||
, authors : List Author.Type
|
||||
, port : Natural
|
||||
, clackSet : List Text
|
||||
, resumeFname : Text
|
||||
, webMentionEndpoint : Text
|
||||
, miToken : Text
|
||||
, jobHistory : List Job.Type
|
||||
}
|
||||
, default =
|
||||
{ signalboost = [] : List Person.Type
|
||||
, authors = [] : List Author.Type
|
||||
, port = defaultPort
|
||||
, clackSet = [ "Ashlynn" ]
|
||||
, resumeFname = "./static/resume/resume.md"
|
||||
, webMentionEndpoint = defaultWebMentionEndpoint
|
||||
, miToken = "${env:MI_TOKEN as Text ? ""}"
|
||||
, jobHistory = [] : List Job.Type
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
let Company = ./Company.dhall
|
||||
|
||||
let Salary = ./Salary.dhall
|
||||
|
||||
let Location = ./Location.dhall
|
||||
|
||||
in { Type =
|
||||
{ company : Company.Type
|
||||
, title : Text
|
||||
, contract : Bool
|
||||
, startDate : Text
|
||||
, endDate : Optional Text
|
||||
, daysWorked : Optional Natural
|
||||
, daysBetween : Optional Natural
|
||||
, salary : Salary.Type
|
||||
, leaveReason : Optional Text
|
||||
, locations : List Location.Type
|
||||
, highlights : List Text
|
||||
, hideFromResume : Bool
|
||||
}
|
||||
, default =
|
||||
{ company = Company::{=}
|
||||
, title = "Unknown"
|
||||
, contract = False
|
||||
, startDate = "0000-01-01"
|
||||
, endDate = None Text
|
||||
, daysWorked = None Natural
|
||||
, daysBetween = None Natural
|
||||
, salary = Salary::{=}
|
||||
, leaveReason = None Text
|
||||
, locations = [] : List Location.Type
|
||||
, highlights = [] : List Text
|
||||
, hideFromResume = False
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{ Type = { url : Text, title : Text }, default = { url = "", title = "" } }
|
|
@ -1,3 +0,0 @@
|
|||
{ Type = { city : Text, stateOrProvince : Text, country : Text, remote : Bool }
|
||||
, default = { remote = True, city = "", stateOrProvince = "", country = "CAN" }
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{ Type =
|
||||
{ name : Text
|
||||
, tags : List Text
|
||||
, gitLink : Optional Text
|
||||
, twitter : Optional Text
|
||||
}
|
||||
, default =
|
||||
{ name = "", tags = [] : List Text, gitLink = None Text, twitter = None Text }
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
let Location = ./Location.dhall
|
||||
|
||||
let Link = ./Link.dhall
|
||||
|
||||
in { Type =
|
||||
{ name : Text
|
||||
, tagline : Text
|
||||
, location : Location.Type
|
||||
, hnLinks : List Link.Type
|
||||
}
|
||||
, default =
|
||||
{ name = "Xe Iaso"
|
||||
, tagline = "Archmage of Infrastructure"
|
||||
, location = Location::{
|
||||
, city = "Ottawa"
|
||||
, stateOrProvince = "ON"
|
||||
, country = "CAN"
|
||||
}
|
||||
, hnLinks = [] : List Link.Type
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
let Stock = ./Stock.dhall
|
||||
|
||||
in { Type =
|
||||
{ amount : Natural
|
||||
, currency : Text
|
||||
, per : Text
|
||||
, stock : Optional Stock.Type
|
||||
}
|
||||
, default =
|
||||
{ amount = 0, currency = "USD", per = "year", stock = None Stock.Type }
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
let StockKind = ./StockKind.dhall
|
||||
|
||||
in { Type =
|
||||
{ kind : StockKind
|
||||
, amount : Natural
|
||||
, liquid : Bool
|
||||
, vestingYears : Natural
|
||||
, cliffYears : Natural
|
||||
}
|
||||
, default =
|
||||
{ kind = StockKind.Options
|
||||
, amount = 0
|
||||
, liquid = False
|
||||
, vestingYears = 4
|
||||
, cliffYears = 1
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
< Grant | Options >
|
|
@ -1,12 +0,0 @@
|
|||
{ Author = ./Author.dhall
|
||||
, Company = ./Company.dhall
|
||||
, Config = ./Config.dhall
|
||||
, Job = ./Job.dhall
|
||||
, Link = ./Link.dhall
|
||||
, Location = ./Location.dhall
|
||||
, Person = ./Person.dhall
|
||||
, Resume = ./Resume.dhall
|
||||
, Salary = ./Salary.dhall
|
||||
, Stock = ./Stock.dhall
|
||||
, StockKind = ./StockKind.dhall
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
# JSON Feed Extensions
|
||||
|
||||
Here is the documentation of all of my JSON Feed extensions. I have created
|
||||
these JSON Feed extensions in order to give users more metadata about my
|
||||
articles and talks.
|
||||
|
||||
## `_xesite_frontmatter`
|
||||
|
||||
This extension is added to [JSON Feed
|
||||
Items](https://www.jsonfeed.org/version/1.1/#items-a-name-items-a) and gives
|
||||
readers a copy of the frontmatter data that I annotate my posts with. The
|
||||
contents of this will vary by post, but will have any of the following fields:
|
||||
|
||||
* `about` (required, string) is a link to this documentation. It gives readers
|
||||
of the JSON Feed information about what this extension does. This is for
|
||||
informational purposes only and can safely be ignored by programs.
|
||||
* `series` (optional, string) is the optional blogpost series name that this
|
||||
item belongs to. When I post multiple posts about the same topic, I will
|
||||
usually set the `series` to the same value so that it is more discoverable [on
|
||||
my series index page](https://xeiaso.net/blog/series).
|
||||
* `slides_link` (optional, string) is a link to the PDF containing the slides
|
||||
for a given talk. This is always set on talks, but is technically optional
|
||||
because not everything I do is a talk.
|
||||
* `vod` (optional, string) is an object that describes where you can watch the
|
||||
Video On Demand (vod) for the writing process of a post. This is an object
|
||||
that always contains the fields `twitch` and `youtube`. These will be URLs to
|
||||
the videos so that you can watch them on demand.
|
24
flake.lock
24
flake.lock
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1652776076,
|
||||
"narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=",
|
||||
"lastModified": 1649676176,
|
||||
"narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8",
|
||||
"rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -20,11 +20,11 @@
|
|||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1652722411,
|
||||
"narHash": "sha256-FxzNgYiH9c91hUVAntcjrqY//KOTUPP2a4e8Wyuysxg=",
|
||||
"lastModified": 1650265945,
|
||||
"narHash": "sha256-SO8+1db4jTOjnwP++29vVgImLIfETSXyoz0FuLkiikE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "94beb7a3edfeb3bcda65fa3f2ebc48ec6b40bf72",
|
||||
"rev": "e8f9f8d037774becd82fce2781e1abdb7836d7df",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -35,11 +35,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653117584,
|
||||
"narHash": "sha256-5uUrHeHBIaySBTrRExcCoW8fBBYVSDjDYDU5A6iOl+k=",
|
||||
"lastModified": 1651114127,
|
||||
"narHash": "sha256-/lLC0wkMZkAdA5e1W76SnJzbhfOGDvync3VRHJMtAKk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f4dfed73ee886b115a99e5b85fdfbeb683290d83",
|
||||
"rev": "6766fb6503ae1ebebc2a9704c162b2aef351f921",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -49,11 +49,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1653060744,
|
||||
"narHash": "sha256-kfRusllRumpt33J1hPV+CeCCylCXEU7e0gn2/cIM7cY=",
|
||||
"lastModified": 1651007983,
|
||||
"narHash": "sha256-GNay7yDPtLcRcKCNHldug85AhAvBpTtPEJWSSDYBw8U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dfd82985c273aac6eced03625f454b334daae2e8",
|
||||
"rev": "e10da1c7f542515b609f8dfbcf788f3d85b14936",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue