Repository navigation
Replies: 20 comments
Reset
Nested modules should still be used for well scoped package APIs
100% is not necessary. At minimum, 80% should be targeted.
This doesn't seem appropriate as a charter question to me. This is a very technical question in regards to the technical implementation for how humus should abstract on top of bedrock. I'm going to leave any comments on the technical details on that proposal and not this one
Keep the hugo docs |
Revision: answers to the open questionsThis revision applies the answers to the five open questions. It also records two later changes: bedrock v0.22.0 is out, and the AI tooling is no longer kept. Each section below replaces the section of the same name in the post. Everything else in the post is unchanged and still applies. Decisions
The charter has no open questions left. Engineering rulesThese are proposed, enforced in CI rather than by review, as in bedrock:
Module layoutToday one Decision: a package with a well-scoped API gets its own nested module.
The costs are the ones z5labs/bedrock#578 listed for Reset strategyDecision: reset, as bedrock did in z5labs/bedrock#553. One story lands on main a tree that keeps only:
That story deletes everything else, and each package comes back through its own stories. main has no REST server until the HTTP and REST stories land. Dependency on bedrock: met. bedrock v0.22.0 contains the process model ( Stale materialOnly the docs site and AI tooling entries change.
The proposals and their orderOnly the Later list changes, because the docs site is no longer deferred:
|
Revision 2: decisions from the lifecycle proposalThis revision applies the decisions in the lifecycle proposal's revision. Each section below replaces the section of the same name, as amended by the first revision. Everything else is unchanged and still applies. In short:
Principlesbedrock's four principles apply to humus unchanged. Two more are specific to humus.
Engineering rulesThese are proposed, enforced in CI rather than by review, as in bedrock:
Package inventory
The proposals and their order
|
Revision 3: health is split across two wavesThis revision splits health into two proposals.
Each section below replaces the section of the same name, as amended by revision 2. Everything else is unchanged and still applies. Package inventory
The proposals and their order
|
Revision 4: wave 1 is done, wave 2 starts, and REST moves to wave 3Wave 1 is done. Its five proposals are closed, and every story written from them has landed on main:
So wave 2 starts, with four proposals:
This revision also reviews how the proposals depend on each other, and moves one. Proposal: REST endpoint DSL and OpenAPI moves from wave 2 to wave 3. Revision 3 let it start early, because it only produces an Each section below replaces the section of the same name, as amended by revision 3. Everything else is unchanged and still applies. Package inventoryOnly these rows change. Every other row of revision 3's table stands.
Dependencies between the proposalsA proposal depends on another when its design builds on the other's API. The waves follow from that:
The wave-1 rows record the order the proposals actually ran in. Configuration, telemetry and humustest built on the lifecycle while it was still being decided. That is why wave 1's stories carried "Blocked by" entries across proposals, and why the parallel rule starts at wave 2. The two wave-3 proposals don't depend on each other:
Three points keep the wave-2 proposals in line with each other without making them depend on each other. Each is already in all four drafts:
One decision could create a dependency between two wave-2 proposals: serving gRPC and HTTP on one port. The gRPC proposal leaves it out of scope, and the HTTP proposal leaves unencrypted HTTP/2 as an open question. If either takes it into scope, it is decided in the HTTP server foundation first, and this table changes. The proposals and their order
|
Revision 5: humus.Main is wave 2, and the runtime proposals move to wave 3The four runtime proposals each specified an App built on The four runtime proposals depend on it, and from wave 2 on no proposal depends on another in its own wave. So:
Each section below replaces the section of the same name, as amended by revision 4. Everything else is unchanged and still applies. Package inventoryOnly these rows change. Every other row of revision 4's table stands.
Dependencies between the proposalsThe rules are unchanged. The table is:
The two wave-4 proposals don't depend on each other:
Three points keep the wave-3 proposals in line with each other without making them depend on each other:
One decision could still create a dependency between two wave-3 proposals: serving gRPC and HTTP on one port. That is unchanged from revision 4: if either proposal takes it into scope, it is decided in the HTTP server foundation first, and this table changes. The proposals and their order
|
Revision 6: humus.Main is the entry pointProposal: humus.Main gives every service one entry point that exits the process. Revision 5 moved the proposals around it but left the charter's own description of a humus Each section below replaces the section of the same name, as amended by revision 5. Everything else is unchanged and still applies. What humus ishumus is an opinionated framework for building services on bedrock: HTTP and REST APIs, gRPC services, queue consumers and jobs, with telemetry, health and graceful shutdown built in.
PrinciplesOnly principle 1 changes:
Package inventoryOnly this row changes. Every other row of revision 5's table stands.
Dependencies between the proposalsUnchanged, except for two bullets. The first wave-4 bullet becomes:
The second of the three points that keep the wave-3 proposals in line becomes:
|
Revision 7: clients in wave 4, failure injection in wave 5, and a wave for every Later itembedrock v0.24.0 releases
Each section below replaces the section of the same name, as amended by revision 5 and revision 6. Everything else is unchanged and still applies. Retries, circuit breakers and failure injectionbedrock leaves humus the same kind of work for all three modules: the protocol wiring, the OTel instruments and the settings. The work divides differently, though.
So each client proposal owns its protocol's wiring. A client that left them out would have to be redesigned when they were added.
One proposal decides these once, instead of three client proposals deciding them three times. It builds on the clients, so it is wave 5. Carrying scenarios across Kafka needs nothing more. As proposed, the Kafka runtime extracts the propagator's baggage from each record's headers, and producing to Kafka injects it. Package inventoryThese rows are new. Every row of revisions 5 and 6 stands.
Dependencies between the proposalsThe rules are unchanged, with one added: when a proposal moves to a later wave, every proposal that depends on it moves with it. For example, revision 5 lets REST move to wave 5 if it needs a health decision of its own. If it does, authentication and authorization moves to wave 6, and wave 6 moves to wave 7.
The two bullets on REST and exposing health probes stand, as revision 6 amended them. Wave 4's new proposals don't depend on those two, or on each other:
Three points keep the client proposals in line with each other without making them depend on each other. If RabbitMQ's proposal also publishes, its publisher keeps to them too.
The two wave-5 proposals don't depend on each other. One decision could change that: whether failure injection trusts a caller because authentication says who it is. If its proposal takes that into scope, failure injection moves to wave 6, after authentication and authorization. The proposals and their order
There is no Later list. A proposal that defers something either names the wave it moves to, through a revision of this charter, or puts it out of scope. Where the deferrals goSome proposals defer work to "later", or to the Later list. Each of those deferrals now has a wave. The open proposals update their references when they're next revised.
|
Revision 8: waves 2 and 3 are done, and wave 4 startsWaves 2 and 3 are done. Their five proposals are closed, and every story written from them has landed on main:
One bug came out of the Kafka runtime's container tests (#757). A member fenced out of its group can still commit for the partitions it held: under at-least-once that can move the new owner's committed offset back, and under at-most-once a record can be processed twice. The fix changes no API, so it is a story, #758, and blocks no proposal. So wave 4 starts, with six proposals:
Each section below replaces the section of the same name, as amended by revision 7. Everything else is unchanged and still applies. Package inventoryOnly these rows change. Every other row of revisions 5, 6 and 7 stands.
Dependencies between the proposalsThe rules and the table are unchanged, except for one row, which named a function that doesn't exist. The test client the gRPC services proposal shipped is
What wave 3 hands onEach wave-3 proposal closed with no open questions, and named what it leaves to waves 4 and 5 under "What waves 4 and 5 build on this". Each of these already has its wave. This table records them in the charter, as revision 7 did for the deferrals before it:
The proposals and their order
There is still no Later list. |
Revision 9: humus's own metrics, a proposal in wave 5Outbound HTTP clients' revision 1 answers its open question 4: no client records instruments of its own in wave 4. bedrock's Each section below replaces the section of the same name, as amended by revision 7 and revision 8. Everything else is unchanged and still applies. Package inventoryThis row is new. Every other row of revisions 5 to 8 stands.
Dependencies between the proposalsThe rules and the table stand, with this row added:
The proposals and their orderOnly wave 5 changes:
Where the deferrals goThis row is new:
The open proposals update their references when they're next revised. There is still no Later list. |
Revision 10: RabbitMQ is tested against RabbitMQ itselfRabbitMQ's revision 1 answers its open question 1. humus is neither RabbitMQ's client nor its server, so it doesn't write or keep a broker implementation, and Each section below replaces the part of the same name, as amended by revision 2 for the principles and revision 8 for the package inventory. Everything else is unchanged and still applies. PrinciplesOnly principle 6 changes:
Package inventoryOnly this row changes. Every other row of revisions 5 to 9 stands.
There is still no Later list. |
Revision 11: the REST proposal is now Proposal: OpenAPI endpoint DSLRevision 1 of the REST proposal renames it Proposal: OpenAPI endpoint DSL, and names its package Each section below replaces the part of the same name, as amended by revision 8 for the package inventory. Everything else is unchanged and still applies. Package inventoryOnly these two rows change. Every other row of revisions 5 to 10 stands.
NamesThe charter and its revisions name the proposal Proposal: REST endpoint DSL and OpenAPI in three places: the wave plan, the dependencies between the proposals, and what wave 3 hands on. In each, read Proposal: OpenAPI endpoint DSL instead. Their links go to #760, and still work. Where they speak of REST's handler, operations or document, read the There is still no Later list. Edited after revision 2 of #760: the package is Edited after revisions 3 to 5 of #760: the opt-in subpackages |
Revision 12: wave 4 is done, and wave 5 startsWave 4 is done. Its six proposals are closed, and every story written from them has landed on main:
Story #758, the fix for the Kafka runtime's fenced-member bug (#757), has landed too. So wave 5 starts, with three proposals:
Each section below replaces the section of the same name, as amended by revisions 7 to 11. Everything else is unchanged and still applies. Package inventoryOnly these rows change. Every other row of revisions 5 to 11 stands.
Dependencies between the proposalsThe rules stand. These three rows replace those of revisions 7 and 9. Every proposal they name is done, so no wave moves:
The three wave-5 proposals still don't depend on each other:
What wave 4 hands onEach wave-4 proposal closed with no open questions, and named what it leaves to wave 5. Each of these already has its wave. This table records them in the charter, as revision 8 did for wave 3:
The proposals and their order
There is still no Later list. Edited after revision 1 of #871: every name humus's own metrics defines starts with |
Revision 13: wave 5 is done, and wave 6 is four walkthroughsWave 5 is done. Its three proposals are closed, and every story written from them has landed on main:
So wave 6 starts. It changes in three ways from what revision 7 planned:
Wave 6's four proposals:
Each section below replaces the section of the same name, as amended by revisions 7 to 12. Everything else is unchanged and still applies. One section is new: What every walkthrough keeps. Package inventoryOnly these rows change. Every other row of revisions 5 to 12 stands.
Dependencies between the proposalsThe rules stand. Revision 7's two rows for wave 6, walkthroughs and a humus MIGRATING.md, and AI tooling, are replaced by these four:
Every proposal they name is done, so no wave moves. The four don't depend on each other. No walkthrough imports, calls or deploys another's code. Their pages share one thing, the Walkthroughs section and the docs test's rule for its samples, and this revision makes those itself, in one story. So each walkthrough's pages wait for that story, and for nothing of another walkthrough's. What every walkthrough keepsA walkthrough is a production-ready application, kept in this repository, with pages that walk a reader through how it was built. It bridges the gap between the feature pages, each about one package, and putting every feature together into a service someone operates. These points keep the four walkthroughs in line with each other without making them depend on each other, as revision 7's three points did for the clients. Each proposal says how it keeps them, and none asks them again. The open questions below are about four of them.
The Walkthroughs sectionOne story is written from this revision, as the reset's was from the charter. It adds what the four walkthroughs' pages share:
Proposal: Kubernetes controller walkthrough, a new feature outside the waves, proposes the same section and rule, so it can use these. What waves 4 and 5 hand onEach wave-4 and wave-5 proposal named what it left to the walkthroughs. This table says which walkthrough takes each:
The proposals and their order
Wave 6 is the charter's last wave. There is still no Later list. Out of scope: AI tooling, and a humus MIGRATING.md. Open questionsThese four are about the points every walkthrough keeps, so they're answered once, here, for all four. Proposal: Kubernetes controller walkthrough asks the first three for its own walkthrough.
Edited to link the bug report, #953. |
Revision 14: WireMock, the LGTM stack, and code-first walkthroughsThe job walkthrough's revision 1 takes four changes from review. They apply to every walkthrough, so this revision adds them to the points every walkthrough keeps:
Each section below replaces or adds to the section of the same name, as revision 13 left it. Everything else is unchanged. No wave moves. Package inventoryOnly these rows change. Every other row of revisions 5 to 13 stands.
Dependencies between the proposalsIn the job's and the RabbitMQ processor's rows, "the HTTP server foundation, for its stand-in" becomes "the HTTP server foundation, for its unit tests' stubs". Every proposal named is still done. What every walkthrough keepsPoints 2, 4, 6, 7, 8 and 9 become the following, and point 11 is added. Points 1, 3, 5 and 10 are unchanged. 2. It stands alone. No walkthrough imports, calls or deploys another's code. Its dependencies are real systems, in containers and in its kind overlay. WireMock stands in for an HTTP API it invents, with mappings the walkthrough owns, and its cases read what the App sent from WireMock's request journal. No walkthrough writes a server to stand in for a dependency. humus still writes no fake of another project's server, as revision 10 amended principle 6. 4. It is tested at three levels, with the cases written once. The first two levels become:
The rest of the point is unchanged. 6. It ships an image and manifests, and publishes neither. A Dockerfile builds a static binary onto a distroless, non-root base.
A script beside the overlay, 7. Its CI jobs aren't required. " walkthrough (testcontainers)" runs its container tests, if it has any. " walkthrough (kind)" builds the image, runs 8. Its alerts are rules. 9. Its pages are 11. Its code has no comments except the license header that every Go file starts with, and a one-line package comment per package. Build constraints and The Walkthroughs sectionThe docs test's rule adds JSON, for WireMock's mappings: a Go, YAML, JSON, Dockerfile or protobuf sample on a walkthrough's page must appear, line for line, in a file under its walkthrough's directory. The section's story makes this change, in place of the job walkthrough, whose revision 1 planned it for itself. What this changes in each walkthroughThis section is added. Each walkthrough's stories make these changes:
Proposal: Kubernetes controller walkthrough is outside the waves, so these points don't bind it. Open questionsRevision 13's four are still open. This revision adds none. |
Revision 15: revision 13's questions answeredRevision 13's questions:
Each section below replaces or adds to the section of the same name, as revision 14 left it. Everything else is unchanged. No wave moves. Package inventoryThis row is added. Every other row of revisions 5 to 14 stands.
What every walkthrough keepsPoints 8 and 10 become the following. In point 3, the observability item becomes "traces, logs and metrics over OTLP, alerts on its instruments, humus's own included, and a dashboard". In point 6, the LGTM item adds "The Collector also runs the receivers the alerts need, such as the Kubernetes cluster receiver." Every other point is unchanged. 8. Its alerts are Grafana's, and it ships a dashboard.
10. It is a module of its own, Every example is a moduleThis section is added. An example is a complete application, in a module of its own at One more story is written from this revision itself, as for the Walkthroughs section:
A walkthrough's story that adds its module waits for this one. What waves 4 and 5 hand onThe row for humus's own metrics becomes:
What this changes in each walkthroughThese add to revision 14's table. Each walkthrough's stories make them:
Proposal: Kubernetes controller walkthrough asks questions 1 to 3 for itself. This revision doesn't answer them there. Open questionsNone. Revision 13's four are answered above. ReferencesThese are added:
|
Revision 16: the Kafka processor walkthrough has no redrive jobThe Kafka processor walkthrough's revision 1 drops its redrive job. Whether a dead letter can be replayed depends on why it was dead-lettered, which each end user learns by running their own system, so its pages tell the reader to plan for that. Each section below replaces the rows of the same name, as revision 15 left them. Everything else is unchanged. No wave moves. Package inventoryOnly this row changes. Every other row of revisions 5 to 15 stands.
Dependencies between the proposalsIn the Kafka processor walkthrough's row, "jobs, for its redrive job" is dropped. Every proposal it still names is done. Open questionsNone. |
Revision 17: the API walkthrough's catalog is HTTP, and gRPC gets a walkthrough of its ownThe API walkthrough's revision 2 answers its open questions. Its catalog is an Each section below replaces the rows of the same name, as revision 16 left them. Everything else is unchanged. No wave moves. Package inventoryOnly this row changes. Every other row of revisions 5 to 16 stands.
Dependencies between the proposalsIn the API walkthrough's row, "gRPC services and outbound gRPC clients, for the catalog; outbound HTTP clients, for the key set" becomes "outbound HTTP clients, for the catalog and the key set". Every proposal it still names is done. The gRPC walkthrough has no row until its proposal is written. Its wave is decided then. What waves 4 and 5 hand onOnly this row changes:
Open questionsNone. |
Revision 18: the gRPC walkthrough joins wave 6Proposal: gRPC walkthrough is the proposal that revision 17 left for later. It builds a wallet and its ledger, two gRPC services of the walkthrough's own, at Its prototype found a bug in Each section below replaces or adds to the rows of the same name, as revision 17 left them. Everything else is unchanged. No wave moves. Package inventoryThis row is added. Every other row of revisions 5 to 17 stands.
Dependencies between the proposalsThis row is added:
Every proposal it names is done. Like the other walkthroughs, it depends on none of them. What waves 4 and 5 hand onOnly this row changes:
The proposals and their orderWave 6's list gains: It keeps the points every walkthrough keeps, and its pages use the Walkthroughs section that #974 and #1090 added. Open questionsNone. The walkthrough's own four are in its proposal. |
Revision 19: wave 6 is done, and so is the charterWave 6 is done. Its five walkthroughs are closed, and every story written from them has landed on main:
The charter's own stories, #974 and #975, have landed too. So have the fixes for the bugs the walkthroughs found: #953 (#960), #1144 (#1244), #1175 (#1178), #1176 (#1180), #1254 (#1258), #1255 (#1256), #1274 (#1275) and #1278 (#1279). Every proposal this charter planned, in waves 1 to 6, is closed as resolved, and revision 7 left nothing for later. So the charter is done, and this discussion closes. One bug from wave 6 is still open: #1293. The API walkthrough's server spans are named Proposals for brand-new features, such as finding flaky tests and simulation testing, don't belong to the charter and get no wave, like Kubernetes controllers before them. Nothing else in the charter changes. No wave moves. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Note
The charter is done, as revision 19 records. Wave 6 is done, every proposal in waves 1 to 6 is closed as resolved, and this discussion is closed. The one open bug from wave 6, #1293, is fixed as a bug, not through the charter.
Note
The package inventory and the dependencies between the proposals are amended again by revision 16. The Kafka processor walkthrough has no redrive job, so it no longer depends on jobs. No wave moves.
Note
Revision 15 answers revision 13's questions. Walkthroughs are kustomizations, each with a kind job. Every example, not only the walkthroughs, is a module of its own at
example/<name>, and none is released. A walkthrough is an example that is also production-ready, and any other example may cut corners. Nothing is Prometheus's: alerts are Grafana-managed rules, each walkthrough ships a Grafana dashboard, and the Collector's receivers replace exporters such as kube-state-metrics. No wave moves.Note
The points every walkthrough keeps are amended by revision 14. WireMock stands in for an HTTP API a walkthrough invents, and there is no compose file: one script brings each walkthrough up on kind, in CI and for a reader. The kind overlay's OpenTelemetry Collector forwards to the LGTM stack (Loki, Grafana, Tempo and Mimir), and Mimir's ruler loads the alerts. The code has no comments except its license headers and package comments, and the pages are code-first steps. No wave moves.
Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 13, which also adds the points every walkthrough keeps. Wave 5 is done. AI tooling and a humus MIGRATING.md are out of scope, since humus has no users outside z5labs. Wave 6 is four walkthroughs, one proposal each: an API, a job, a Kafka processor and a RabbitMQ processor. They don't depend on each other, so no wave moves.
Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 12. Wave 4 is done, and wave 5 starts, with three proposals: failure injection, authentication and authorization and humus's own metrics. They still don't depend on each other, so no wave moves.
Note
The package inventory is amended again by revision 11. Proposal: REST endpoint DSL and OpenAPI is now Proposal: OpenAPI endpoint DSL, and its package is
openapi/v3. The waves don't change.Note
Principle 6 and the package inventory are amended again by revision 10. humus writes no other project's server for tests. RabbitMQ is tested against RabbitMQ itself, in a container, and an App that uses it runs whole against that container rather than inside
synctest. The waves don't change.Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 9. Instruments of humus's own, such as gauges of the clients' breakers and retry budgets, become a proposal of their own in wave 5: humus's own metrics.
Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 8. Waves 2 and 3 are done, and wave 4 starts, with six proposals: REST endpoint DSL and OpenAPI, exposing health probes, outbound HTTP clients, outbound gRPC clients, producing to Kafka and RabbitMQ.
Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 7. bedrock v0.24.0's
retryandcircuitgo into three wave-4 client proposals: outbound HTTP clients, outbound gRPC clients, and producing to Kafka. RabbitMQ is wave 4 too. Failure injection, on bedrock'sfit, and authentication and authorization, which replaces REST security, are a new wave 5. The walkthroughs, a humus MIGRATING.md and AI tooling are a new wave 6. The Later list is gone: every deferral names a wave or is out of scope.Note
What humus is, principle 1, the package inventory and the dependencies between the proposals are amended again by revision 6. A humus
mainisfunc main() { humus.Main(app.Init) }, or a runtime package'sMain.humus.Mainis the one place that hands an App the real process.Note
The package inventory, the dependencies between the proposals and their order are amended again by revision 5. Proposal: humus.Main is wave 2, on its own. The four runtime proposals move to wave 3, and REST and exposing health probes move to wave 4.
Note
The package inventory and the order of the proposals are amended again by revision 4. Wave 1 is done, and wave 2 has started: HTTP server foundation, gRPC services, jobs and queue processing and the Kafka runtime. Proposal: REST endpoint DSL and OpenAPI moves to wave 3, because it is built on the HTTP server foundation. The revision also maps the dependencies between the proposals.
Note
The package inventory and the order of the proposals are amended again by revision 3. Health is split into two proposals. Proposal: health monitors and probes stays in wave 1 for health's core. Proposal: exposing health probes, in a new wave 3, decides how probes are served over HTTP and gRPC.
Note
The principles, engineering rules, package inventory and order of the proposals are amended again by revision 2. It applies the decisions of the lifecycle proposal. Tests may use files in their own temp directory. The lint rules don't ban the
Hostboundary. Health is a Service rather than part of the lifecycle. Each wave-2 proposal specifies an App built onhumus.App.Note
The engineering rules, module layout, reset strategy, docs site and AI tooling plans, and open questions in this post are superseded by the revision below. It records the answers to the open questions: reset; nested modules for well-scoped package APIs; an 80% coverage gate; the Hugo docs site stays; the AI tooling is deleted with the reset instead of frozen; and whether to ban
net.Listen,net.Dialandos.ReadFileoutsideOSHostmoves to #630. It also notes that bedrock v0.22.0 contains the process model. The rest of this post is unchanged and kept for context.Note
This is the charter for re-evaluating humus on bedrock's process model. It proposes what humus is, the rules every humus package is held to, what happens to each package, and the order in which the package proposals are discussed. Each package's API is proposed in its own discussion, and stories are written only from accepted proposals.
Summary
bedrock has been rebuilt around one idea: an application is an OS process (z5labs/bedrock#553 to z5labs/bedrock#571). A
bedrock.Appisand
func main() { bedrock.Main(app) }is the only place that touches the real process. Everything bedrock provided beyond that boundary is gone:runtime/http,runtime/http/rest,runtime/otel, Builder/Runtime/Runner,RecoverPanicsandNotifyOnSignal. bedrock's MIGRATING.md names humus as the new home of the framework pieces.humus is built on everything that was removed, so this proposal does not port it. It starts over: humus is re-evaluated package by package against the process model, the way bedrock was.
Why start over instead of porting
rest.Runis a Builder stack insideDefaultRunner,RecoverPanicsandNotifyOnSignal(rest/rest.go#L201-L224).job.Appandqueue.Apphave the v0.21.0Run(context.Context) errorruntime shape (job/job.go,queue/queue.go).grpc/grpc.gowas deleted and onlyNewApiandRegisterServiceare left;jobandqueueset up no telemetry;rest.YamlSource, anrpcpackage, petstore examples and five AI instruction files, none of which exist.runtime/http/rest, inlinedruntime/oteland adaptedjobandqueue. It never asked the questions the process model raises:mainfromos.Getenv;What humus is
humus is an opinionated framework for building services on bedrock: HTTP and REST APIs, gRPC services, queue consumers and jobs, with telemetry, health and graceful shutdown built in.
bedrock.App, and itsmainisfunc main() { bedrock.Main(app) }.Principles
bedrock's four principles apply to humus unchanged. Two more are specific to humus.
os.Args, the environment, the standard streams or signals, and nothing exits the process. Everything comes throughbedrock.Process.humus.Host, proposed in Proposal: the humus App lifecycle). Time comes fromtesting/synctestin tests, and randomness fromtesting/cryptotest.slog.Default.testing/synctestbubble, on bedrocktest'sProcessand humustest'sHost, with no real socket, file or environment variable. Every package proposal shows such a test.Engineering rules
These are proposed, enforced in CI rather than by review, as in bedrock:
os.Args,os.Stdin,os.Stdout,os.Stderr,os.Getenv,os.LookupEnv,os.Environ,os.Exit,signal.Notify,signal.NotifyContext,flag.Parseandflag.CommandLine.net.Listen,net.Dialandos.ReadFileoutsidehumus.OSHost;otel.Set*,otel.Get*,otel.Tracer,otel.Meter,global.SetLoggerProvider);resource.Default;slog.SetDefault.testify/require, as they do today.Examplefunctions or as apackage mainwith anapp_test.go.Package inventory
humus(root)Logger/LogHandlerover the global otelslogApp,Service,Host,Setupbedrockconfig.Reader[T]SettingsandReadSettingsper packagetelemetry(new)restthrough bedrock'sruntime/otelhumustest(new)Host, telemetry recorder, Service contract testhealthMonitor,Binary,And,Or, plus an internal gRPC health serverMonitor; add probes owned by the lifecyclerestRun, plus bedrock'sruntime/http/restDSLgrpcNewApi,RegisterService; can't runjobqueue,queue/kafkaConsumer/Processor/Acknowledger, plus a franz-go runtimeinternal/httpserver,internal/grpcserver,internal/grpchealthexample/rest/shoppingcartmainreadsos.Getenvand opens a pgx poolReset strategy
The proposal is to reset as bedrock did in z5labs/bedrock#553. One story lands on main a tree that keeps only:
LICENSE;.githubtemplates;.claude/backlog.json;That story deletes everything else, and each package comes back through its own stories.
Module layout
Today one
go.modcovers everything. The example's pgx, testcontainers (and with it docker), franz-go and grpc-go all end up in every user's module graph.The proposal:
grpc,queue/kafkaandexample.The costs are the ones z5labs/bedrock#578 listed for
fit: a CI step per module, and separate<module>/vX.Y.Ztags.From discussion to stories
storylabel, and each links back to the discussion. Only then can the backlog loop pick them up.The proposals and their order
http.Handler.Stale material
go.modsays 1.26, and shows a 55.9% coverage badge.docs/contentshow removed APIs: the Builder/Runner pattern, YAML config,rest.Run(rest.YamlSource(...))and therpcpackage. The proposal is to delete them with the reset and write docs as each package lands, ending with a migration guide like bedrock's..claude/agents/implement-*andinstructions/rest-api-generatorgenerate code against today's DSL. The proposal is to freeze them until the REST DSL proposal is accepted, then regenerate them.Open questions
grpc,queue/kafkaandexample, or one module?net.Listen,net.Dialandos.ReadFileoutsideOSHost? That would be stricter than bedrock.References
example/httpserver, the reference serviceAll reactions