Genius hack by PhD candidate (with source code): Turn any monitor into a 3D display using a Wiimote - <AUTHOR> http://blogs.zdnet.com/Ou/?p=976

<comment><USER2> Not only is he working on some really cool stuff; I think that one of the most powerful things about Jonny Lee, is that he's such a great communicator. I'm sure the guy has a pretty big brain between his ears if he's getting his PhD in CS at CMU. But, he really does have a gift for being able to break down a subject and be able to communicate it well. He also understands the video medium and uses it to his advantage.

<comment><USER3> Yeah, and did you see him bustin' moves toward the end? Awesome.

How exactly do people interface into hardware like the Wii remote? What he's doing doesn't actually seem computationally difficult--the hard part seems to be...you know, getting the xyz coords from the device.

<comment><USER4> There are drivers for it, but I don't know how good they are.

<http://www.wiili.org/Wiimote_driver>

</comment></comment></comment><comment><USER5> I sincerely feel like standing up and giving a long standing ovation. This is the future of gaming, at lest for 3D shooters, nothing less.

<comment><USER6> I'm really not sure about that, and for the sake of all the other VR and AR researchers who have gone before Johnny Lee - he really didn't invent rendering based on head tracking. The reason I'm not sure about this tech for 3D shooters is that its like looking through a virtual window, you can't fully reorient yourself in 3D - I'm not sure what combining this and full mouse-look control would be like. Also on a PC based setup where you're close to the screen the lack of stereoscopic vision would be more obvious.

I think its more likely the future of different sort of game - maybe those old cabal style scrolling shooters for instance.

Here's a video of some guys doing the same thing with face tracking (ie no LEDs needed) - <http://www.youtube.com/watch?v=iUdZk4KUDTI>

<comment><USER7> My idea... an old west shoot out. You're in the saloon, peering out the window with a rifle. You can duck out of sight behind the television just like you could with a real window. You could also limit your exposure to different baddies by changing you angle of attack.

The directional pad or keyboard could switch between windows, doors, newly created holes, etc.

It's not immediately obvious how this will revolutionize all shooters, but for the shooting gallery type this should be included in all of them starting now.

</comment></comment></comment><comment><USER8> At iRobot I had the luxury of having lots of people trying to sell us 3D headsets and such. It would make a huge difference for controlling a robot remotely.

It's clear that this tech provides much better impression of 3D than any others I've seen.

It would work for a small display as well, letting you look around through a tiny portal.

Also, am I the only one who things "cake" when someone says "portal"?

<comment><USER9> No..... and I'm surely not the only one who thinks "lie" when someone says "cake".

</comment></comment><comment><USER10> from his blog, at <http://procrastineering.blogspot.com/> \--

"Louis Castle announced yesterday at GDC2008 that EA's upcoming title 'Boom Blox' will ship with an easter egg that allows head-tracking using the Wii remote! [...] I'm proud. If this pans out, it'll be only 5 months between the initial research prototype to integration into a major product release. Sweet! Happy to see my stuff being used. [...] Just in case you are wondering: No, I don't get any royalties or benefits for the use of this technique in games. Personally, I'm much happier impacting the state of technology on such a large scale in such a short period of time rather than struggling to transform it into personal financial gain."

sigh. if we were just a LITTLE bit greedier, he could be so, so rich.

</comment><comment><USER11> Not directly related to the article, but let me mention a patch for Quake II my brother wrote a while ago, which creates another kind of 3D illusion using red-blue glasses: <http://www.jfedor.org/red-blue-quake2/>

</comment><comment><USER12> I wish I had a Wii developers kit. It would be so cool to create games using this technique.

</comment><comment><USER13> I used his whiteboard project to turn my laptop into a touch-capable laptop. The only thing is that my IR source doesn't work very well. I replaced a keychain LED with an IR LED but the switch is a simple squeeze and it is incredibly hard to turn it on and get a good signal, so when I'm trying to calibrate it, I usually accidentally click twice and have to redo it. Does anyone have a good idea for an IR pen?

</comment><comment><USER14> Good presentation! Johnny Lee has been evolutionary in wii hacks, a genuine hacker

</comment><comment><USER15> What's awesome about this is how some low-tech (but only now common with the Wii) pieces have been assembled to give a more immersive/convincing 3D viewpoint than ever before.

It's still not stereoscopic vision, but I believe there's an obvious and still fairly cheap extension that could reach that next level: place a pixel-aligned vertical lenticular lens¹ on the monitor.

This can make it so that at predictable distances from the screen, each eye sees just even or odd columns of the display, which would each show just the left-eye or right-eye frames. Without eye-tracking, being just a little off optimal position could ruin the effect.

With cheap eye-tracking, software can see which eye is in which zone, always maintaining the proper left-right mapping. (There might be flickering in transitions; I suspect people would adapt or software could fall back to monoscopic when eyes are misaligned. Thus you always have at least as strong an illusion of 3D as in this demo, but if your eyes fall into the proper lens bands -- boom! -- true stereo vision.)

¹ <http://en.wikipedia.org/wiki/Lenticular_lens>

</comment><comment><USER16> Get the get-well cards ... dude's project is _sick_.

</comment><comment><USER17> This is sort of old but yeah its cool right? There are also people using candles as the IR source. I'm not sure how that works...

</comment><comment><USER18> Is there a research contribution here?

<comment><USER19> As gently as I can manage ...

At the end of the video is a URL for his website. It is <http://johnnylee.net/>

His website is pretty neat. It includes more of his Wii remote projects -- including his interactive whiteboard which I think is even more interesting -- and it includes a link to his academic pursuits.

Following the "Academics" link, you'll find that his thesis project is "Projector-Based Location Discovery and Tracking", which takes his whiteboard hobby a couple of steps further.

<comment><USER8> I just tipped him at <http://tipjoy.com> for this url: <http://www.cs.cmu.edu/~johnny/projects/wii/>

</comment></comment></comment><comment><USER20> this is one of the coolest things I've seen. ever.

</comment><comment><USER21> wow</comment>


Dart Pad: JsFiddle for Dart - <AUTHOR> https://dartpad.dartlang.org/

<comment><AUTHOR> It even supports contextual auto-completion. For example try:

        void main() {
          var list = [1, 2, 3, 4, 5, 6];
          list.
        }

and hit CTRL+SPACE directly after `list.` See: [https://api.dartlang.org/apidocs/channels/stable/dartdoc- vie...](https://api.dartlang.org/apidocs/channels/stable/dartdoc- viewer/dart:core.List)</comment>


An Introduction to Real-Time Subsurface Scattering - <AUTHOR> https://therealmjp.github.io/posts/sss-intro/ <comment><USER2> Here is a WebGL Demo of subsurface scatter I created a couple years ago:

[https://clara.io/view/5c7d28c0-91d7-4432-a131-3e6fd657a042](https://clara.io/view/5c7d28c0-91d7-4432-a131-3e6fd657a042)

It is based on the DICE method described here: [https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approxim...](https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating- translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/)

</comment><comment> irq-1 Curious about the latest (?) tech. nvida's RTX, I found this:

> RTX causes a visible performance hit, which is offset by a technology known > as DLSS, which stands for deep learning supersampling. In order to create > this, Nvidia trains a neural network on pre-release game engine images at > lower and higher resolutions. The AI provides the weights information for > Tensor Cores in consumer GPUs through driver updates.

> When DLSS is turned on, the game is rendered at a lower resolution, with > Tensor cores working to upscale to a higher resolution using Deep Learning. > This results in a higher frame rate with a slightly worse image at high > resolution. This can be used in conjunction with ray tracing to provide > better framerates. NVIDIA claims that users can achieve performance similar > to ray tracing off with a combination of DLSS and ray tracing on.

[https://analyticsindiamag.com/nvidias-real-time-ray- tracing-...](https://analyticsindiamag.com/nvidias-real-time-ray-tracing-ai- powered-rtx-explained/)

<comment><USER3> DLSS makes games look like blurry poop [https://www.game- debate.com/news/26617/nvidia-explains-blurr...](https://www.game- debate.com/news/26617/nvidia-explains-blurry-dlss-image-quality-in-bfv-and- metro-exodus-more-improvements-inbound)

AMD in turn whipped out contrast adaptive sharpening shader that does the same thing without bingo filing buzzwords. [https://www.techspot.com/review/1903-dlss-vs-freestyle-vs- ri...](https://www.techspot.com/review/1903-dlss-vs-freestyle-vs-ris/) This move forced Nvidia to work on their own sharpening filters making fancy DSLL obsolete with dump brute force filter. So much for AI.

</comment></comment><comment><USER4> Great write up!</comment>


Ask HN: What Python web programming frameworks and tools are you using? - <AUTHOR> 	I'm interested in hearing from the community about what tools you are using for building web applications in Python.<p>So, what tools, databases, web servers and frameworks are you using for your latest Python web application projects? Or, if you've abandoned Python, what language have you moved to, and why? <comment><USER2> Bottle[0], Dataset[1], and pipenv[3].

With those three tools I can create a web app with basic functionality with few lines of code, like a prototype. For example:

      from datetime import datetime
      from bottle import get, post, request, run, template, redirect
      import dataset

      db = dataset.connect('sqlite:///database.sqlite')
      entries_table = db['entries']

      @get('/')
      def show_entries():
          entries = entries_table.all()
          entries_sorted = sorted(entries, reverse=True)
          return template('entries', entries=entries_sorted)

      @post('/add')
      def add_entry()
          entry = request.forms.get('entry')
          entries_table.insert(dict(
              text=entry,
              created_by=datatime.utcnow(),
          ))
          return redirect('/')

      run(reloader=True, debug=True)

\- [0] [https://bottlepy.org/docs/dev/](https://bottlepy.org/docs/dev/)

\- [1] [https://dataset.readthedocs.io/en/latest/](https://dataset.readthedocs.io/en/latest/)

\- [3] [https://docs.pipenv.org/](https://docs.pipenv.org/)

Edit: formatting.

<comment><USER3> Where is the code that shows (in the browser) the form for add_entry()? I've used Flask, and for a task like this, you typically have to have either one method which is decorated with a route that takes a list of two method args, "get" and "post" in a list, and then have an if statement to distinguish between code to display the form (get code) and code to process the data on submit (post code), or two separate methods, which could be called get and post or get_entry and post_entry. But your get method does not show a form; it displays all the entries.

<comment><USER2> In that example I put the form on the '/' route. Here is a GitHub repo with the code:

[https://github.com/thinkxl/hn-bottle-example](https://github.com/thinkxl/hn- bottle-example)

And here is a gif showing how it works:

[https://dsh.re/364b2](https://dsh.re/364b2)

Edit: Words.

<comment><USER3> Okay, will check those out, thanks.

</comment></comment></comment></comment><comment><USER4> For websites and internal web applications I use the following.

Framework:

\- A bastardized modification of Django (bad choice, but I'm stuck with it). I'd really like to try Pyramid or Flask.

\- Mako for templating.

Databases:

\- PostgreSQL for primary data storage.

\- Solr for full-text search.

\- Redis for cached data.

Servers:

\- Nginx for the front-end server.

\- uWSGI for the application server (bridge between Nginx and Django). I'd like to try Nginx Unit.

Browser-side:

\- jQuery for functionality.

\- Bootstrap for base styles.

<comment><USER2> Flask is really cool. It has a great community and a package for everything you'd need.

<comment><USER5> I use Flask in most of my projects, the source is very fun to read.

</comment></comment></comment><comment><USER6> Django, DRF(usual suspects), django-silk from profiling API's. Pycharm is my IDE of choice.

</comment><comment><USER7> Flask if building APIs, Django if building CRUD sites.

I write all my database commands in raw SQL rather than using an ORM, primarily because it's far quicker for me to write slightly more complex SQL than manipulate objects.

</comment><comment><USER8> I'm a big fan of Flask. For more performance oriented projects I'm dabbling with Go, going to attempt a non-trivial project with it soon.

</comment><comment><USER9> Django with Django REST Framework. Postgres for DB, Redis for caching. RQ/Django RQ for background tasks. OpenAPI for API documentation.

</comment><comment><USER10> Django all the way.

Use the built-in admin functionality for easy CRUD, and add the django-rest- framework plugin for a full REST api as well.

</comment><comment><USER11> I'm currently working on a web2py app that I'm working to convert to Django.

</comment><comment><USER12> flask via flask_restplus

SQLAlchemy for ORM

PostgreSQL/Redis/Elasticsearch for storage</comment>


Yahoo Knowledge Graph Covid-19 Datasets, API, and Dashboard - <AUTHOR> https://github.com/yahoo/covid-19-data <comment><USER2> Useful information esp. official sources as part of the dataset</comment>


How to quadruple your wealth in a six hour plane flight - <AUTHOR> http://maneeshsethi.com/how-to-quadruple-your-wealth-in-a-six-hour-plane-flight/

<comment><USER2> The title is a misnomer. You don't quadruple your wealth by going somewhere else, you just cut your burn rate by a 3/4. Moving to another country to eat up your savings is a very short term strategy - a lot of fun perhaps, but short term all the same.

A more useful discussion would be how to move to another country and run your web based business, or to become ramen profitable in a country where the ramen is pretty cheap.</comment>


Slack Closing IRC Gateways - <AUTHOR> https://get.slack.help/hc/en-us/articles/201727913-Connect-to-Slack-over-IRC-and-XMPP <comment><USER2> Previous discussion on this topic: [https://news.ycombinator.com/item?id=16539857](https://news.ycombinator.com/item?id=16539857) [https://news.ycombinator.com/item?id=16567009](https://news.ycombinator.com/item?id=16567009)</comment>


Tell HN: Up Down Vote Button on comments - <AUTHOR> Just want to point out that that on mobile the up and down voting button are too close to each other. It's very easy to click on down by mistake instead of up vote button.  Suggestion would be to not make the arrows disappear and bold the button that was clicked. <comment><USER2> Yeah, that can perhaps be a visual improvement.

As it is right now, it is anyways not a problem for folks like me who do not have enough HN karma to downvote any comment. :)

</comment><comment><USER3> When you vote a link appears that says unvote or undown to undo that action.

<comment><AUTHOR> Yes but its hard to know if I upvoted or downvoted.

<comment><USER4> downvotes are undone by an [undown] link instead of an [unvote] link.

<comment><AUTHOR> Ah Don't know how I missed that.</comment></comment></comment></comment>


Don't change the world - <AUTHOR> http://micho.biz/dont-change-the-world/

<comment><USER2> Follow the advice in this post if you're looking for short-term profits and long-term mediocrity.

If you're in business _just for the money_ , then the points in this post are valid. But, then you should probably also be concentrating your efforts somewhere else entirely. Give up software and become a loan shark or a banker or something.

If you're in business because the idea of doing anything else is boring and distasteful, if you admire people who set out to write a page of human history and accomplished it, then there is nothing of value at all in this blog post.

<comment><USER3> I think worldchanging vs. just making money is completely orthogonal to software vs. banking. For instance, microlenders like Kiva probably "change the world" orders of magnitude more than the typical internet startup.

Of all the businesses that add real value to my life, the number of them that "changed the world" can fit on one hand. The others are just honest business, and there's nothing wrong with that.

<comment><USER4> Kiva isn't a good counter-example -- the reason they're "changing the world" isn't because they're doing banking as usual with good foresight into where the current customers want to go next; they've turned normal banking practice on its head (both in the source of the capital, in who borrows it, and how much they borrow), and that's precisely why they're important.

Though personally, I won't even argue that a startup needs to be "world- changing" to change the world. For example, a startup that simply makes it easier to get bottled water delivered directly homes in such a way that soon a huge population is drinking only bottled water...

...and no one (immediately) needs to fund the incredible environmental cost of trucking water everywhere to everyone even though they already have perfectly safe, good-tasting water available from their tap...

...so yes, that changes the world.

This is why I personally found this article depressing (for @#$%s sake, why not sell people water purifiers if they don't like the taste of their tap water??)

Every business changes the world -- mostly in a small way, though that's nothing to be ashamed of. Some in a big way. But _all_ of them in some way.

It's really, really worth putting at least 10 minutes thought into whether your startup, especially if it's gloriously successful, will make the world a generally _better_ place (even if just "people generally doing good things will have an easier time of it"), or will it make the world a generally _worse_ place ("we found a way to stop people from returning merchandise they don't want", or maybe "we make wasting time more addictive").

The OP doesn't even seem to consider putting 10 seconds into this aspect of choosing a business -- into which you'll invest many years of your life. Ugh.

</comment></comment></comment><comment> guard-of-terra Bottled water business is a fraud.

I routinely see a plastic bottle of water costing 1.5x more than a glass bottle of fine lemonade at the same shop.

It goes like this: people drink a lot of bottled water -> big market -> two big bottled water brand nuke the marker with advertising -> shops begin to carry branded bottled water and drop unbranded bottled water, which costs 2x more -> a lot of people buy a half liter of advertising daily.

The problem is: They siphon money from peoples' pockets to the advertisers. They spend those to increase the level of noise.

And I believe the water quality is dismal, i.e. it's the same tap water and much worse than reverse osmosis filtered water from my tap filter.

I think it should actually be regulated and illegal. Then we'll get less noisy adds in our lives and two times cheaper bottled water from a variety of vendors, with its quality up.

</comment><comment><USER5> I have two main problems with this blog post:

1.) The example used - The increasing consumption of bottled water is observable and the options available to those entrepreneurs are reasonable. However the real question is this: who was the first successful entrepreneur to _capitalise_ on the idea of bottling water? That person definitely changed the world.

2.) The repeated confusion between cause and effect - When Apple brought out their affordable personal computer it helped to kickstart the trend of personal computing. If that is not changing the world then what is?

</comment><comment><USER6> The real issue here is that there are (at least) two ways to go about starting a startup. You _can_ go for changing the world, and in that case you must face the fact that you could fail and end up with a niche business. You can also go for maximizing profits. The latter may not result in a world change, or it may. It simply changes your focus. Failure is still out there—both of these approaches can lead a completely nuked business. Hell, both can lead to a niche business if you don't do them right.

</comment><comment><USER7> > Consistently over time, the most successful entrepreneurs I've seen weren't > fighting the world – they were merely building the best sails to move faster > than anybody else.

What causes the winds to change? There must be some new innovation for people to want sails in the first place (to butcher your analogy).

> That's why Groupon clones are making millions a month with unoriginal ideas. > The business model is already well understood and customers are familiar > with it. The Groupon model is a trend that extends well beyond the company.

This is all true but ignores the fact that until Groupon _started_ the social coupon trend, no companies made any money with this business model (because there were none, or none popular enough to matter).

> Those who built great iPhone apps at the time also know about these trends. > Their success had more to do with a "force of nature" (millions of users > thirsty for apps) than with their talent designing apps.

Again, yes, but no one wanted any apps (or even knew what an "app" was) before Apple decided to invent the iPhone.

</comment><comment><USER8> I think the distinction isn't whether one changes the world and the other doesn't, it is whether one changes _people_ and the other doesn't. Jake didn't change his customers. He predicted what they would do next. The demand for his product would exist whether it was him or someone else who was providing it. If no one else imported the new brand of water, the demand for Frank's product wouldn't exist. They'd be fine with their inferior quality bottled water. Frank experienced such resistance because he had to change his customers instead of anticipating what his customers would do anyways.

Saying that the change from tap to bottled water at home doesn't change the world seems kind of silly since it means that municipal water becomes less profitable. All the empty bottles which are thrown out and which go to landfills have an affect on the world outside of people. Whether people by brand A or brand B doesn't have much of an affect on the outside world. If anything, the post should be "Do change the world, don't change people".

</comment><comment><USER9> Nobody likes "Don't change the world", but a lot of people love "Find and solve a customer's existing, urgent problem".

<comment><USER4> The distinction here is pretty dramatic with the example of bottled water.

Assuming that this business scenario is playing out in some country that has high-quality, well-monitored _tap_ water, both of those entrepreneurs are in the business of convincing people to "solve a need" they don't actually have.

In this case, "don't change the world" means "notice that people are easily suckered into buying bottled water, and do that better".

Whereas "find and solve a customer's existing, urgent problem" could possible involve selling efficient and low-cost water purifiers (if people in some areas would prefer better-tasting tap water, I guess? I like mine), or more likely have nothing to do with drinking water whatsoever.

</comment></comment><comment><USER10> Some of the points are valid, but you shouldn't generalize the situation. Very few people in the 90's woke up with the idea that they needed to be connected with someone on the other side of the world. But they eventually realized they did when they were shown the internet.

Yeah sometimes you don't need to be "disruptive", but sometimes you do. And it's especially hard to realize which is appropriate when you are building for a profit, a bit easier when you are building for change.

<comment><USER11> His point is that the ones that made the disruptive change like Netscape are not necessarily the ones that made the most money for the least effort. The people that saw the trend and momentum and went with it had an easier time and made more money more efficiently then the ones that actually changed the world. So even though there are counter examples you can't say they had an easy time of it or took the simplest path to success.

All that said, I don't find the kinds of startups he is encouraging as interesting.

<comment><AUTHOR> Great example at Netscape! That was exactly my point. Major disruptions have already been started by others, and it's easier to ride that wave than starting a new one.

</comment></comment></comment><comment><USER12> All this post says is that it's easy to do something predictable and hard to do something novel.

</comment><comment><USER13> No no no no no! This kind of thinking is for those in it for the money. If you're in anything for the money you won't get very far. It's not that this is wrong advice. Things do work the way he says but no one should be following this advice. Would you encourage your child to grow up to be mediocre or encourage the kid to be the best.

If selling a mediocre product is what you're passionate about then by all means go for it but do not look for the easy buck by doing so because it's just not there. Time and time again we're reminded as consumers that we don't know what we want until someone shows it to us. You can give the people what they want in a way that changes the world.

This whole thing is just wrong. It's hard to argue because it's right in a sense but at the same time no one should be approaching things in such a cynical way. Let's all just forget this was ever written and hope no one listens.

</comment><comment> lenka-penka hmmm...interesting points</comment>


Comma Separated JSON - <AUTHOR> http://www.kirit.com/Comma%20Separated%20JSON <comment><USER2> So literally just JSON without the "[" and "]," delimiting rows, and another "[" at the beginning and "]" at the end of the file?

There are already streaming JSON parsers/serializers, why not just use (or write) one of those instead of inventing yet another file format?

There's also [http://ndjson.org/](http://ndjson.org/) and [http://jsonlines.org/](http://jsonlines.org/)

<comment><USER3> It's not just JSON without [ and ], it's a bunch of JSONs represented as a table. The first line sets the property's key and every other line are the values. It is a representation that needs a parser to be read but that's way faster for a row based database to generate it than to output full json. Plus it's smaller than minified json.

<comment><USER4> The spec doesn't specify what the first line contains.

It only says "Semantically a CSJ file is an array of JSON objects which share a common set of keys." You used your knowledge of how these representations usually work to infer that the first line contains a list of keys for the remaining lines.

Some obvious questions for a table spec include: 1) must those keys be strings? 2) Are duplicate keys allowed? 3) Can different rows have a different number of columns? Or must the writer generate null fields?

FWIW, I've used JSON Lines for my own work. It's very easy to read a line and (in Python), json.loads(line). How should I parse this "JSON without [ and ]"?

There's not a built-in function for it. Either I have to write my own JSON tokenizer, or I have to terminate the string with '[' and ']' and parse _that_. Both are much more complicated than using JSON Lines? You'll notice they only gave output generation timing numbers, not input parsing.

If a JSON-based table format is important, why not layer those same table semantics on top of JSON Lines, rather than make a format which is harder to read?

<comment><USER3> The format for the keys is the same as a javascript object. They are unique strings or numbers. It's already in the Ecmascript standard for objects.

<comment><USER4> Could you help me understand your response?

I find it hard to match your statement to the JSON spec(s). Neither RFC 7159 nor ECMA 404 use the term "key". The standard for objects requires a string for the 'name' of an object member, which is certainly what you refer to. However, JSON does not allow a number.

I tried looking at the ECMAScript spec. In [http://www.ecma- international.org/publications/files/ECMA-ST...](http://www.ecma- international.org/publications/files/ECMA-ST/Ecma-262.pdf) :

> An Object is logically a collection of properties. ... Properties are > identified using key values . A property key value is either an ECMAScript > String value or a Symbol value .

That 'Symbol' has nothing to do with numbers, so only strings make sense for an external representation.

Perhaps you mean to include the integer from the Array object? The spec says "An Array object is an exotic object that gives special treatment to array index property key ... A String property name P is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32-1."

Is that limited range of integers what you mean when you saying that numbers are allowed as keys?

Regarding uniqueness, the CSJ spec says nothing about uniqueness, so how do you know the keys must be unique? It doesn't inherit that from JSON. RFC 7159 says that in an object "The names within an object SHOULD be unique."; uniqueness is not required. It then adds "When the names within an object are not unique, the behavior of software that receives such an object is unpredictable."

Therefore, I don't see how you drew the conclusion you did.

</comment></comment></comment></comment></comment><comment><USER5> I appreciate the problem this is trying to solve, but it could be more easily remedied by a JSON stream processor than reinventing the wheel of data marshalling (yet again). JSON is so simplistic in structure, it's trivial to know when you've met the conditions of a completed segment of structure. There's no reason why a stream parser couldn't handle this well.

<comment><USER6> How about twice the bandwidth, twice the memory, and at least twice the CPU complexity in parson full JSON objects than the proposed CSJ format?

</comment></comment><comment><USER7> This is actually a very elegant way of formalizing CSV. For most apps, if you were to simply output "CSV files" using this encoding, really no one consuming them would know any different -- except you could actually point them at a spec being used.

I've been in arguments with customers before where they complained we were quoting strings, and CSV files shouldn't have quotes, and it would have been nice to say "We're using CSJ, please just parse that way".

I think the name is perhaps misleading though, as it sounds more like it's a variant of JSON than a formalization of CSV. Perhaps "JSON flavored CSV" would be more appropriate?

<comment><USER8> I mean, you could always point them to RFC 4180.

<comment><USER7> Okay talk about ironic. Yesterday in our ops meeting, it came up that some tool another department had built was exporting csv "with extra quotes that were causing problems" (I've had no involvement in any of this). My ears perked up remembering this comment and I was able to point out this RFC, so hopefully it will save them some time in arguing about csv formatting. Thanks!

</comment></comment></comment><comment><USER9> So you save some space on top level keys which are stored once in the header...but you waste space by having to flatten data structures into a table to start with, with key values being repeated over lines, the more deeply nested, the worse it gets.

Stick with JSON document per line.

<comment><USER10> is there necessarily a need to repeat key values over lines?

why not have all possible object definitions in the header and data as a single huge array?

<comment><USER11> You're describing the type-length-value format, used in some places in digital video or in Open Sound Control.

Basically you have a TYPE (fixed width, eg. 16 bits), a LENGTH (again fixed) and a VALUE which is simply a stream of bytes that goes on for LENGTH bytes and is interpreted based on what TYPE it is. You can nest your fields and get very creative in quite a compact way.

One could represent a JSON document with TLV by adding an associative map between the field names and their type numbers, then stream away.

I always loved the simplicity of TLV. Though nowadays, I'm not sure this has much of an advantage over gzipped JSON.

<comment><USER12> Off-topic: Howdy, Mr. Thénot! Crazy reading the comments and seeing your username here. Hope life is goin' well for ya with the HealthNinja stuff -- haven't seen you since I left Wellcentive (around the same time as mbonnette, if that gives you an idea of who I am).

</comment></comment></comment></comment><comment><USER13> ElasticSearch bulk API deals with streaming by using line breaks of JSON docs instead of an array. If you are interested in using this Comma Separated JSON, maybe you want to try this simpler approach before (though the comma separated version seems to be lighter, if I want really to reduce weight I'd consider protobuf, probably).

Reference: [https://www.elastic.co/guide/en/elasticsearch/reference/curr...](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs- bulk.html)

</comment><comment><USER14> Or: just use \n and also be able to read individual rows. Many programs in the wild do this.

<comment><USER15> Newline-delimited JSON? I've used it informally, but I've never had the nerve to suggest it as an actual documented interchange format. It makes a lot of sense for things which CSV is often used for - dumping out big tables of data into files for shipping over FTP or similar - or even for logfiles with structured data entries. The tricky thing is having to restrict the JSON on each line to not contain any newline characters. Even though all legitimate JSON can be minified into a form which has the same semantics but contains no newlines, "JSON with no newlines in it" isn't a well defined standard.

<comment><USER14> "JSON with no commas in it" isn't a thing either. That's not what's being discussed here.

</comment></comment></comment><comment><USER16> I've been using my custom JSV Format for years:

[https://github.com/ServiceStack/ServiceStack.Text/wiki/JSV-F...](https://github.com/ServiceStack/ServiceStack.Text/wiki/JSV- Format)

Which is just JSON with CSV-escaping which is ends up being faster, more concise and more human-friendly since quotes are only necessary when using special delimiter chars. It's just not as interoperable or ubiquitous as JSON so only an option when you control both ends.

</comment><comment><USER17> If you are using a proper CSV library you don't have any of the problems this format is trying to solve. The CSV format does not have any issues mentioned, it is either a buggy CSV library or some lazzy developer who thinks CSV is just fields separated with comma writing 2 line of code instead of using a proper CSV library.

<comment><USER18> Which CSV library is able to infer that a value is a number instead of a string?

<comment><USER17> CSV for sure requires a convention to be shared between the producer and the consumer of the data. Once you have that I don't think you will need to deal with this problem.

To be honest, what I didn't like is the tone of the article. It is just that this statement is wrong: "But the problem is that CSV isn't really a well defined file format with a well defined syntax." There is RFC 4180.

</comment></comment></comment><comment><USER19> I would call this "JSON encoded CSV" since it appears to be a strict subset of CSV, not JSON.

<comment><USER4> A cell can embed JSON objects and arrays, so it isn't a strict subset.

</comment></comment><comment><USER20> I thought MIME types had to go through an application process or start with x-

</comment><comment><USER21> I think I'd rather stick to the format supported by Go and the 'jq' command, where each line is actually JSON.

But if it became popular, this format seems easy to support.

</comment><comment><USER22> JSON enhanced CSV might be a more suitable name. After all it is valid CSV and invalid JSON.

</comment><comment><USER23> Have needed something like this a few times, would be great if it was standardized.

<comment><USER10> inb4: [https://xkcd.com/927/](https://xkcd.com/927/)

the reason json is popular is because it's widely used and is easily parsed (without having to call any extra libraries).

standardizing this would mean accepting upon a complete working alternate that'd work everywhere just akin to json (plus the added perks), which will take a lot of (dis)agreement, especially given that there are already a dozen other standards trying to replace json.

</comment></comment><comment><USER24> no one uses csv by choice, they use it because they have to work with tools (excel) that can only produce/consume csv

given you don't have that constraint there are much better options (json lines, avro, parquet, protobufs...)

<comment><USER25> I use TSV often when I want to easily dump data from a C program to gnuplot or similar. It's more of an ad hoc file format then a serious one though.

</comment></comment><comment><USER15> So this is something that looks quite a lot like CSV, in some cases produces identical output to CSV, but which isn't compatible with CSV.

<comment><USER4> To be fair, most CSV isn't compatible with CSV.

Especially with the CSV in RFC 4180, which among other things requires a CRLF.

</comment></comment><comment><USER26> doesn't look very JSONy without any curly braces.</comment>


Fermat Numbers (2013) - <AUTHOR> http://www.jefftk.com/p/fermat-numbers

<comment><USER2> [https://news.ycombinator.com/user?id=anacleto](https://news.ycombinator.com/user?id=anacleto)

Are your doing some experiments or something? a new account with 48 submissions in the past 5 days is odd.

<comment><AUTHOR> No, definitely not. I submit only what I consider really interesting. I've known HN for a long time and I only regret not having used it previously.</comment></comment>


My first app: Emailr, a simple way to send automated emails to friends - <AUTHOR> https://github.com/jeffninghan/emailr

<comment><USER2> Friends don't send friends automated emails.

Unless you're trolling, in which case automate away.

<comment><AUTHOR> haha yeah the trolling of friends was the main use case I had in mind.</comment></comment>


Immutable Infrastructure: No SSH - <AUTHOR> https://boxfuse.com/blog/no-ssh.html <comment><USER3> It's quite silly. I mean they mix up two completely separate issues. Deployment problem and people problem. Image deployments are not new - computing clusters have done it for ages. Immutable deployments aren't new either - actual immutable filesystems booted over network were there for many many years.

Yes, that's going to prevent drift at first. No, it's not going to prevent people from doing silly stuff. At least ssh allows them to do silly stuff in a "normal" and visible way and doesn't stop you from debugging issues when you actually need it. If you enforce no-login without teaching people, they'll just reinvent it... badly - for example by making executable configurations, or pseudo-web-shells.

And there's one big issue with images which will cause a lot of friction in real teams - they're slow to build. And even slower to test. If you're doing it properly it means first testing locally on some approximate environment, then handing the package over to a system which will test the whole deployment, which takes ages to boot up all components. (time scales with system complexity - it's not ages for a single webserver of course) Anyone developing something related to integrating services will get additional frustration unfortunately.

> Enforcing immutability [...] You need to prevent log in.

No... If you need immutability, you make your system actually immutable and then audit logins when logins are needed. Preventing logins is just punishing people and slowing them down when they need it the most, because you don't trust them.

> Vulnerabilities like ShellShock simply vanish

Said a person who does not understand why ShellShock was an issue and why it doesn't matter if a user who already has local access uses shellshock.

<comment><USER4> > Vulnerabilities like ShellShock simply vanish

I'm actually surprised at the naivety of whoever wrote this. I'm not an op at all and I understood enough about ShellShock to know that this isn't correct at all.

</comment></comment><comment><USER5> Removing ssh ties the hands of your operations team when an outage hits because you have removed their debugging console.

With this change, the team loses access to all the standard OS tools which are useful in the event of a service outage for debugging. What usually ends up happening then is that the standard tools are replaced with substandard and patchy implementations.

If your infrastructure is drifting then a better solution is to restart it more regularly. If you find staff are still making untracked changes then that's not a technology problem - it's a people problem.

<comment><USER6> A better alternative is to kill entire servers every once in a while and reprovision them. That way, console access effectively becomes read-only, since any changes will soon be lost, but you can still debug stuff.

<comment><USER7> +1 netflix made Chaos Monkey specifically for that (not that anyone on HN couldn't code an equivalent, just that it's a technique used at scale).

</comment></comment></comment><comment><USER8> _" Sign up for your Boxfuse account."_

What? And disturb the tranquil immutability of boxfuse.com?

<comment><USER9> It actually gets swapped with a new Boxfuse.com on write.

</comment></comment><comment><USER10> We do something similar with Nix ([https://www.nixos.org](https://www.nixos.org)). We have a CI server (Hydra) which creates a closure containing our software and all its dependencies, which we then upload to a network of AWS machines that are created with a few python scripts.

This works fairly well, but from experience we do need to keep an SSH setup on the machines. Just last week we had a load spike on a production server which was caused by a software bug, triggered by a usage pattern that was unexpected and not covered in our tests. If we did not have SSH (and access to the CLI tools on that machine) we would not have been able to debug this unexpected problem. I guess what I'm saying is that as long as software has bugs and hardware has glitches, we'll sometimes need access to low-level tools which can help us figure out the cause of these unexpected scenarios.

<comment><USER11> Exactly what I was thinking as I read this. Just use nix. Forget the dogma.

</comment></comment><comment><USER12> Somewhere in the infrastructure there has to be mutable servers - <USER2> and log servers at the least. I can't think of many architectures where everything can be a closed appliance.

Are they suggesting that every time you need to apply a security patch, you'll have to build a new server and cut your traffic over to it? That sounds like a lot of DNS and Load Balancer config updates (mutable!) even if the newly patched server builds are 99% automated.

The idea of black-box appliances has been around a long time, and it has its place in the modern infrastructure, but I'm not sure it really solves the problems they are trying to solve (which sound more like change management issues).

<comment><AUTHOR> This type of image is primarily designed for 12-factor apps where all persistent state is kept outside the instance in some geo-redundant highly available system like Amazon RDS or S3.

<comment><USER13> The problem with Amazon RDS, and they freely admit it, is that it's not built for the scale at which some companies operate. If you need advanced features of your DB, or need to operate at large scales (the magnitude of scale differs by RDS engine), you'll end up wanting to run your own DB on an EC2 instance.

<comment><USER14> When you have enough business that RDS is too small, you are not going to be heartbroken about paying for a bespoke setup.

Until then, ignorance is bliss.

<comment><USER13> Well, ignorance also tends to fuel any number of flamewars...

In my experience with RDS as a MySQL admin, Amazon was not using sane defaults for quite some time, which resulted in a remarkably non-performant product. Thankfully, they listened to feedback, so over the course of a few years the MySQL RDS instances started to become much more dependable and useful. I'd be happy to use one today, which is something I couldn't have said too long ago.

And even with RDS, having a DBA available (even just as a consultant) is still quite useful - it's unrealistic to expect your developers to write ideal SQL. You can get a long ways with RDS if your queries and schemas are well tuned.

</comment></comment></comment></comment></comment><comment><USER15> So I've considered this before, and I know it is coming from a good place. It seems great for the good times. At Clarify.io we use immutable infrastructure and we don't log in to boxes. Except when there are problems. And there are problems. Always.

You don't want to have to fight your way in in the middle of a disaster.

At Clarify.io we've considered having an on-login event fire when an admin uses SSH to log in to the box. This would schedule the server for termination within 24 hours. This gets you best of all worlds:

\- Gives tools to debug and restore service when there is a failure

\- Forces admins to not depend on SSH to bring a system up

\- Replaces servers when they are potentially drifting

\- Encourages a "cattle" mentality about the servers

<comment><USER16> I really like this idea. Would be keen to see what your orchestration code looks like to handle that.

<comment><USER15> We already use JanitorMonkey. It would likely involve tagging the instance in AWS with a tainted tag, and adding code to JanitorMonkey to do the normal mark-and-sweep.

<comment><USER16> That's awesome! I don't know how I've missed JanitorMonkey amongst their tools, but that looks great. Definitely giving it a whirl.

</comment></comment></comment></comment><comment><USER17> "Vulnerabilities like ShellShock simply vanish" \- eh .... not really.

Shellshock was not just from SSH, it was any program that used environment variables to pass data around.

Immutable infrastructure is a great ideal, but has various downsides. sometimes people need to access the raw system to do debugging. While shoot the node, and boot a new one has advantages, it does just move the problem down the line.

The BBC solution is a nice balance.

</comment><comment><USER18> This is just dumb as nails.

Now I can't login to the production server in order to strace the process to figure out why production is misbehaving.

And don't say you should always replicate the issue in preprod, sometimes you simply can't. Some issues only emerge at prod scale+load+latency that you don't have the financial resources or technical ability to be able to exactly replicate in a testbed.

You are drunk on too much koolaid, go home.

<comment><USER19> That's great if strace et. al. can actually tell you why production is misbehaving. Of course, strace doesn't exist in vacuum, it changes the way your code executes. Everything is going to be slower, and race conditions and locks may not present themselves so readily. Then you also have the added stress of screwing around with a live server, what if you do something that messes it up worse?

Sometimes it makes more sense just to kill that server and add a fresh one to the pool. Better yet if that process is automated. Good logging can actually be more valuable than mucking about in the live environment (or as I call it, panic mode).

</comment></comment><comment><USER20> Uhh... you now how we handle drift? We manage the update repository ourselves. New packages don't get released until we are ready to release them....

You don't need to limit ssh to help handle state drift. Article writer doesn't seem to understand the difference between user access, and software deployment.

</comment><comment><USER21> This is what happens when dev teams hate ops teams. Troubleshooting a production bug without a terminal is a recipe for lengthy outages.

<comment><USER14> I worked on Cloud Foundry buildpacks for 7 months. I was working at the Pivotal Labs offices in NYC and I can tell you this for free: devs want SSH access too.

When a box dies in staging, it's nice to learn why.

</comment></comment><comment><USER22> > Trouble starts the minute you start relying on commands like this:

        sudo apt-get install mypkg

So what's wrong with `sudo apt-get install mypkg=<version>`?

<comment><USER23> Do you do this every time? Must be cumbersome, there's no equivalent of Gemfile.lock and bundler for apt-get, is there?

(Or is there? Serious question)

<comment><USER24> [https://help.ubuntu.com/community/PinningHowto](https://help.ubuntu.com/community/PinningHowto)

My guess is that apt pinning/holding predates Gemfile.lock by quite a few years :)

<comment><USER23> This and Ansible are non-answers to me.

The functionality of bundle install and bundle update are not replicated by apt pinning or holding. How do you roll back a bad update to your pinned packages? Put back the old Gemfile.lock and bundle (again)? Does that really work?

I guess I don't really use Ansible so I don't know, but it's very easy to roll back a bundle update if you keep your Gemfile.lock in revision control too. I've used apt pinning before though, and I'm quite sure rollback of a package update that has a dependency conflict with the old version is not as easy.

<comment><USER25> _I 've used apt pinning before though, and I'm quite sure rollback of a package update that has a dependency conflict with the old version is not as easy._

Aptitude has always handled that just fine for me, downgrading the dependencies as well if needed.

<comment><USER23> You're still losing the information about what you had pinned before by unpinning, unless you can dig it out of dpkg.log after the fact. This is almost nothing like having Gemfile.lock and committing it to the project code repo, saving each changeset after every "bundle update".

It is an issue with the package manager, like the python/virtualenv guy suggested, apt can't support keeping parallel versions installed at the same time and linking in the locked version into each separate project that needs a specific version. The conflicting versions do conflict. This is not a problem for bundler, since a given project is not likely to need two separate conflicting versions in a single bundler exec.

There is no "project" concept at all in dpkg. You just have to maintain wholly separate environments for those conflicting dependencies, on separate machines, if they show up in cases where you really need both versions.

Or work with containers instead, which is arguably not really a different solution than already proposed.

<comment><USER25> _You 're still losing the information about what you had pinned before by unpinning, unless you can dig it out of dpkg.log after the fact._

Oh, that's why I mentioned Ansible in my previous comment. I have a version controlled file with:

      - apt: pkg=lib1 version=11.6
      - apt: pkg=app version=33
      ...

To rollback, I can just revert to the right commit and re-run ansible- playbook.

As for multiple parallel versions installed, sure you can. All you need to do is packaging them using different prefixes. What you can't do is blindly use packages from the main repos; those are built to be used to support the OS programs, not yours. But even those are often made to have multiple parallel version: I have python 2.7 and python 3 installed, both from Debian's main repo.

</comment></comment></comment></comment></comment></comment></comment><comment><USER26> Interesting; so, boxfuse is one of these (..."micro" kernels? What's the name, of when you run in a hypervisor without a real OS, so no user isolation, no process isolation, etc.) OS/image-creation tools...

I didn't realize they were production ready yet, but sounds pretty spiffy.

What's interesting is that I think Boxfuse is spinning what most people would call a weakness ("if stuff breaks, I can't SSH into the shell and fix it (because, not only is that a 'bad idea', there just isn't a Linux OS there to SSH into anyway)" and calling it a strength.

Nice spin. :-)

If I tried boxfuse, I'd probably look at embedding the Apache Java-based SSHD server, not for app setup, but debugging ... assuming its terminal session would provide useful information in the Boxfuse "there is no OS" environment.

(The boxfuse site uses the term "Secure Micro OS, Few MBs", so if I'm misinterpreting what their platform does, someone please correct me.)

</comment><comment><USER27> On *BSD kernels you can use securelevel to achieve proper immutability to some extent (like unchangeable pf rules, read-only raw disk devices, etc...). Disabling ssh only gives you the guarantee that ssh is going to be disabled, and that is quite different from immutability.

</comment><comment><USER28> > Vulnerabilities like ShellShock simply vanish.

What? No, they don't! ShellShock was about executing unintended code in a bash process where you control an environment variable but not stdin. If you control stdin, there's no need to sneak a command into an environment variable: you can just type it into the shell.

Apart from this, the article makes no argument for removing SSH: it only argues for restricting access to privileged userids. That is to say, the standard best practice for decades. Root should be reserved for special situations, not used by default.

</comment><comment><USER29> This is so the wrong question. Immutable infrastructure does not require nor warrant restricting the form of access you have to your services.

Having everything build-oriented (basically building the builder on every deployment, than using it to build the service) is what prevents drift.

Running on a read-only file system is what guarantees immutability and prevents drift.

Not allowing SSH is plugging a single hole which guarantees nothing. Can the app-server write on its own disk? Can it modify configuration files? Maybe even code?

As a developer I want to be able to write applications that are not specific to any one deployment method. I want to be able to change my mind to host this on different kind of infrastructure. These kind of limits force you to create a strong adherence between your application and its tooling and the deployment method.

Of course, the Read/Write domain has to be explicit and limited, but this is good practice anyway. Running on a distributed storage grid based on something like CEPH can allow you to address this domain not only explicitly but also in a fault-tolerant and scalable way.

When you cut off SSH you are cutting off half of the tooling we have and you make everything overly complicated. I want to be able to tail any log on any host. I want to be able to scp for inspection any file to my dev machine.

At platform.sh (a PaaS running on a distributed grid of micro-containers) we run a build oriented immutable infrastructure so there is no, there can be no infrastructure drift.

We proxy SSH so security stays the responsibility of the orchestration layer not any single host or service. This means we can filter by role any connection to any service, but developers can still just use the tools that work.

</comment><comment><USER30> This is not even a problem if you're using Ansible (and possibly others): you just say you want the latest version of the package installed, and ansible will to an `apt-get update` for you as a preliminary step, and install/update the package if needed.

So basically, all the machines you're running ansible on will have the latest version (if that's what you want, of course)

</comment><comment><USER31> What is drift? Local edits, updates not applied, literally ntpd/ntpdate not updating the time. Your host is misconfigured; it's broken.

How do you deal with systems breaking? By monitoring for them. It also helps to make them 'disposable', but this is not a replacement for monitoring. Good monitoring will tell you when time is off, when disks are about to fill up, when permissions are bad and when packages aren't up to date.

Removing ssh does not give you monitoring. It does not prevent system state from changing. It really doesn't do anything but remove a very secure and simple method of communication and file transfer.

Minimal/disposable images? That's fine. It won't make your servers or services immutable. One day your hardware's going to catch on fire and your first clue won't be the smoke billowing into the neighboring rack, it will be the errors in your logs.

</comment><comment><USER32> I find the better pattern here is to limit and discourage SSH and then monitor and log the hell out of it. There are numerous tools out there that can centralize any actions being taken on a host and sending it to a log that can be centralized. Outright removing all SSH puts you in a rough spot if things go south with some piece of software that your system monitoring/centralized logging don't cover 100%, and makes it way hard to do things like strace on a process.

<comment><USER15> Or if one of the problems of the server caused logging to not correctly start :)

<comment><USER16> Which is certainly a valid case, but I would argue that if that IS the case, and it cannot autorecover, then that is a good candidate for the instance to self terminate.

</comment></comment></comment><comment><USER33> A common response on this thread has been that if you take away SSH, you can't log into individual machines to debug. But you know the other situation where you can't do that? When your software is running on your users' machines rather than yours, i.e. mobile and desktop apps. I agree with the position of the OP, that it's better to make the software robust by design and through testing.

<comment><USER25> _it 's better to make the software robust by design and through testing._

But that's a false dichotomy; having SSH in no way prevents you from designing and testing your software just as well.

<comment><USER19> I don't know, I think there's a legitimate argument to be made that some tools can become a crutch and a detriment. At one of my consults all the developers lean heavily on IDE debugging at the expense of developing well-defined contracts and interfaces. Nobody blinks twice at having a ton of threads mutating global variables because they have all these great debugging and tracing tools.

</comment></comment></comment><comment><USER34> I ssh into machines for many reasons other than to change them. In fact most changes are done remotely with Ansible.

</comment><comment><USER35> I'm a fan of immutable infrastructure but there is still a need to get access to a container now and again to troubleshoot things. We don't run SSH inside the containers but it's easy enough to write some tooling to find a host running an instance and use docker exec to get a shell on it.

</comment><comment><USER36> What about logs? What about looking into the server to find out what is going on on the server?

<comment><AUTHOR> Application logs should be shipped over the network to either your own ELK infrastructure or some hosted solution like Loggly, Logentries or Papertrail. Boot logs can be obtained from your infrastructure (like EC2 instance logs).

<comment><USER37> And when that stops working for some reason? of course the real solution to have out of band managemnet

<comment><USER38> the network is 100% reliable, always. The internet, doubly so (it's so big, you know). Maybe you missed the memo.

<comment><USER37> Well as a "circuit switched bigot" Vint must have left me off the mailing list :-)

I used to to do OSI international interconnect support an testing for my sins many moons ago.

</comment></comment></comment></comment></comment><comment><USER39> May I suggest another "innovation" \- statically link everything into a single blob and run it under systemd.

The building scripts should be written in JavaScript, of course. Package it as a startup. Become millionaire.

</comment><comment><USER40> Docker?

<comment><USER41> Still requires an underlying OS which may need to be patched or upgraded.</comment></comment>


Show HN: Did not find automated personalization for websites and created this - <AUTHOR> https://www.landy.io/ <comment><USER2> As a CRO consultant this is interesting, but I'm skeptical. (It's not particularly your fault. Nearly every marketing tool promises nirvana, but very few of them deliver.)

It sounded great until I realized that:

1) I would still have to think of variations and create them myself.

2) Even after that, this would only be useful if things like location and time of day really did have a significant effect on conversion rates.

3) And even after that, this would only be _worth it_ if those effects were not obvious to me and could only be discovered with ML. For instance, it doesn't take ML to hypothesis that a visitor who came from an ad link (&utm_campaign=dogs) is more interested in seeing a page about Dogs. And that hypothesis can be tested for free with Optimizely.

In other words, ML is cool and all but I don't see what value this adds to conversion optimization.

Maybe my assumptions are wrong and I'm missing something, in which case I hope this is useful feedback.

<comment><USER3> 1) Yes, the problem with creating variations is still here and is worth mentioning. Today you need to know your product well and know your visitors well to create a valuable hypothesis. And this is what we're working on right now (disclaimer - I'm one of the co-founders of Landy).

2) The idea here is that with ML you should not analyze every dimension separately. ML is taking into the account all available characteristics and making decisions based on all of them together (like if the guy on OS X, who came from NY from the Facebook campaign in the evening - prefer to watch product video instead of watching screenshots - no problem, we'll show him video).

3) The real power of ML comes out when you could not obviously split your traffic based on the ad link (like utm_campaign=dogs). Direct and search traffic on your homepage are great examples in this case. Also, manual targeting requires a bunch of analytic folks, who will continuously analyze your traffic, setup and adjust optimization campaigns. Even in this case - it's still difficult to adapt to dynamic changes in traffic (like a new type of visitors, season changes, etc). So ML could not only improve results but also decrease the amount of human resources which is currently required for solving such complex problems.

So what I'm trying to say is that your assumptions definitely make sense in some cases. But we believe that there are still plenty of cases when ML could drastically increase your results and save your time.

</comment></comment><comment><USER4> I had a similar idea but couldn't convince people on my team to try it out. Glad to see someone is trying this. Adding a SaaS model is a good idea.

Have you tried switching out parts of a page? I tried switching react components in an admin interface. It took into account the user id, so in some cases, the user would get a 'customized' UI.

I had trouble tuning the data to make the output actually useful, so the project has been shelved for now. Hope this works out for you guys.

</comment><comment><USER5> I was disappointed that the landing page wasn't personalized as a demonstration

<comment><USER3> Actually, it is. We're currently running simple personalization campaign with two versions of landing pages which has different design, messaging, etc.

</comment></comment><comment><USER6> This makes sense. Ads have been personalized for a long time so why not pages? Some work is needed to create these but for people trying to squeeze every conversion they can out of visitors is may be worth the trouble. It also might help prevent fast bounces.</comment>


Should I require  username at login? - <AUTHOR>

I'm putting together my first website, and I'm wondering if I should bother asking for a username at login. If the password is long enough, won't that be just as difficult to geuss randomly as a shorter username and password?<p>Assuming the answer to that is yes, it a good idea to force users to choose a password, or would that be inconvenient? <comment><USER2> The number of people who pick '12345' or 'password' is astronomical. And forcing them to remember a "strict" password is more detrimental to the user experience than just having a user/password combination.

Besides, what are you going to do if you get dupes? "Sorry, that password is already in use"?

<comment><AUTHOR> I see now that it is a terrible idea. Thank you.

</comment></comment><comment><USER3> If you need to allow identification of users, you'll probably want some sort of username. And adding a username later will be harder than putting one in now. Also, any deviation from what the users expect/are accustomed to (i.e. username/password) will lead to user confusion. I would just go with the standard username/password login.

Personally I don't mind if you generate a random password for me, but either way works.

<comment><AUTHOR> There would be a username, it just wouldn't be a part of the login process. I'm inclined to go with a better system instead of what people are expecting, but that's probably bad policy if I want users :) . A randomly generated password might solve the duplicates problem, but I guess I'll just stick to the standard format. Thanks for the feedback.</comment></comment>


Retguard: An improved stack protector for OpenBSD - <AUTHOR> https://marc.info/?l=openbsd-cvs&m=152824407931917&w=2 <comment><USER2> Cool. If I understand the LLVM code correctly, it's inserting the following instruction sequence into the code:

        mov r11, [cookie]
        xor r11, [rsp]
        ...
        xor r11, [rsp]
        cmp r11, [cookie]
        jeq 2
        int 3
        int 3
        ret

(where r11 might be some other suitable temp register as needed). cookie points to an 8-byte chunk of .openbsd.randomdata, a section that is initialized at binary load time by the kernel to contain random data. The canary is one of 4000 possible values, named "__retguard_0" through "__retguard_3999", presumably to avoid having the kernel generate an unbounded amount of random data - the section is limited to 1MB in size.

This makes ret instructions fairly hard to use for rop purposes. Unlike the original design, which xor'd [rsp] directly, this new approach preserves return prediction so it should have a lesser effect on performance. With the changes to reduce polymorphic gadgets in place, this should make ROP attacks significantly less palatable. Also, in the original design, an arbitrary leak made rop attacks feasible as you could just place xor-encrypted return addresses on the stack. With the new design, you need repeatable register control too, assuming the temp register isn't spilled, which raises the bar quite a bit.

<comment><USER3> What is preventing an attacker from overwriting the last xor and cmp instruction sequence with nop instructions?

<comment><USER4> W^X (W xor X) which means memory is either writeable or executable. Guess what, OpenBSD maps code only executable and not writeable.

</comment></comment></comment><comment><AUTHOR> It's also worth mentioning there's previous work to reduce the amount of polymorphic gadgets in the instruction stream, including a new framework for clang:

[https://marc.info/?l=openbsd- cvs&m=151123332419798&w=2](https://marc.info/?l=openbsd- cvs&m=151123332419798&w=2)

[https://marc.info/?l=openbsd- cvs&m=152495643720502&w=2](https://marc.info/?l=openbsd- cvs&m=152495643720502&w=2)

</comment><comment><USER5> The post from ~9 months ago by deraadt is worth reading: [https://marc.info/?l=openbsd- tech&m=150317547021396&w=2](https://marc.info/?l=openbsd- tech&m=150317547021396&w=2)

<comment><AUTHOR> That is the previous design which changed significantly from what's been committed today (see other comments).

Github mirror, for easier review: [https://github.com/openbsd/src/commit/e688c2b0648a80551cf735...](https://github.com/openbsd/src/commit/e688c2b0648a80551cf7353d9f455c7cbb98f13c)

</comment></comment><comment><USER6> The underlying assumption is that the XORd value cannot be crafted by the attacker. If read-access of [rsp] is possible, this scheme is vulnerable to information leak of the return address (or another program pointer which lets the attacker derive the return address), because cookie = retaddr^[rsp]. But still this is better than the original RETGUARD which was easier to attack in both ways, either a leak of the stack position to get the return address or vice versa.

</comment><comment><USER7> What's meant by the term "gadget"? Does it mean an exploit mechanism? My searches are mostly showing information about USB device drivers.

<comment><USER8> It's a reference to this class of vulnerabilities: [https://en.wikipedia.org/wiki/Return- oriented_programming](https://en.wikipedia.org/wiki/Return- oriented_programming)

<comment><USER7> Cool. Thanks!

</comment></comment></comment><comment><USER9> Question; does this protection get applied to all languages that use llvm on openbsd or is it C/C++ specific?

</comment><comment><USER10> How is this different than any other stack canary? Is it because it is per- function instead of per-stack like Linux?

<comment><USER11> First off, the normal glibc/GCC stack canary is per-process, not per-stack.

(I started writing a more detailed reply based on the commit description, but there was too much speculation without seeing their source code).

<comment><AUTHOR> OpenBSD's is per shared library, i.e: libc has a different stack cookie than your application and/or other libraries.

RETGUARD however, is per function.

</comment></comment></comment><comment><USER12> I don't pay enough attention to know how this is different from what PaX team did with RAP 3 years ago:

[https://pax.grsecurity.net/docs/PaXTeam-H2HC15-RAP-RIP- ROP.p...](https://pax.grsecurity.net/docs/PaXTeam-H2HC15-RAP-RIP-ROP.pdf)

<comment><USER13> this is basically the xor canary approach originally pioneered by the Stackguard guys (i'm pretty sure you were already around at the time though probably forgot such old history as did the rest of the world apparently ;). the OpenBSD implementation suffers from a few problems, mostly their own making:

1\. if they can't find a register to load the cookie into, they'll silently skip instrumentation (i'm not sure how that would happen in practice but the silent treatment when omitting a security feature is a non-starter).

2\. if they can find such a register then it'll be spilled to the stack and restored in the epilogue, so a normal buffer overflow can control both the xor'd retaddr and the retaddr itself and the only thing standing in the way of exploitation is the secret cookie value - not unlike with Stackguard/SSP.

3\. one would think that a per-function cookie is an improvement but... they're shared among threads (in userland) or everything (in the kernel) so infoleaks are just as catastrophic as before (it'd certainly help if someone described a proper threat model for this defense). at least the kernel side should use a per-syscall cookie to make it somewhat resemble an actual defense mechanism (and there's some more described in my presentation).

4\. the int3 stuffing before retn must be someone's joke 'cos it sure as hell won't prevent abusing the retn as a gadget. it does introduce a mispredicted branch for every single function return however.

<comment><USER14> Hey PaXTeam, thanks for having a look! I wrote the implementation, so I can answer some of these.

1\. We don't silently skip instrumentation. If we can't find a free register then we will force the frame setup code to the front of the function so we can get one. See the diff in PEI::calculateSaveRestoreBlocks().

2\. We do spill the calculated value to the stack. This is unavoidable in many cases (non-leaf functions). It would be an optimization to not do this in leaf functions, but this would also mean finding a register that is unused throughout the function. This turns out to be a small number of functions, so we didn't pursue it for the initial implementation.

3\. I'm not sure what you mean by the cookies are shared. Do you just mean that they are all in the openbsd.randomdata section? They have to live somewhere. Being able to read arbitrary memory in the openbsd.randomdata section would leak them, yes, though this doesn't seem to have been a problem for the existing stack canary, which lives in the same section. I see that RAP keeps the cookie on a register, which sounds like a neat idea. I'd be curious to see how you manage to rotate the cookie arbitrarily.

4\. I'm glad you like the int3 stuffing. :-) We could always make the int3 sled longer if it turns out these rets are still accessible in gadgets that terminate on the return instruction. Have you found any?

Anyway, I'm happy to see your commentary on this. You guys do some nice work! If you have other suggestions for improvement I'd be happy to hear them. You can email me at mortimer@.

<comment><USER13> 1\. both insertReturnProtectorPrologue and insertReturnProtectorEpilogue check hasReturnProtectorTempRegister before proceeding with the instrumentation. so either the changes to calculateSaveRestoreBlocks are not enough to prevent that condition from ever triggering or these checks should be asserts at most or just be eliminated altogether.

2\. sure but then this means that RETGUARD is not an improvement over Stackguard/SSP which is not how it's marketed...

3\. shared means that entities of a class (threads in a process in userland, every single process/thread in the kernel) see the exact same cookies so leaking a cookie from one entity can allow exploitation by another. this is especially detrimental to the kernel side protection. frequent enough cookie rerandomization can help narrow this channel (RAP has a per-thread cookie in the kernel that is updated on each syscall, and there's some more to reduce infoleaks across kernel stacks, it's all in the presentation).

4\. any normal path leading up to the ret is a gadget and int3 stuffing does nothing to prevent that (the underlying logic here is that if one can retarget a return to arbitary addresses then he has already leaked enough information so bypassing the cookie check is a no-brainer too). not only that but in the bsd.mp kernel i just checked, of the 32199 ret (0xc3) bytes only 20236 are actual retn insns, the rest are inside insns. so this int3 stuffing leaves many other instances available. Red Hat tried similar gadget elimination a while ago but noone's using the gcc feature as far as i can tell.

</comment></comment></comment></comment><comment><USER15> Anyone seen this new ReturnProtectorPass also upstream at clang? It was written end of 2017 AFAIR, that when when we last discussed this here.

CFI still looks more promising to me though. Protecting the CALL part. But this is better than the old gcc/clang stack cookie of course, protecting RET.

</comment><comment><USER16> When I first read this, I thought how come no one thought of this before? It feels like common sense.

Dumb question (potentially): will this make code that is not inlined, calling a function many times, often, run a lot slower?

<comment><USER14> It depends on the function. Many things will contribute. If your CPU can keep the cookie in cache then loading it repeatedly will relatively fast compared to hitting main memory. If your branch predictor can figure out the jmp over the int3 instructions quickly then that will also be fast. If the function is very short then the retguard stuff will add relatively more instructions to the function so will have a larger impact than if the function was long, etc.

I found that the runtime overhead was about 2% on average, but there are many factors that contribute.

</comment></comment><comment><USER17> While I didn't understand most of this, any reason why they're still using CVS? Genuinely curious, I'm sure they have good reasons.

<comment><AUTHOR> You must be jealous that we're self-hosted. ;-)

<comment><USER18> I made a program called Meta-CVS in 2002 that stores a versioned directory structure with permissions and symbolic links along with the files in an ordinary CVS repository.

[http://www.kylheku.com/~kaz/mcvs.html](http://www.kylheku.com/~kaz/mcvs.html)

Meta-CVS has an import feature (mcvs grab) which detects renamed files. It fixes up symlinks pointing to moved files too and such.

Meta-CVS didn't catch on widely because by the time I had it stable, CVS itself was being side tracked by newly emerging projects like SVN.

Plus people were afraid of it being written in Common Lisp.

If you're still using CVS in 2018 and not Meta-CVS, you're ridiculously backwards though. :)

<comment><USER19> The need to secure repos was identified by Karger in MULTICS evaluation. It was a requirement in TCSEC security certification. A great summary of issues is below by David A. Wheeler:

[https://www.dwheeler.com/essays/scm- security.html](https://www.dwheeler.com/essays/scm-security.html)

On top of yours, the OpenCM and Aegis programs attempted to meet some of these requirements. Most ignore them. Big, blind spot in software security.

</comment></comment></comment></comment><comment><USER20> Speaking of OpenBSD, does anyone know what happened here and how true it is?

[https://arstechnica.com/information- technology/2010/12/fbi-a...](https://arstechnica.com/information- technology/2010/12/fbi-accused-of-planting-backdoor-in-openbsd-ipsec-stack/)

It would certainly jive with John Gilmore's story on how the NSA worked through the standard bodies to keep IPSEC easily exploitable by making the design too difficult to implement properly:

[https://www.mail- email@example.com/msg12...](https://www.mail- firstname.lastname@example.com/msg12325.html)

Their behavior around Simon & Speck and how they refused to reveal details on how exploitable they could be also seems to be similar to their previous tactics.

This is why it's worrisome that Google intends to implement Speck in Android and have pushed it to the Linux kernel, too.

[https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da7a0ab5b4babbe5d7a46f852582be06a00a28f0)

More details on how the NSA has been sabotaging open source projects here:

[https://www.youtube.com/watch?v=fwcl17Q0bpk](https://www.youtube.com/watch?v=fwcl17Q0bpk)

<comment><USER21> Don't have all my sources on hand, but the last time I looked in to this the general conclusion I came to was that there's evidence to suggest that someone was in fact paid to put vulnerabilities into the IPSec stack of OpenBSD. But there was no evidence to suggest that those vulnerabilities ever got written or if they were written that they ever made it into the source tree.

I believe OpenBSD conducted an audit of their tree when rumours of an IPSec backdoor started and didn't find anything alarming.

<comment><USER22> Pretty ancient stuff to bring up, especially in this context. Here's the last denial I recall by one of the people accused of planting backdoors in OpenBSD. Note the date.

[https://www.itworld.com/article/2744922/open-source- tools/op...](https://www.itworld.com/article/2744922/open-source- tools/openbsd-fbi-allegations-denied-by-named-participants.html)

<comment><USER23> Sorry to indulge in tin foil hattery. But this all seems in conclusive.. has there been an independent audit of the components involved?

<comment><USER23> Following up my own question. Just read the security and audit details on OpenBSD page.

[https://www.openbsd.org/security.html](https://www.openbsd.org/security.html)

It appears that there is a continuous audit of source code. So, even if a malicious hole was planted, it ought to be discovered in the years of repeated auditing. Cheers to OpenBSD!

<comment><USER22> Yes, it is the best OS for security, and the audits have gone on for the duration of the project.</comment></comment></comment></comment></comment></comment>