active_sanction 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -0
- data/CONTRIBUTING.md +69 -5
- data/README.md +1 -0
- data/lib/active_sanction/storage/meta.rb +18 -0
- data/lib/active_sanction/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b6c9a31bd72dfdc43d5614499a19aab837b55996b9644ae145b89da18b93bea6
|
|
4
|
+
data.tar.gz: 40cbea7b7fcf458307171ca953fb61864dce06da7733ece2ac17e4d27a43215d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 892209a20496c2eea1185776a83725cb89ae6c7b40ba2385becf7870b78d8e1a6cf88734e29afec40153418dfa73ac275a3270b0bb16a80e56c3de6605e58652
|
|
7
|
+
data.tar.gz: e3330620e4c4f6c31c6a7e0c58b53bda9972628e9d6965798d56f666f7301b83ccc2edb42931d15b18b161c9480df96b5147edf0e94b77461e90e0958944ed46
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,71 @@ algorithms or the scorer could move a score. **A change that moves `MATCHER_VERS
|
|
|
13
13
|
called out here as such**, because it is the one kind of change that alters what a past
|
|
14
14
|
screening decision would come out as today.
|
|
15
15
|
|
|
16
|
+
## [Unreleased]
|
|
17
|
+
|
|
18
|
+
Nothing yet.
|
|
19
|
+
|
|
20
|
+
## [1.0.1] - 2026-09-14
|
|
21
|
+
|
|
22
|
+
A packaging and release-tooling release. **Nothing about screening changes**: no behaviour
|
|
23
|
+
in `lib/` moved, `MATCHER_VERSION` is unchanged at `1`, and a name scores today exactly what
|
|
24
|
+
it scored under 1.0.0.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Releases publish themselves from a tag**, through
|
|
29
|
+
[`.github/workflows/release.yml`](.github/workflows/release.yml). Pushing `v1.2.3` re-runs
|
|
30
|
+
the three gates against the tagged tree, checks that the tag and `VERSION` agree, that the
|
|
31
|
+
tag is an ancestor of `main` and that the changelog has a section for it, then builds the
|
|
32
|
+
gem, publishes it and writes the GitHub release from that section. A tag failing any of
|
|
33
|
+
those publishes nothing.
|
|
34
|
+
|
|
35
|
+
**No API key exists to leak.** It authenticates by
|
|
36
|
+
[trusted publishing](https://guides.rubygems.org/trusted-publishing): a short-lived OIDC
|
|
37
|
+
token, verified by rubygems.org as naming this repository and this workflow file, exchanged
|
|
38
|
+
for a credential that expires with the job. The alternative is a long-lived key in a public
|
|
39
|
+
repository's settings, one leak away from someone else publishing under this gem's name --
|
|
40
|
+
and unlike a bad deploy, a bad gem is already installed by the time anyone could be warned.
|
|
41
|
+
Same reasoning that keeps a service-account key out of the documentation deploy.
|
|
42
|
+
|
|
43
|
+
The gem pushed is the gem that was verified, carried between the two jobs as an artifact
|
|
44
|
+
rather than rebuilt -- a second build is a second thing, however identical it looks.
|
|
45
|
+
|
|
46
|
+
**The publish is confirmed against rubygems.org** (#136), because `gem push` exiting 0 says
|
|
47
|
+
the upload was accepted rather than that a `bundle install` will find the version. The job
|
|
48
|
+
that writes the GitHub release waits on that confirmation, so a version rubygems.org did not
|
|
49
|
+
end up serving is never announced.
|
|
50
|
+
|
|
51
|
+
- **A gem badge on the README** (#136), read live from rubygems.org rather than generated into
|
|
52
|
+
a file. What it states is what is installable, which is a different question from what was
|
|
53
|
+
last tagged -- and a version written into the repository would be stale the moment the next
|
|
54
|
+
one published. Same argument as #104, applied to the one fact about this gem that lives
|
|
55
|
+
somewhere else entirely.
|
|
56
|
+
|
|
57
|
+
- **A release can be cut from the Actions tab**, without tagging by hand (#139). The
|
|
58
|
+
workflow's "Run workflow" button takes a tag and a checkbox: ticked, it runs every gate
|
|
59
|
+
against `main` and writes the tag only once they have all passed. That is the safer order
|
|
60
|
+
than `git tag && git push`, which makes a tag public before anything has checked the tree
|
|
61
|
+
under it — and this workflow will not move a tag somebody may already have fetched, so the
|
|
62
|
+
repair for that is a new version number. A tag it writes is annotated but unsigned; push
|
|
63
|
+
the tag yourself when you want your own signature on it. See
|
|
64
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md#releasing).
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- **`rake canary:refresh` regenerates the catalogue page's data as well as the baselines.**
|
|
69
|
+
`site/src/data/sources.json` is derived from `.github/baselines` (#104), so accepting new
|
|
70
|
+
numbers without rebuilding it left the two disagreeing and
|
|
71
|
+
[`spec/site_sources_data_spec.rb`](spec/site_sources_data_spec.rb) red. The rolling
|
|
72
|
+
baseline pull request the canary opens had failed on this every run since it started
|
|
73
|
+
opening one, on all six Rubies. Chained onto the task rather than added as a step to each
|
|
74
|
+
caller: a derived file that callers have to remember to rebuild is stale by the third
|
|
75
|
+
caller.
|
|
76
|
+
|
|
77
|
+
- **The canary signs its baseline commit off.** Nothing exempts a bot from
|
|
78
|
+
[`.github/workflows/dco.yml`](.github/workflows/dco.yml), which skips merge commits and
|
|
79
|
+
nothing else, so the rolling pull request failed the DCO check as well.
|
|
80
|
+
|
|
16
81
|
## [1.0.0] - 2026-09-13
|
|
17
82
|
|
|
18
83
|
The first release. Everything below is in it.
|
|
@@ -535,4 +600,6 @@ summarized here because they are what a reader of a first release most needs:
|
|
|
535
600
|
- Recall at the default threshold is 0.939 overall on the labeled set, and every record this
|
|
536
601
|
version misses is named in the committed accuracy report.
|
|
537
602
|
|
|
603
|
+
[Unreleased]: https://github.com/Babystep-Technologies/active_sanction/compare/v1.0.1...main
|
|
604
|
+
[1.0.1]: https://github.com/Babystep-Technologies/active_sanction/compare/v1.0.0...v1.0.1
|
|
538
605
|
[1.0.0]: https://github.com/Babystep-Technologies/active_sanction/releases/tag/v1.0.0
|
data/CONTRIBUTING.md
CHANGED
|
@@ -232,11 +232,75 @@ comment restating the name would be noise.
|
|
|
232
232
|
|
|
233
233
|
## Releasing
|
|
234
234
|
|
|
235
|
-
`bundle exec rake install` installs the gem locally.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
version
|
|
239
|
-
|
|
235
|
+
`bundle exec rake install` installs the gem locally.
|
|
236
|
+
|
|
237
|
+
A release is a tag. Bump `VERSION` in
|
|
238
|
+
[`lib/active_sanction/version.rb`](lib/active_sanction/version.rb), move the
|
|
239
|
+
`Unreleased` section of [`CHANGELOG.md`](CHANGELOG.md) under the new version
|
|
240
|
+
with its date, and merge that.
|
|
241
|
+
|
|
242
|
+
Then the tag, which you can let the workflow write or write yourself.
|
|
243
|
+
|
|
244
|
+
**From the Actions tab**, which is the shorter path and the safer order. Open
|
|
245
|
+
[`Release`](https://github.com/Babystep-Technologies/active_sanction/actions/workflows/release.yml),
|
|
246
|
+
press **Run workflow**, enter `v1.2.3`, and tick **Create the tag on main**.
|
|
247
|
+
Every gate runs against `main` first, and the tag is written only once they
|
|
248
|
+
have all passed — so a release that turns out not to be publishable leaves no
|
|
249
|
+
tag behind.
|
|
250
|
+
|
|
251
|
+
**Or from a terminal**, which is the path to take when you want your own
|
|
252
|
+
signature on the tag:
|
|
253
|
+
|
|
254
|
+
$ git tag -s v1.2.3 -m "Release 1.2.3"
|
|
255
|
+
$ git push origin v1.2.3
|
|
256
|
+
|
|
257
|
+
The cost of that order is that the tag is public before anything has checked
|
|
258
|
+
the tree under it. If a gate then fails, the tag stays where it is: this
|
|
259
|
+
workflow will not move a tag somebody may already have fetched, so the repair
|
|
260
|
+
is a new version rather than a retagged one.
|
|
261
|
+
|
|
262
|
+
Either way, [`.github/workflows/release.yml`](.github/workflows/release.yml)
|
|
263
|
+
does the rest. It re-runs the three gates against the tree being released,
|
|
264
|
+
checks that the tag and `VERSION` agree, that the commit is on `main`, and
|
|
265
|
+
that the changelog has a section for it — then builds the gem, publishes it to
|
|
266
|
+
[rubygems.org](https://rubygems.org), confirms rubygems.org is serving that
|
|
267
|
+
version, and writes the GitHub release from that changelog section. A release
|
|
268
|
+
that fails any of those checks publishes nothing, and a push rubygems.org did
|
|
269
|
+
not end up serving is never announced (#136).
|
|
270
|
+
|
|
271
|
+
**Leave the box unticked to re-run a publish.** A dispatch with `Create the
|
|
272
|
+
tag` unticked publishes a tag that already exists — one pushed before this
|
|
273
|
+
workflow did, or one whose publish failed after the tag was public — and
|
|
274
|
+
nothing in this workflow ever moves or deletes a tag. Ticking the box against
|
|
275
|
+
a tag that already exists is not an error either; it publishes that tag and
|
|
276
|
+
says it created nothing.
|
|
277
|
+
|
|
278
|
+
**A tag the workflow writes is annotated but not signed.** It has no key of
|
|
279
|
+
yours, and signing with a machine key would say less than saying nothing. The
|
|
280
|
+
tag names the commit every gate ran against, and the provenance that matters
|
|
281
|
+
for what users install is on the other side: the gem is published by [trusted
|
|
282
|
+
publishing](https://guides.rubygems.org/trusted-publishing) from this
|
|
283
|
+
repository and this workflow file. Sign the tag yourself, with the terminal
|
|
284
|
+
path above, when you want the tag to carry it too.
|
|
285
|
+
|
|
286
|
+
The [gem badge](https://rubygems.org/gems/active_sanction) at the top of the
|
|
287
|
+
README reads from rubygems.org rather than from anything in this repository,
|
|
288
|
+
so it states what is installable rather than what was last tagged.
|
|
289
|
+
|
|
290
|
+
**Nobody needs a RubyGems API key, including the person tagging.** The
|
|
291
|
+
workflow authenticates by [trusted
|
|
292
|
+
publishing](https://guides.rubygems.org/trusted-publishing): it mints a
|
|
293
|
+
short-lived OIDC token, rubygems.org verifies the token names this repository
|
|
294
|
+
and this workflow file, and hands back a credential that expires with the job.
|
|
295
|
+
There is no publishing secret in this repository's settings, for the same
|
|
296
|
+
reason there is no service-account key for the documentation deploy. It is
|
|
297
|
+
configured once, on rubygems.org, under the gem's **Trusted Publishers**:
|
|
298
|
+
owner `Babystep-Technologies`, repository `active_sanction`, workflow
|
|
299
|
+
`release.yml`, environment `rubygems`.
|
|
300
|
+
|
|
301
|
+
`bundle exec rake release` — the manual path that tags, pushes and publishes
|
|
302
|
+
in one step — still exists and still works for anyone with push rights to the
|
|
303
|
+
gem. It is not how this gem is released, and using it skips every check above.
|
|
240
304
|
|
|
241
305
|
`MATCHER_VERSION` in the same file is bumped on a different occasion and for
|
|
242
306
|
a different reason — whenever a change to the normalizer, the index, the
|
data/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# ActiveSanction
|
|
6
6
|
|
|
7
|
+
[](https://rubygems.org/gems/active_sanction)
|
|
7
8
|
[](https://github.com/Babystep-Technologies/active_sanction/actions/workflows/ci.yml)
|
|
8
9
|
|
|
9
10
|
**[Full documentation, guides and the source catalogue →](https://babystep.tech/active_sanction/)**
|
|
@@ -110,6 +110,24 @@ module ActiveSanction
|
|
|
110
110
|
# per source: a list that failed to refresh keeps its previous snapshot,
|
|
111
111
|
# which is the right call and only safe if the age of what is being
|
|
112
112
|
# screened against is visible.
|
|
113
|
+
#
|
|
114
|
+
# **Accurate to a second, and never fewer than the seconds that have
|
|
115
|
+
# passed.** `fetched_at` is stored to the second -- Snapshot#time!
|
|
116
|
+
# truncates it, so that a stored snapshot reloads equal to the one that
|
|
117
|
+
# was written -- so the instant of the fetch is known only to lie
|
|
118
|
+
# somewhere inside the second this names. What comes back is therefore
|
|
119
|
+
# the largest age consistent with what was recorded, which is the
|
|
120
|
+
# direction a staleness measure has to err in: an answer that is at most
|
|
121
|
+
# a second pessimistic is a report that nobody acts on, and one that is
|
|
122
|
+
# optimistic is a list being screened against that is older than it
|
|
123
|
+
# claims.
|
|
124
|
+
#
|
|
125
|
+
# The practical consequence, and the reason it is written down: a list
|
|
126
|
+
# fetched microseconds ago reports 0 or 1, according to whether the run
|
|
127
|
+
# crossed a second boundary on its way here. Both mean "just fetched" --
|
|
128
|
+
# see Sync::Result#age_in_words, which is what a summary table shows --
|
|
129
|
+
# and nothing should assert on the exact number of a fresh sync, because
|
|
130
|
+
# that is a fact about the clock rather than about this library.
|
|
113
131
|
sig { params(now: Time).returns(Integer) }
|
|
114
132
|
def age(now = Time.now) = now.to_i - fetched_at.to_i
|
|
115
133
|
|
|
@@ -6,7 +6,7 @@ module ActiveSanction
|
|
|
6
6
|
# new source adapter, a storage fix or a documentation release -- none of
|
|
7
7
|
# which change what a name scores. MATCHER_VERSION, below, is the one that
|
|
8
8
|
# answers that question.
|
|
9
|
-
VERSION = "1.0.
|
|
9
|
+
VERSION = "1.0.1"
|
|
10
10
|
|
|
11
11
|
# Which matching pipeline scored a decision, stamped onto every MatchResult
|
|
12
12
|
# and bumped whenever a change to the normalizer, the index, the similarity
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_sanction
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marshall Shen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: csv
|