Releases: baristaze/swe_guidelines
Release list
0.51.2: the breadcrumb example is a chat provider's reply URL
The breadcrumb's example of a credential in a URL's path is a chat
provider's reply URL. Patch: wording in a docstring and a test, and
nothing is reversed.
Changed
outgoing_breadcrumb's docstring and the privacy test that holds it
take their example from a chat provider's reply URL, the address a
copy posts to when it answers a chat command; the test posts to
/commands/<credential>and asserts, as before, that the breadcrumb
keeps the scheme and the host and no segment of the path.
0.51.1: a copy stops and starts its stack with make stop and make start
A copy stops and starts its local stack without removing it. Patch:
two developer targets in the scaffold, and nothing is reversed.
Added
make stopin the scaffold stops every container of every file and
profilemake downnames, and removes none, so the stack's ports are
free and its data stays.make startstarts the containers that
exist, and only those, waiting on health, with no build, migration,
or seed; on a tree with no container, it runsmake up.make help,
the quick start, and the local deployment's Commands table list both
besideupanddown.
Changed
make downandmake infra-downsay they remove the containers, so
they read apart frommake stop. OneCOMPOSE_ALLnames every file
and profile fordown,reset,stop, andstart.
0.51.0: a deploy asks a person once, the long-lived branches are never deleted, and the scaffold's ADRs are compacted
A production run asks a person once, a reusable step gates any work
that holds no credential of its own environment, and main, release,
and scaffold cannot be deleted or rewritten. The scaffold's ADRs are
compacted once. Minor: the scaffold gains a reusable workflow, a script,
and ADR 0082, and nothing is reversed.
Added
- ADR 0082 and the scaffold's
human-approval.yml, one reusable
approval step: arulejob refuses an environment with no
required-reviewers rule (or one it cannot read), then anapprovejob
waits in that environment,human-approvalby default. A job that
needs:it runs only after a reviewer approved the run. It is for a
gate whose critical job holds no credential of its own environment,
such as a publish with the run's own token. scripts/branch_rulesets.shin the scaffold sets a ruleset onmain,
release, andscaffold: no deletion, no force push, no bypass
actor.--dry-runprints each one. An administrator runs it once per
repository. A reset ofreleasein the deploy runbook turns off both
of its rulesets for that push.- The repository's own
release.yml, dispatched onmainwith a
release's squash: it waits onhuman-approval, then fast-forwards
release, tags the squash, and publishes the GitHub release with the
changelog's section as its notes. It refuses while the environment has
no required reviewer.CONTRIBUTING.mdsays so.
Changed
- A production run asks a person once, on the one job that holds the
deploy credential:apply, orrollbackon a rollback. A test holds
it so.grant-operator.ymlandstate-unlock.ymlrun the same rule
check before their credential when the environment isproduction.
The check's error says that a private repository can have a
required-reviewers rule only under GitHub Enterprise, so on Free, Pro,
or Team a production deploy there refuses every run. - The scaffold's 47 ADRs are compacted in place: each keeps its title,
status, decision, every bound, identifier, and near miss, and every
consequence a reader acts on, and loses its repeated context, long
quotes of the guideline, and points made twice (26,814 words to
25,483). No ADR is renamed or renumbered. ADR 0024's positions not
taken (no WAF; no GuardDuty or Security Hub) move into its Decision
with their triggers.
Fixed
- The ops audit test's database name carries eight random hex
characters, inside theaudit_<slug>pattern the audit tool accepts,
so two gates on one compose stack no longer drop each other's
database mid-run.
0.50.0: a migration's wait for a lock is bounded, and no capability in a URL reaches the error tracker
A migration waits for a lock only briefly, and the deploy runs it again
when it gives up. No capability carried in a URL reaches the error
tracker, from the server or the portal. A copy numbers its own ADRs
from 1001. Minor: the guideline gains one rule and sharpens two, and
NET-26's statement deadline is reversed on a migration's connection.
Added
- Migrating a Deployed Database, and STO-35: a migration's connection
carrieslock_timeoutfrom settings, under the serving statements'
deadline, and no statement deadline. A migration past the bound exits
with a code that asks for another run, and the deploy runs it again a
bounded number of times before it fails the apply. The scaffold's ADR
0071 cites the rule. - Error Tracking, and the delivery lens's rule on error events: an
outbound call's breadcrumb keeps the method, the status, and the URL's
scheme and host.outgoing_breadcrumbin the scaffold drops the path,
where a webhook's capability lives. - Records of Decisions, and DEL-23: the scaffold's ADRs stay below 1000,
and a copy numbers its own from 1001.arch-scaffold-newand
arch-deviatenumber a copy's decisions from 1001, and
arch-upgrade-scaffoldmoves a clashing scaffold ADR into the copy's
range and rewrites the citations the merge brings.
Changed
- Reversal: NET-26 asks a statement deadline of a storage impl's serving
statement alone. A migration's connection carries the lock bound of
STO-35 instead, and a statement deadline on it that cuts a long
backfill is now a violation. arch-review-fullruns unattended: the review template, the skill,
and the reviewer agent list a scope's files withgit ls-files, run
git from the root, never with-C; the fallback reviewer gets the
same inputs, read-only tools, and an 80-turn cap; and a group report
has a stated format test, one re-run, and one rule each for a fix's
symbol, a tie, and a path's form.- The
review-ombenchmark scenario setsevidence.lenses: true, so
its judges read the section of every lens an answer cites, and its
answer key expects OM-16 and theMANAGER_OWNED_FIELDShalf of OM-03.
A planted finding may list each file its defect shows in. - The repository's
CLAUDE.mdmoves to.claude/CLAUDE.md,make pluginvalidates the plugin with--strict, and
scripts/check_plugin.pyis removed with its test. CI's Claude Code
pin moves to 2.1.289.
Fixed
- A presigned URL names the bucket's regional host, so an upload from
the browser to a bucket made that day outside us-east-1 no longer
fails on a redirect. - The portal's error reports cut every URL at its query: breadcrumbs,
request.url, theRefererheader, and stack frames. An invitation
token or a sign-in code no longer reaches the tracker. - The create run writes the error tracker's url, org, and project from
oneerror_trackerentry inenvironments.json, instead of the
product's name, and refuses a placeholder or a half-named tracker. arch-benchmark-browserlooks for computer actions on the
conversation page after the send too, and records such a session
not-run; its evidence takes the extension the tool saves,.png.- The stale-CNAME test reads the site's name from
environments.json,
so it passes in a copy's gate. - The requeue's plan test seeds settled items and live leases, analyzed,
before it reads its plan, so it no longer fails at random.
0.49.0: a nuke leaves nothing behind, a recreate finds its way, and production's create protects release
An environment the nuke destroyed costs nothing and holds no live
credential, the create run that brings it back finds what it needs
free, and production's create protects release. Minor: the guideline
gains one rule, and nothing is reversed.
A destroy removes what the root declares. What the application wrote,
and what the cloud made for the destroyed resources, is not in the
state, so it stayed: a tenant's live bot token among it. And a recreate
met a zone out of the database's capacity and a DNS record that still
named the distribution the nuke deleted.
Added
- Creating and Destroying an Environment, and OPS-19: a destroy also
removes what the environment left outside the state, the secrets the
application wrote among them; a tenant's secrets stay only beside a
final snapshot that needs them. scripts/cloud_nuke.sh, after the destroy, removes what Terraform
does not own, found by the environment's names: the tenants' secrets
when the database's final snapshot is not found (kept with it when
it is, and any other answer refuses), the cluster's Container
Insights log group, and every task definition revision, paced and
retried. A root already destroyed, with neither cluster nor database
left, skips the apply and the destroy and finishes this step; an
unreadable state refuses.- The production create run protects
release(step 5c): a deploy key
releasewith write access, its private half stored as the
RELEASE_DEPLOY_KEYsecret and never shown, and a ruleset that
restricts creations, updates, deletions, and force pushes, requires
no pull request into release, and lets the deploy key alone
through. Since such a ruleset passes every write deploy key, the run
refuses while another exists. The deploy runbook, ADR 0024, and the
create skill say so. workos-bootstrapreads the environment's webhook endpoints, and an
endpoint the desired state names that is missing, disabled, or that
the key cannot read is a dashboard step the run fails on, instead of
a line it printed and passed.
Changed
- The network gives every zone a private subnet, and the database's and
the cache's subnet groups take them all; the tasks and the public
subnets stay in the load balancer's two zones, and the first two
private subnets keep their zones and ranges. - The create run's step 3c, while no distribution of the account serves
the site's name, deletes a CNAME there to CloudFront whose target no
longer resolves, before the deploy; a target that answers, or a
resolver that cannot tell, refuses. arch-upgrade-scaffoldkeeps a lockfile a move merged without a
conflict while its check passes, and regenerates one that fails from
the merged file, never from the copy's.
Fixed
- A trace is found by its request id: the collector copies
acme.request_idintoacme_request_id, the key X-Ray can filter
on, and indexes the copy; the exporter kept the dot, so no trace was
ever found by id. - An operator who has not enrolled a second factor is told to enrol,
with the runbook's section, instead of a traceback, and the nuke's
report says enrolments and tokens go with the database. - The nuke's report names production's copies of staging's builds only
when the artifacts bucket replicates. - The create run says the grants go one at a time, since a dispatch
made while another waits cancels it, and both runs say a recreated
environment's smoke step waits on the smoke identity's grant. - A Node with no corepack still gets pnpm, and
dev.shstops loudly
when a process fails.
0.48.0: a layer takes the scaffold unchanged, and a copy moves from the source its base records
A repository whose own scaffold builds on this one, a layer, takes the
scaffold unchanged and merges it, and a copy moves from the source its
base records. Minor: a tool and a skill gain a mode, and nothing is
reversed.
A layer keeps the scaffold in scaffold/acme_root/, and products are
copied from it. One tool and one skill then move every layer and every
product, from one tarball, a private source included.
Added
scaffold/base.py --layercommits the source'sscaffold/folder
unchanged, atscaffold/, onto a layer'sscaffoldbranch: one
commit per render, its parent the render before, with the same
trailers. A layer's render records the nameacme, which no copy
takes, sobase.pynever moves a copy's base as a layer's, or a
layer's as a copy's.base.pyreads a private source. On a 404 from codeload, it asks
GitHub's API with the tokengh auth tokengives, in a header no
redirect carries. Without such a token, it refuses and names
--tarball, with thegh apicall that writes one.arch-upgrade-scaffoldmoves a layer, its first take included. It
passes--layer, reads the pin, the ADRs, and the migrations under
scaffold/acme_root/, and runs the gates there; it takes--source
and--tarball. The adopting page says what a layer is.
Changed
- A move without
--sourcetakes the source its base records, and a
--sourcethat names another is refused: a base keeps one source. new.py, run from a layer's checkout, records the checkout's
originon GitHub as the source, and keeps the guideline release its
scaffold pins rather than the layer's own manifest version.
Fixed
arch-upgrade-scaffoldreads the release tags in version order
(--sort=v:refname), sov0.10.0followsv0.9.0.
0.47.0: a write token lives apart from what a reading skill holds, and no tenant's words leave in an exception's text or an outbound call's query
A copy's write token lives apart from what a reading skill holds, and no
tenant's words leave the process in an exception's text or an outbound
call's query. Minor, with one reversal in part, named below.
The boundary of what an agent can do is the credential it holds, never
the prompt. A read skill that sources the file holding a write token has
only its prompt between it and a write, and a tenant's words that reach
it by a log line or a tracker event can steer it.
Changed
- Reversed in part: CTX-38 held the
writetoken in the ops env file; a
writetoken there is now its violation. The provisioner's token
lives in~/.config/acme/ops/<env>.provisioner.env, read only by
acme-ops trafficandstress. The env file a read skill sources
holds thereadtoken alone, the read skills pre-approve only the
acme-opsread commands they run, and OPS-09 and Operator
Credentials say so. - An exception's text leaves the process only when the platform raised
it as a server error: the JSON log line, the tracker's event, and a
work item's, outbox row's, or orchestration's failure record keep the
exception's type and its frames. An error logged by its text alone
now carries its frames. - An outbound call's breadcrumb keeps its method, its status, and its
URL's scheme, host, and path, never its query. The HTTP clients' own
loggers (httpx,httpcore,urllib3) write from WARNING up, since
below it they write a request's whole URL. ops-root-causenames each read it makes, with ajqthat keeps
what the step needs and never an exception's text; it reads the
tracker by request id for its environment, and every read by the
window's bounds.
Fixed
- The scaffold's
.gitignoreno longer ignores a namespace named
reports,coverage,build, ordist: its build and coverage
folders are anchored where their tools write them. - The worker loop's tests wait on what they assert, not on a second of
the wall clock, so a loaded runner no longer fails them. - The benchmark's redactor, and
make runsthrough it, replace
Stripe's secret, restricted, and webhook signing keys.
What a copy does
- Move the provisioner's token out of the ops env file: run the line
the firstacme-opscommand prints, or delete
ACME_PROVISIONER_TOKENfrom the env file and run
uv run acme-ops token --env <env> --identity provisioner. - A copy's own code that logs an exception by its text (
%r,%s)
keeps it only in the plain format a developer reads; pass
exc_info=to keep its frames in the JSON line.
0.46.0: a count asks for a review of a manager, never a split
The count of a manager interface's operations is where a review looks,
never a limit, and the gateway's log filter drops a request's target in
any form. Minor, with one reversal in part, named below.
A count cannot tell one coherent duty of 23 operations from a grab bag
of 23. A limit makes an agent split what belongs together, or park an
operation where it does not belong, to pass a gate. So the number says
where to read, and a review says what to do.
Changed
- Reversed in part: CON-01 and The Business Layer no longer bound a
manager interface. An interface past twenty operations, or the
project's own number, is read for a split: it delegates a duty its
callers use apart, and stays whole when its operations are one duty.
A review reports one left whole with its count and the duty that
holds it together. arch-checkfails no build by the count. Past the threshold it names
the interface and its count under the rule'sto_judge, in the JSON
report and as ato judge:line in the text report, and the exit
status does not read it. The option isreview_thresholdunder
[tool.arch-check.options.CON-01];max_operationsis read as the
same key, and a table that sets both is refused.- The review skills judge every
to_judgeentry in scope, whether or
not the lens has a checker finding, and a report holds a place judged
no breach.arch-review-fullhands each reviewer its rules' entries
whole. arch-deviatewrites a checker entry only for a finding the checker
reports, and records nothing where the rule itself allows what is
described. The scaffold conventions say how a scaffold decides on a
delegate: by the request's own words for the duty and the callers the
run writes.
Fixed
- The gateway's log filter finds a request's target by its place in the
line and writes a dash there, whatever the target's form. In 0.45.0 a
target in absolute form, or with no leading slash, reached uvicorn's
lines with its path and its query string.
What a copy does
- A copy that recorded an exception or an inline ignore for the count
under 0.44.0 or 0.45.0 removes it: it matches no finding now, and the
checker reports it as stale until it goes. A copy that set
max_operationschanges nothing.
0.45.0: a review runs none of the code it reviews, and a session keeps its deadline
A review runs none of the code it reviews, a session made from a
session keeps its deadline, and the scaffold writes no text a tenant
chose into what an operator's skill reads. Minor: arch-check gains a
flag and lens CTX-36 is sharpened. Nothing is reversed.
Added
arch-check --no-localskips a project's local rules, and accepts a
config entry that names a lens a local rule decides. A project's own
gate keeps its local rules.
Changed
- The review skills pass
--no-local, name the root with--root, and
pre-approve no Python command. A review asks once before it runs the
checker, and judges the local rules' lenses itself. - A session made from a session keeps the deadline of the one it ends:
a switch into an org and the landing after an org's deletion take the
earlier of the presented session's deadline and a full lifetime.
Only the exchange of a sign-in starts a new lifetime. CTX-36 and the
scaffold's ADR 0063 say so. - The scaffold's log lines and spans name a request by its route's
template, never its raw path, and the lost-marker warning names an
idempotency key by a digest. A span records no exception text, the
server's socket line drops its target, an error event keeps the
request's method alone, and every engine hides its bound parameters. ops-root-causekeeps ids, kinds, and timestamps from its two reads
of the operator plane, never a name, reads a next page of members by
its cursor, and says what an empty answer means. The skills that hold
a token pre-approve the ops command alone.docs-compacttells an expand and contract in flight by the tree:
the last up file that names the piece decides, and no release tag is
counted. Its sweep lists no applied migration and no generated file.
Its gates runmake openapi, and run the database targets on a
database the run makes and drops. Its citation search finds every
form the checker reads and a citation the margin wrapped, and an ADR
cited from a place the run never edits is kept.
Fixed
WorkManagerImpl.enqueuerequires the permission its kind's table
gives, and refuses a kind the table lacks.- A webhook signature outside its alphabet, or a timestamp past what
intreads, is a bad signature and a 400. A one-time code, an
If-Matchversion, and aContent-Lengthare read as ASCII digits
alone. scaffold/base.pywrites no member of a release's archive through a
link, and lets no link leave the root.- The error tracker reader sends no sort the tracker refuses, so a
request that left no error event answers none. - A copy with a two-word name names its local tracker organization by
the slug the tracker gives it.
What a copy does
- Nothing but take the release. A session no longer renews by a switch,
so a person signs in again when the deadline of their sign-in passes.
An error event in the tracker no longer shows the request's URL,
query, or headers.
0.44.0: a manager that outgrows one interface delegates its duties
A manager that outgrows one interface delegates its duties, and the
scaffold's tenancy manager keeps 17 of its 52 operations. Minor: a rule
is added, with its bound in arch-check. Nothing is reversed.
An interface of 52 operations is read whole by every agent that touches
one of them, and a caller that needs API keys depends on sign-in and
deletion too. So a manager keeps its core, and its other duties are
delegates reached through it.
Added
- The Business Layer says when a manager delegates and how. A delegate
is an interface and an impl of the same namespace, named after the
namespace and the duty, built by the root. A caller outside the
namespace reaches it through its manager
(managers.tenancy.credentials.create_api_key(...)). Inside the
namespace, the root may hand a delegate a sibling typed by its
interface, or a narrow callable for one operation of the manager.
CON-01, CON-09, OM-14, and CTX-21 say the same. arch-checkholds a manager interface, a delegate's included, to a
bound on its operations under CON-01: twenty, or the project's own
max_operationsunder[tool.arch-check.options.CON-01].
Changed
- The scaffold's
TenancyManagerInterfacekeeps seeding, the stage
transitions with the socket tickets, the operator grant job, and the
sweep. Its other 35 operations move, bodies unchanged, to four
delegates:sign_in(9),org(9),members(12), andcredentials
(5), each intenancy/<duty>.pywith its impl inimpl/<duty>.py.
Helpers two duties share are module functions inimpl/shared.py,
andbuild_tenancyinom/root.pybuilds the five. No route, wire
type, or storage call changes. - The scaffold conventions and
arch-scaffold-entitysay where an
operation is written: a scaffold's new operations go to a new delegate
when the manager would pass the bound, andpurge_tenantis always on
the manager itself.
What a copy does
- A copy that takes this release merges the move into its own tenancy
code:tenancy/manager.py,tenancy/impl/manager.py, and the tenancy
tests conflict where the copy changed a moved operation. A caller of a
moved operation names its delegate. An operation the copy added stays
on the manager when the gateway, a peer, or a worker calls it, and
goes to the delegate of its duty otherwise. - A copy whose own manager interface holds more than twenty operations
failsarch-checkat this release: it delegates, or sets
max_operations.