In reply to: https://social.coop/users/smallcircles/statuses/116277491812295481
Great, thanks.
Great, thanks.
@smallcircles @julian I think we might have different ideas about what the ActivityPub API task force is for.
To me, it's about making it possible for clients to use different servers, and different implementations of the API. That's going to include the social API defined in the ActivityPub standard, but it will also encompass things like rate limits, authentication, caching, CORS, and so on.
How that all gets documented will probably be in one or more community group reports.
The extent to which the default profile becomes a 'straightjacket' impact scope, applicability, and usability. I guess its alright as long as there's sufficient flexibility and extensibility taken into account. Guess the "sufficient" does the heavy lifting here.
@smallcircles @julian I think that's always a tension in standards! How do you make it explicit enough that developers can build interoperable software, but extensible enough that they can try new things?
I think one pattern that works well is some base-level standards assumed, and easy ways for extensions to be discoverable and negotiable. If your preferred extension isn't available from the software on the other side of the line, you fall back to the base-level standard.
So, if the rate limit is 300 requests every 5 minutes, and you've already used 143 requests, you might see headers like this:
X-RateLimit-Remaining: 157
X-RateLimit-Reset: 2026-03-22T22:10:00Z
@julian Unfortunately, there are a ton of conflicting variations on this pattern. Some APIs use a Unix timestamp for the reset datetime (!), others use HTTP header values. Mastodon uses an ISO 8601 datetime.
The X-RateLimit-* headers also don't work well if there are multiple quota policies. That can happen if there are particular types of requests that are under a stricter quota than others. There are some variants that APIs use, but they're specific to the platform.
@julian The big advance is the new rate limit headers RFC draft:
https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers
It supports having multiple policies. It's very clean and elegant. Unfortunately, it's still in draft stage. It's probably good to be ready for future changes if you're going to implement this.
> Rate limits are a common part of APIs.
Yes, of API *implementations*, and they may become part of the public interface of these implementation. Whether they should be part of an open standard protocol specification is a different matter imho. Perhaps in a separate implementation guide, suggesting recommended practices.
Or perhaps there may be some way to formulate a generic mechanism in the protocol specification that makes rate limits an extension point, without pinning to a particular method, esp. if it is only a de facto standard.
(Other example. The fediverse is still pinned to an expired draft of HTTP signatures.)
OTOH if the goal of the task force is to mostly just provide implementation guidance, and maybe a reference impl, then I guess examples of rate limiting may be provided.
@smallcircles @julian the point of the API task force is to make using the API across servers possible. That's why we're doing the OAuth work. I think rate limiting is part of the basic profile; it's one of the things you need to support to use the API across different servers.
@julian There are 3 main clusters.
They're linked here for the ActivityPub API task force, but they also apply for the federation protocol:
https://github.com/swicg/activitypub-api/issues/4#issuecomment-4083573914
Anyway, here's my thought: make collection pages real, stable objects, with fixed contents and real modification dates. Return only references, not embedded objects. Do filtering, though. And make pages big -- 100 items or more.
@evan mastodon’s approaches is interesting in this regard, it returns embedded objects for local items, and references for remote objects. Best of both
@django it's good in some ways, but they still don't return Last-Modified headers.
@smallcircles @julian I disagree!
Rate limits are a common part of APIs. For apps to work across servers, the servers need to provide about the same interface.
Using standard rate-limiting headers lets client apps detect what rate limits they will be held to. It reduces the uncertainty.
Fortunately, there is a well known de facto standard and an even better IETF standard coming up. We should point them out.
@citc what?
@julian that's the way to do reverse chron that messes with caches!
Instead, number your pages from oldest to newest. So page 1 was the first page created. After PAGE_SIZE items have been added, create page 2, make it the `first` page, and now page 1 never changes (unless one of its items gets `Remove`d). All your volatility is in the most recent page, and older pages rarely change.
You can also use UUIDs or other IDs for pages.
@julian the downside is that your `first` page is rarely full. You can get around this by having the `first` page be up to 2 * PAGE_SIZE in length, and shifting PAGE_SIZE items to a new page when the `first` page hits its max.
@hongminhee so, I guess this is true, but maybe also the craft changes?
I am old enough to remember when it was common to embed blocks of assembly language in your C code to optimize particular functions or loops. As high level languages grew, that familiarity with hardware architecture has mostly disappeared, but we've developed other skills instead.
When I read @jesse or @simon 's posts about exploring collaboration with LLMs, I see curiosity, creativity and joy in the craft.
@evan@cosocial.ca Totally agree, and I think that’s actually the point the essay is trying to make. The split isn’t “LLM users vs. craft lovers” but something more like “people with room to choose how they use the tools vs. people who don’t have that room.”
@mitchellh@hachyderm.io is a good example. He’s clearly using LLMs as a craftsperson. So am I, I think. But both of us are in situations where we’re not being measured against a colleague’s output every quarter. The workplace dynamic is what compresses all of that curiosity and exploration into pure throughput.
The craft probably does survive, just not evenly distributed.
@hongminhee Fantastic article. 👏 👏
I think there's one possible ray of light for the "code as craft" people - at least a subset of them. To me the craft'ers can enjoy coding for various reasons - the demo-scene folks, the "get it into the smallest amount of code" folks, the aesthetic folks.
But another camp is the "make it easy to understand and extend" folks - and that's pretty much where I fall. People like me, who like arranging things neatly, have had a great advantage for the last few decades, because tidy code is good for industry. There's a reason @mfowler 's Refactoring book is such a big seller.
What I'd argue we don't know for sure yet, is whether readable code as a valuable thing for the industry, is dead. The LLM extremists would probably say it is. But that only works if the only form of validation of code is going to be external (testing & observability, basically). I argue that if humans will still be required to "review" (whatever that ends up meaning) at least some code, then readable code is going to be advantageous.
Even if LLMs can produce readable code we still need human judgment, but for me judgment skills will come from doing, and not just reviewing. In other words, there'll still be an economic case for "developing by hand".
If I'm wrong, and external validation does become sufficient for judging code, then all bets are off. But in that situation I don't think the LLMs will end up writing code as we know it anyway - why would they? They will write whatever uses the least tokens and gets to a valid result most cheaply. Which could be in assembler.
@macgirvin like, only the most recent page should be volatile. Except for deletions, older pages should not change.