Skip to content

Releases: baristaze/swe_guidelines

0.51.2: the breadcrumb example is a chat provider's reply URL

Choose a tag to compare

@baristaze baristaze released this 05 Oct 12:41
f0f8348

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

Choose a tag to compare

@baristaze baristaze released this 05 Oct 08:18
0089bfb

A copy stops and starts its local stack without removing it. Patch:
two developer targets in the scaffold, and nothing is reversed.

Added

  • make stop in the scaffold stops every container of every file and
    profile make down names, and removes none, so the stack's ports are
    free and its data stays. make start starts the containers that
    exist, and only those, waiting on health, with no build, migration,
    or seed; on a tree with no container, it runs make up. make help,
    the quick start, and the local deployment's Commands table list both
    beside up and down.

Changed

  • make down and make infra-down say they remove the containers, so
    they read apart from make stop. One COMPOSE_ALL names every file
    and profile for down, reset, stop, and start.

0.51.0: a deploy asks a person once, the long-lived branches are never deleted, and the scaffold's ADRs are compacted

Choose a tag to compare

@baristaze baristaze released this 04 Oct 17:42
989b77e

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: a rule job refuses an environment with no
    required-reviewers rule (or one it cannot read), then an approve job
    waits in that environment, human-approval by 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.sh in the scaffold sets a ruleset on main,
    release, and scaffold: no deletion, no force push, no bypass
    actor. --dry-run prints each one. An administrator runs it once per
    repository. A reset of release in the deploy runbook turns off both
    of its rulesets for that push.
  • The repository's own release.yml, dispatched on main with a
    release's squash: it waits on human-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.md says so.

Changed

  • A production run asks a person once, on the one job that holds the
    deploy credential: apply, or rollback on a rollback. A test holds
    it so. grant-operator.yml and state-unlock.yml run the same rule
    check before their credential when the environment is production.
    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 the audit_<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

Choose a tag to compare

@baristaze baristaze released this 04 Oct 07:46
b1501e9

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
    carries lock_timeout from 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_breadcrumb in 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-new and
    arch-deviate number a copy's decisions from 1001, and
    arch-upgrade-scaffold moves 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-full runs unattended: the review template, the skill,
    and the reviewer agent list a scope's files with git 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-om benchmark scenario sets evidence.lenses: true, so
    its judges read the section of every lens an answer cites, and its
    answer key expects OM-16 and the MANAGER_OWNED_FIELDS half of OM-03.
    A planted finding may list each file its defect shows in.
  • The repository's CLAUDE.md moves to .claude/CLAUDE.md, make plugin validates the plugin with --strict, and
    scripts/check_plugin.py is 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, the Referer header, 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
    one error_tracker entry in environments.json, instead of the
    product's name, and refuses a placeholder or a half-named tracker.
  • arch-benchmark-browser looks 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

Choose a tag to compare

@baristaze baristaze released this 04 Oct 00:05
36355e9

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
    release with write access, its private half stored as the
    RELEASE_DEPLOY_KEY secret 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-bootstrap reads 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-scaffold keeps 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_id into acme_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.sh stops loudly
    when a process fails.

0.48.0: a layer takes the scaffold unchanged, and a copy moves from the source its base records

Choose a tag to compare

@baristaze baristaze released this 02 Oct 07:23
4223c0b

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 --layer commits the source's scaffold/ folder
    unchanged, at scaffold/, onto a layer's scaffold branch: one
    commit per render, its parent the render before, with the same
    trailers. A layer's render records the name acme, which no copy
    takes, so base.py never moves a copy's base as a layer's, or a
    layer's as a copy's.
  • base.py reads a private source. On a 404 from codeload, it asks
    GitHub's API with the token gh auth token gives, in a header no
    redirect carries. Without such a token, it refuses and names
    --tarball, with the gh api call that writes one.
  • arch-upgrade-scaffold moves 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 --source takes the source its base records, and a
    --source that names another is refused: a base keeps one source.
  • new.py, run from a layer's checkout, records the checkout's
    origin on GitHub as the source, and keeps the guideline release its
    scaffold pins rather than the layer's own manifest version.

Fixed

  • arch-upgrade-scaffold reads the release tags in version order
    (--sort=v:refname), so v0.10.0 follows v0.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

Choose a tag to compare

@baristaze baristaze released this 30 Sep 20:04
a2cf954

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 write token in the ops env file; a
    write token there is now its violation. The provisioner's token
    lives in ~/.config/acme/ops/<env>.provisioner.env, read only by
    acme-ops traffic and stress. The env file a read skill sources
    holds the read token alone, the read skills pre-approve only the
    acme-ops read 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-cause names each read it makes, with a jq that 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 .gitignore no longer ignores a namespace named
    reports, coverage, build, or dist: 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 runs through 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 first acme-ops command prints, or delete
    ACME_PROVISIONER_TOKEN from 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

Choose a tag to compare

@baristaze baristaze released this 30 Sep 16:17
11b8415

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-check fails no build by the count. Past the threshold it names
    the interface and its count under the rule's to_judge, in the JSON
    report and as a to judge: line in the text report, and the exit
    status does not read it. The option is review_threshold under
    [tool.arch-check.options.CON-01]; max_operations is read as the
    same key, and a table that sets both is refused.
  • The review skills judge every to_judge entry in scope, whether or
    not the lens has a checker finding, and a report holds a place judged
    no breach. arch-review-full hands each reviewer its rules' entries
    whole.
  • arch-deviate writes 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_operations changes nothing.

0.45.0: a review runs none of the code it reviews, and a session keeps its deadline

Choose a tag to compare

@baristaze baristaze released this 30 Sep 14:26
d98c218

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-local skips 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-cause keeps 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-compact tells 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 run make 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.enqueue requires 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
    int reads, is a bad signature and a 400. A one-time code, an
    If-Match version, and a Content-Length are read as ASCII digits
    alone.
  • scaffold/base.py writes 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

Choose a tag to compare

@baristaze baristaze released this 30 Sep 12:14
1708f97

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-check holds a manager interface, a delegate's included, to a
    bound on its operations under CON-01: twenty, or the project's own
    max_operations under [tool.arch-check.options.CON-01].

Changed

  • The scaffold's TenancyManagerInterface keeps 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), and credentials
    (5), each in tenancy/<duty>.py with its impl in impl/<duty>.py.
    Helpers two duties share are module functions in impl/shared.py,
    and build_tenancy in om/root.py builds the five. No route, wire
    type, or storage call changes.
  • The scaffold conventions and arch-scaffold-entity say where an
    operation is written: a scaffold's new operations go to a new delegate
    when the manager would pass the bound, and purge_tenant is 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
    fails arch-check at this release: it delegates, or sets
    max_operations.