This is an automated email from the ASF dual-hosted git repository.
akm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/main by this push:
new 54c643b Cleaning up notes; fixes #533
54c643b is described below
commit 54c643b41afbbbd5efb41c0d62c1191d02181e2f
Author: Andrew K. Musselman <[email protected]>
AuthorDate: Fri Jan 23 12:01:21 2026 -0800
Cleaning up notes; fixes #533
---
atr/docs/storage-interface.md | 39 +++++++++++++++++++
notes/api-security.md | 38 -------------------
notes/development.md | 26 -------------
notes/for-prospective-contributors.md | 23 ------------
notes/outcome-design-patterns.md | 38 -------------------
notes/test-user-flows.md | 71 -----------------------------------
notes/trivial-changes.md | 9 -----
7 files changed, 39 insertions(+), 205 deletions(-)
diff --git a/atr/docs/storage-interface.md b/atr/docs/storage-interface.md
index befc07c..262b9f6 100644
--- a/atr/docs/storage-interface.md
+++ b/atr/docs/storage-interface.md
@@ -179,3 +179,42 @@ The structure of the directories that need backing up is
as follows. An ellipsis
Because of the versioning scheme used for the `attestable`, `finished`, and
`unfinished` directories, these can be incrementally updated by simple copying
without deletion. The downloads directory, however, must be snapshotted as its
organization is random.
This list does not include any configuration files, logs, or log directories.
All configuration files and the audit logs, at a minimum, should also be backed
up.
+
+## Outcome design patterns
+
+One common pattern when designing outcome types is about how to handle an
**exception after a success**, and how to handle a **warning during success**:
+
+* An **exception after a success** is when an object is processed in multiple
stages, and the first few stages succeed but then subsequently there is an
exception.
+* A **warning during success** is when an object is processed in multiple
stages, an exception is raised, but we determine that we can proceed to
subsequent stages as long as we keep a note of the exception.
+
+Both of these workflows appear incompatible with outcomes. In outcomes, we can
record _either_ a successful result, _or_ an exception. But in exception after
success we want to record the successes up to the exception; and in a warning
during a success we want to record the exception even though we return a
success result.
+
+The solution is similar in both cases: create a wrapper of the _primary type_
which can hold an instance of the _secondary type_.
+
+In _exception after a success_ the primary type is an exception, and the
secondary type is the result which was obtained up to that exception. The type
will look like this:
+
+```python
+class AfterSuccessError(Exception):
+ def __init__(self, result_before_error: Result):
+ self.result_before_error = result_before_error
+```
+
+In _warning during success_, the primary type is the result, and the secondary
type is the exception raised during successful processing which we consider a
warning. This is the inverse of the above, and the types are therefore inverted
too.
+
+```python
[email protected]
+class Result:
+ value: Value
+ warning: Exception | None
+```
+
+This could just as easily be a Pydantic class or whatever is appropriate in
the situation, as long as it can hold the warning. If the warning is generated
during an additional or side task, we can use `Outcome[SideValue]` instead. We
do this, for example, in the type representing a linked committee:
+
+```python
[email protected]
+class LinkedCommittee:
+ name: str
+ autogenerated_keys_file: Outcome[str]
+```
+
+In this case, if the autogenerated keys file call succeeded without an error,
the `Outcome` will be an `OutcomeResult[str]` where the `str` represents the
full path to the autogenerated file.
diff --git a/notes/api-security.md b/notes/api-security.md
deleted file mode 100644
index 0051cc7..0000000
--- a/notes/api-security.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# ATR API security model
-
-All ATR routes, on both the website and the API, require HTTPS using TLS 1.2
or newer for their transport.
-
-There are two access levels to the ATR API: public and committer. Public API
endpoints are accessible to everybody. Committer endpoints have the following
accessibility criteria instead.
-
-## PATs
-
-Committers must obtain a [Personal Access
Token](https://en.wikipedia.org/wiki/Personal_access_token) (PAT) from the ATR
website at the route `/tokens`. Only committers, signed in through [ASF
OAuth](https://oauth.apache.org/api.html) to ATR, can obtain PATs. Each PAT
expires in 180 days, and can be revoked at any time by the user at the same
route. ATR does not store PATs, only the hashes of PATs.
-
-## JWTs
-
-To make a request to a committer protected endpoint on the API, committers
must first obtain a [JWT](https://en.wikipedia.org/wiki/JSON_Web_Token). They
can do this in one of two ways:
-
-1. For debugging, obtaining a JWT from the `/tokens` page.
-2. For script use, obtaining a JWT by POSTing their PAT in a JSON payload to
the API endpoint `/api/jwt`. This is a public route, and requires a payload
such as `{"asfuid": "${ASF_UID}", "pat": "${PAT_TOKEN}"}`. The response will be
`{"asfuid": "${ASF_UID}", "jwt": "${JWT_TOKEN}"}`.
-
-Every JWT issued by the ATR expires in 90 minutes, uses the HS256
(HMAC-SHA256) algorithm, and makes `sub` (ASF UID), `iat` (issue time), `exp`
(expires at), and `jti` (token payload) claims. JWTs are stateless, so there is
no analogue stored by the ATR, except for the secret symmetric key of the
server which is initialised on startup. If the ATR server is restarted, all
JWTs are expired immediately.
-
-The JWT can be used to access protected endpoints by using it in the
`Authorization` header as a bearer token, i.e. `Authorization: Bearer
${JWT_TOKEN}`. PATs and JWTs must never appear in URLs. They must be protected
by the user at all times. Accidental sharing of a PAT or a JWT must be reported
to ASF security.
-
-Note that PATs cannot be used to access protected endpoints. They can only be
used to issue a JWT, which is then used to access protected endpoints.
-
-Endpoints which mutate state, require significant computation, or have large
or sensitive payloads use POST. All other endpoints use GET.
-
-## Limitations
-
-We do not currently support scopes in either PATs or JWTs, but are considering
this.
-
-Admins are able to revoke any PAT, and users are able to revoke any of their
own PATs, but neither admins nor users are able to revoke JWTs on an individual
basis. Restarting the server resets the server secret symmetric key, which has
the side effect of expiring all JWTs, and can be used in an emergency.
-
-We do not have refresh tokens, and do not plan to implement refresh tokens.
PATs must be used to issue a new JWT through the API.
-
-We do not presently have logging or auditing of the logging for the API. Once
we implement logging, we must ensure that tokens and other sensitive data are
not stored.
-
-We do not use all available JWT fields, such as `iss` (issuer).
-
-Security-related actions, such as PAT and JWT issuance, are rate limited to 10
per hour per IP/ASF UID.
diff --git a/notes/development.md b/notes/development.md
deleted file mode 100644
index e840099..0000000
--- a/notes/development.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Development
-
-You will need to have a working [Python
3.13](https://www.python.org/downloads/release/python-3132/) installation,
[uv](https://docs.astral.sh/uv/),
[mkcert](https://github.com/FiloSottile/mkcert), and a POSIX compliant `make`.
To optionally build the HTML documentation files you will also need
[cmark](https://github.com/commonmark/cmark).
-
-Ensure that you have the pre-commit hook installed:
-
-```shell
-make sync-all
-uv run --frozen pre-commit install
-```
-
-To run the project, use the following commands, which will add a local CA root
to your OS and browser certificate store if using Firefox:
-
-```shell
-make sync-all
-make certs-local
-make serve
-```
-
-And add the following line to your `/etc/hosts`:
-
-```text
-127.0.0.1 localhost.apache.org
-```
-
-The website will be available at
[https://localhost.apache.org:8080/](https://localhost.apache.org:8080/) using
a self-signed certificate.
diff --git a/notes/for-prospective-contributors.md
b/notes/for-prospective-contributors.md
deleted file mode 100644
index 625ccc6..0000000
--- a/notes/for-prospective-contributors.md
+++ /dev/null
@@ -1,23 +0,0 @@
-**Instructions for prospective contributors:** <!-- markdownlint-disable-line
MD041 -->
-
-Thank you for your offer to help with ATR! We require new contributors who are
not existing ASF committers to send a message of introduction to our
development mailing list.
-
-Please follow these instructions carefully:
-
-1. Send an empty message to
[[email protected]](mailto:[email protected])
-
-2. Reply to the automated response to subscribe
-
-3. Send a message to [[email protected]](mailto:[email protected])
introducing yourself. Your message must also contain the last ten lines of
output from ATR pre-commit checks, and the last ten lines of output from the
e2e tests
-
-_These instructions do not apply to trivial changes such as bug fixes or the
correction of typographical errors. They do, however, apply to any substantial
documentation changes._
-
-We **only accept PRs that have been linted and tested**. You will need to run
and test ATR in order to contribute. Please see the following guides:
-
-* [How to run the ATR
server](https://release-test.apache.org/docs/running-the-server)
-* [How to run ATR pre-commit
checks](https://release-test.apache.org/docs/how-to-contribute#pull-request-workflow)
-* [How to run and create ATR
tests](https://release-test.apache.org/docs/running-and-creating-tests#running-end-to-end-tests)
-
-You must mark your PR as a draft until it is ready for review. You must use
the rebase strategy to keep your PR up to date with the `main` branch. Please
follow everything in the [contribution
guide](https://release-test.apache.org/docs/how-to-contribute) and the [code
conventions](https://release-test.apache.org/docs/code-conventions).
-
-Thank you again for the offer of contribution. We hope that these requirements
and the volume of reading will not deter you from contributing. ATR is used to
bolster supply chain security, so we put these procedures in place to help to
ensure a high quality of contributions. If you have any problems following
these instructions, please [open a new GitHub
issue](https://github.com/apache/tooling-trusted-releases/issues/new?template=BLANK_ISSUE).
diff --git a/notes/outcome-design-patterns.md b/notes/outcome-design-patterns.md
deleted file mode 100644
index d5430cd..0000000
--- a/notes/outcome-design-patterns.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Outcome design patterns
-
-One common pattern when designing outcome types is about how to handle an
**exception after a success**, and how to handle a **warning during success**:
-
-* An **exception after a success** is when an object is processed in multiple
stages, and the first few stages succeed but then subsequently there is an
exception.
-* A **warning during success** is when an object is processed in multiple
stages, an exception is raised, but we determine that we can proceed to
subsequent stages as long as we keep a note of the exception.
-
-Both of these workflows appear incompatible with outcomes. In outcomes, we can
record _either_ a successful result, _or_ an exception. But in exception after
success we want to record the successes up to the exception; and in a warning
during a success we want to record the exception even though we return a
success result.
-
-The solution is similar in both cases: create a wrapper of the _primary type_
which can hold an instance of the _secondary type_.
-
-In _exception after a success_ the primary type is an exception, and the
secondary type is the result which was obtained up to that exception. The type
will look like this:
-
-```python
-class AfterSuccessError(Exception):
- def __init__(self, result_before_error: Result):
- self.result_before_error = result_before_error
-```
-
-In _warning during success_, the primary type is the result, and the secondary
type is the exception raised during successful processing which we consider a
warning. This is the inverse of the above, and the types are therefore inverted
too.
-
-```python
[email protected]
-class Result:
- value: Value
- warning: Exception | None
-```
-
-This could just as easily be a Pydantic class or whatever is appropriate in
the situation, as long as it can hold the warning. If the warning is generated
during an additional or side task, we can use `Outcome[SideValue]` instead. We
do this, for example, in the type representing a linked committee:
-
-```python
[email protected]
-class LinkedCommittee:
- name: str
- autogenerated_keys_file: Outcome[str]
-```
-
-In this case, if the autogenerated keys file call succeeded without an error,
the `Outcome` will be an `OutcomeResult[str]` where the `str` represents the
full path to the autogenerated file.
diff --git a/notes/test-user-flows.md b/notes/test-user-flows.md
deleted file mode 100644
index 9023e82..0000000
--- a/notes/test-user-flows.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# Test user flows
-
-To test the ATR, here are some example command line and GitHub user flows.
-
-## Command line
-
-To install the `atr` command, use the [instructions in the client
`README.md`](https://github.com/apache/tooling-releases-client/tree/main?tab=readme-ov-file#quick-start),
or simply use `uv run --frozen atr` instead of `atr`.
-
-[Create a PAT](https://release-test.apache.org/tokens) using the UI, then
store the value in `atr` configuration.
-
-```shell
-atr set tokens.pat "$PAT_FROM_UI"
-```
-
-You can view the configuration file to check that the value is set. **This
will write secret values to stdout.**
-
-```shell
-atr config file
-```
-
-The following commands constitute roughly an entire flow, which will be
reflected in the UI. We are using `tooling-test-example` as the project name.
Don't forget to [create this or another
project](https://release-test.apache.org/project/add/tooling), or [use an
existing project](https://release-test.apache.org/committees) as applicable.
Use your ASF UID `@apache.org` instead of `example`.
-
-```shell
-atr release start tooling-test-example 0.1+demo
-
-atr upload tooling-test-example 0.1+demo example.txt ../example.txt
-
-atr check wait tooling-test-example 0.1+demo -i 25
-
-atr check status tooling-test-example 0.1+demo
-
-atr release info tooling-test-example 0.1+demo
-
-atr vote start tooling-test-example 0.1+demo 00002 -m [email protected]
-
-atr vote resolve tooling-test-example 0.1+demo passed
-
-atr distribution record tooling-test-example 0.1+demo NPM None react 18.2.0
False False
-
-atr release info tooling-test-example 0.1+demo
-
-atr announce tooling-test-example 0.1+demo 00003 -m [email protected] -s
Subject -b Body
-```
-
-When finished with an example flow, it is recommended that you delete the
version.
-
-```shell
-atr dev delete tooling-test-example 0.1+demo
-```
-
-If there is ever a problem with a JWT verification, try refreshing your JWT.
-
-```shell
-atr jwt refresh | wc
-```
-
-## GitHub actions
-
-We use [the
`tooling-asf-example`](https://github.com/apache/tooling-asf-example)
repository to check our GitHub actions.
-
-First, [start a new release in the ATR web
UI](https://release-test.apache.org/).
-
-You can then use the
[`build-and-rsync-to-atr.yaml`](https://github.com/apache/tooling-asf-example/actions/workflows/build-and-rsync-to-atr.yaml)
workflow to build Python wheel files and upload them to the ATR.
-
-Then, start a vote in the ATR web UI. This cannot be linked here because the
URL will depend on which project and version you use.
-
-Use the
[`resolve-vote-on-atr.yaml`](https://github.com/apache/tooling-asf-example/actions/workflows/resolve-vote-on-atr.yaml)
workflow to resolve the vote.
-
-Use the
[`record-distribution-on-atr.yaml`](https://github.com/apache/tooling-asf-example/actions/workflows/record-distribution-on-atr.yaml)
workflow to record an external distribution. The external distribution _must
exist_ on the distribution platform, because the ATR fetches real metadata.
-
-Use the
[`announce-release-on-atr.yaml`](https://github.com/apache/tooling-asf-example/actions/workflows/announce-release-on-atr.yaml)
workflow to announce the release and copy the files into the download area.
diff --git a/notes/trivial-changes.md b/notes/trivial-changes.md
deleted file mode 100644
index 7ad1b32..0000000
--- a/notes/trivial-changes.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# How to make a trivial change in ATR
-
-Sometimes it is necessary to make a trivial change in ATR to e.g. test pull
request workflows or lints.
-
-The recommended approach for doing so is to update the following timestamp:
-
-1761331837
-
-By changing the timestamp in this file, it makes it clear that the intent of
your change was to make a trivial change. Please also describe the wider intent
of the change in your comment message subject.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]