Skip to content

Releases: geolonia/pointsman

Pointsman 0.18.0

Choose a tag to compare

@dkastl dkastl released this 26 Oct 12:40
Immutable release. Only release title and notes can be modified.
9dec36e

Hardening of the Actions, the decide request, profile validation, MCP logins, the GitHub connector, the FIWARE bridge, and the GitHub and CodeRabbit facts (#235, #236).

For deployments:

  • Move ref in engine.json to the commit of v0.18.0. No migration, no new secrets, no new GitHub App permission or event.
  • MCP: people are recorded as github:<account id> instead of github:<login>. Everyone logs in again once (old grants are refused, and refreshing one fails with invalid_grant). Decisions recorded as github:<login> stay as they are and no longer count as the person's own in chains.
  • GitHub connector: the comment command now names the question: /pointsman <answer> <commit> <question>, where <question> is the first 8 characters of the decision id. The decision comment and the check run show the full command; a command without the question is refused with a note. Buttons are unchanged.
  • Decide: a ref with control characters, line separators or direction marks is refused with 400 invalid_request.

What changed:

  • deploy-watch and triage Actions: an answer for a test token (test: true) never counts. deploy-watch does not count its cancel; triage adds only the review label, and its action output is test.
  • Decide request: ref may not contain control characters, line separators or direction marks. replay-profile.mjs shows such characters in stored text (refs, answers, actions, rule text) escaped.
  • Repeated decide request (Idempotency-Key): the answer has the review as it is now: resolved with final_action and resolved_at once a person answered, superseded once a newer decision replaced it.
  • Profile validation: the check for profiles that require each other in a circle visits each profile once (it was exponential with shared requires).
  • MCP login: the OAuth grant keeps the GitHub account id, and the decision owner is github:<account id>. The login still names the person in feedback (by).
  • GitHub connector: a comment command must name the question it answers, so it never answers a question that replaced the one the person read. An answer is taken only when the current settings (answers.profiles) still offer it. copilot_review on a pull request with more than 1,000 reviews is recorded as failed for the commit instead of being checked again every 10 minutes.
  • FIWARE bridge: a retry after a person resolved the review writes it as resolved with their action (the result, the Decision entity, also one left pending by the first try, and the Task). A retry of a superseded decision writes nothing.
  • github_release: a changed package.json is also read at the head, and must differ only in its top-level "version"; a dependency named version no longer counts.
  • github_checks: two required workflows with the same path from another repository or ref fail the fact (error). The same workflow required by more than one ruleset counts once.
  • CodeRabbit paid_for_head: an edited paid-review comment counts from its last edit, and only when its author made that edit.
  • CodeRabbit rebase_only: line numbers are compared too. In a file the base branch changed between the two commits, each approved hunk is followed through the base's own change and must land where the head's hunk is; a hunk on lines the base changed, or a base that is not ahead of the old one, gives no value.

Pointsman 0.17.2

Choose a tag to compare

@dkastl dkastl released this 25 Oct 15:48
Immutable release. Only release title and notes can be modified.
v0.17.2
b1ad3e6

FIWARE bridge: a decision a person still checks is always treated as pending (#232).

For deployments:

  • Move ref in engine.json to the commit of v0.17.2. No migration, no new secrets, no new GitHub App permission or event.
  • FIWARE bridge: a route with task now also opens a Task for an action whose review is pending even when task.actions leaves it out.

What changed:

  • FIWARE bridge: an answer with review: {status: pending} (an action in the profile's people_check) counts as checked by a person, whatever the route's reviewActions say. The result and the Decision entity get reviewStatus: pending, the final action waits for the person, and a route with task opens a Task for it. Before, a route whose reviewActions left out that action wrote it as final. reviewActions now only adds actions to check (for engines or profiles that report no review); any other review value falls back to the old rule.
  • FIWARE bridge, work orders: a result with reviewStatus: pending can be resolved by a work order also when its action is not in the route's reviewActions.

Pointsman 0.17.1

Choose a tag to compare

@dkastl dkastl released this 25 Oct 14:52
Immutable release. Only release title and notes can be modified.
v0.17.1
f783c0b

Hardening of facts, connectors and Actions (#229).

For deployments:

  • Move ref in engine.json to the commit of v0.17.1. No migration, no new secrets, no new GitHub App permission or event.
  • FIWARE bridge: a profile with a question named like a field of the result (see below) now gets nothing written; rename the question.

What changed:

  • GSI facts, gsi-shelters-flood: a geometry whose box leaves the tile grid (at or near a pole, or at or across the 180° meridian) is refused: the fact is missing (error), and no tile is read.
  • github_bump: a changed lockfile line with a backslash (an escape such as \u0065 or \/, in a package-lock.json or a pnpm-lock.yaml) gives registry_changed true. Peers in a pnpm-lock.yaml version are taken off in one pass, also when deeply nested; results for usual lockfiles are the same.
  • CodeRabbit facts: the editors are read with each comment's and review's text; when that text differs from the copy read before (an edit between the two reads), the fact is missing, as for a comment someone else edited.
  • GitHub connector: a recorded approval that is not in the review list (which reads up to 1,000 reviews) is read by its id and dismissed if it still stands; when that read fails, the record stays and the next run tries again.
  • FIWARE bridge: after a 409 on resolving a review, the final action is written and the Task completed only when Pointsman has the review resolved with the same action; a review still pending is tried again (not when its profile version is gone), and one closed as superseded is reported.
  • FIWARE bridge: an answer whose name, or <name>Probability, is a field of the result (value, inputHash, decision, reviewStatus and the others, or an NGSI-LD one such as observedAt) is refused: nothing is written for that decision, the error says which question to rename, and there is no retry. A profile with a question named like this needs it renamed; the entity's next change is then decided again (#228).
  • deploy-watch and triage Actions: an answer a person still checks (review: {status: pending}, from people_check) does not count: deploy-watch does not count such a cancel, and triage adds only the review label.

Pointsman 0.17.0

Choose a tag to compare

@dkastl dkastl released this 25 Oct 12:41
Immutable release. Only release title and notes can be modified.
v0.17.0
b08aaf3

The GitHub connector can ask Copilot for a review (#220). Nothing changes until a deployment maps a decision action to the new action.

For deployments:

  • Move ref in engine.json to the commit of v0.17.0. No migration, no new secrets, no new GitHub App permission or event.
  • To use it: map a decision action to { "do": "copilot_review" } in GITHUB_CONNECTOR actions, only where your organization allows Copilot code review for every repository in repos. Limit how many commits get a review with skip_drafts and a rule on github_copilot (for example its reviews count), and keep a Copilot budget in the organization. Not yet tried with a GitHub App (only with github-actions[bot]): check the first request when you switch it on.

What changed:

  • GitHub connector, copilot_review (#225): requests a review from Copilot with one fixed reviewer and no settings. At most one Copilot review per head commit, whoever asked (another profile or a person; Copilot known by its account id). Done only when GitHub's answer lists Copilot, otherwise shown on the check run as failed and not tried again for that commit. The pull request is read again right before, and nothing is asked if its head moved. Never for a fork's or a closed pull request. When the connector cannot tell whether Copilot was already asked, it asks nothing and looks again 10 minutes later.
  • Not built from #220: CodeRabbit commands and paid reviews, because CodeRabbit ignores commands from a GitHub App. A person or an agent still posts them.
  • Threat model: amended for copilot_review (Q44 to Q47); re-bound to this release in a separate pull request.

Pointsman 0.16.0

Choose a tag to compare

@dkastl dkastl released this 25 Oct 09:12
Immutable release. Only release title and notes can be modified.
v0.16.0
8eea43d

Asking a person inside the pull request (#147): the engine can close a waiting review, the GitHub connector keeps one question per head commit and acts on the person's answer, and, where a deployment switches it on, a person with write access answers from the pull request itself. Nothing changes until a deployment switches answers on.

For deployments:

  • Move ref in engine.json to the commit of v0.16.0. No migration, no new secrets. The engine is deployed before the connector, as the config template's deploy workflow does: the connector calls the engine's new get, close and (for answers) resolve, as the INTERNAL_CLIENT client over the internal call, so INTERNAL_CLIENT must list the connector's profiles (as before). With an older engine, over the internal call a run is tried again until the engine is updated; over HTTPS a missing route means the question is decided again.
  • Without answers in GITHUB_CONNECTOR, the GitHub App needs no new permission and no new event. A profile that asks a person (people_check) now keeps one question per head instead of opening a new review on every run, and the connector acts on the answer.
  • To switch answers on: add answers to GITHUB_CONNECTOR; give the connector's GitHub App Contents: Read (for the last pusher) and subscribe it to Check run; for the /pointsman command also Issues: Read and Issue comment; list people_answers in the profiles answered this way; keep the ruleset's "dismiss stale approvals" and "approval of the most recent push"; switch it on only where everyone with write access may approve. Not yet tried against GitHub itself: whether updating a check run with no actions removes its buttons, and whether requested_action events need the Check run subscription; check both when first switching it on.

What changed:

  • Engine (#221): POST /v1/reviews/{id}/close closes a pending review as superseded. Only the client that made the decision may do it: no callback, a later resolve gets 409, and the review leaves the queue. InternalEngine gains get, resolve and close, running the same code as the HTTPS routes after the token check.
  • GitHub connector, a question per head (#221): a decision that waits for a person is kept, per head commit and profile, and read back instead of decided again. The person's answer (final_action) is acted on with the same guards: an approval only on the unchanged head, once per head. The question is closed and asked anew when what it rests on changes: a push, the title or description, the base, the draft state, the run settings, the mapped actions, or what a required decision says. Closing a question never holds up a run: a failed close is tried again at most once every 5 minutes, up to 10 times within 24 hours.
  • GitHub connector, answers in the pull request (#222), off by default:
    • buttons on the check run, and a /pointsman <answer> <12 characters of the head> command (only with "command": true);
    • each answer is checked: by a person with write access, not the author, not the last pusher, on the unchanged head, while the question is still open;
    • caps per pull request and clock hour;
    • the answerer is recorded as github:<login> (<id>) and shown as "answered by ", without a mention;
    • a command whose 12 characters start more than one commit of the pull request is refused.
  • Threat model: amended for #221 and #222 (P-CONNECTOR-ANSWER-AUTHORIZED, P-CONNECTOR-ANSWER-BOUND, P-CONNECTOR-COMMAND-EXACT, the Answerer, R-CONNECTOR-ANSWERS), accepted; it is re-bound to this release in a follow-up, which also covers 0.15.0.
  • Repository: CodeRabbit reviews only when asked (#219).

Known limits: an answer is picked up on the pull request's next run; a new profile version on the same head does not re-ask an open question; an answer given after the title or description was edited, before the next run, is resolved in Pointsman but not acted on (fails safe); if a run stops between a decision and saving its question, that earlier review is never closed; a closed review and one replaced by a chained decision both read superseded, and the time of a close is not stored; about 10 accounts can use up the hour's answer reads on one pull request; pull requests from forks cannot be answered in the pull request.

Pointsman 0.15.0

Choose a tag to compare

@dkastl dkastl released this 24 Oct 10:15
Immutable release. Only release title and notes can be modified.
v0.15.0
6e91056

Fixes in the GitHub connector and the CodeRabbit facts, found with the threat model's amendment for v0.14.2 (#211). A minor release because a connector setting that loaded until now can be refused.

For deployments:

  • Move ref in engine.json to the commit of v0.15.0. No migration, no new secrets, no new permissions.
  • Check GITHUB_CONNECTOR first: a profile with runs.<profile>.once_per_head and an action mapped to approve or keep_approval is now a config error (the connector answers 500 and logs the setting). Remove once_per_head from that profile, or the approving action. The docs already said not to combine them.

What changed:

  • GitHub connector, once_per_head with an approval (#212, #216): refused. A kept decision is not asked again on the same commit, so it never withdrew its approval after a failed check or a change request.
  • GitHub connector, its own reviews (#213, #216): a review event about one of its own approvals, or their dismissal, sent by its own bot, no longer starts a run (each one asked every profile again). The connector remembers the ids of the reviews it gave (the newest 50 per pull request). A person's dismissal of its approval, another app's review or dismissal, and an event that comes before the approval's id is recorded still start a run. The run that approves or dismisses reads the reviews again and draws the decision comment.
  • CodeRabbit facts, ignored (#215, #217): CodeRabbit's summary is left out of the description only as a whole block, from its start to its end marker, as the connector already does. A lone start marker no longer hides the text after it.
  • Docs: docs/modules.md says how the CodeRabbit facts find earlier decisions (#214, #217); the deploy guide covers migrations on updates and connecting the GitHub connector, and the PR-review guide a Dependabot group (#210); Japanese versions of the four English-only pages (#208); the site's layout (#205, #206, #207, #209).
  • Threat model: bound to v0.14.2, covering what shipped since v0.12.0 (#211).

Known limit: the decision comment now relies on the approving run's own re-read of the reviews. If GitHub's review decision lagged behind the approval at that moment, the comment's station stays behind until the next event.

Pointsman 0.14.2

Choose a tag to compare

@dkastl dkastl released this 23 Oct 23:33
Immutable release. Only release title and notes can be modified.
v0.14.2
a5cf423

A fix for the token script (#202), and the documentation site at https://pointsman.net (#168, #169, #203).

For deployments:

  • Move ref in engine.json to the commit of v0.14.2. No migration, no new secrets, no new permissions. No change in behaviour in the engine or the connectors (the MCP tool definitions moved to src/mcp-tools.ts, so the site can list them).

What changed:

  • tokens.mjs rotate --keep-old printed a revoke command without --config and with scripts/tokens.mjs as the path. Run as printed in a config repository, it used the default configuration (and could revoke in another KV namespace, so the old token stayed valid) and a path that does not exist there. It now prints the path it was started with, --local or --remote, and --config as given, quoted for the shell.
  • Documentation site: https://pointsman.net, with the docs under /docs/ in English and Japanese (Starlight), a reference generated from the code (the engine version is added when the site is built, so a release changes no committed page), an AI and agents page with llms.txt and llms-full.txt, and an "About this site" page. Several pages are still short planned pages. The old address geolonia.github.io/pointsman/ redirects there, keeping the path.
  • Repository: pnpm docs:check and pnpm site:build, a required CI job "Build the docs", the site as a workspace package (docs-site/), and the GitHub Pages workflow now only runs by hand to publish the redirect.

Pointsman 0.14.1

Choose a tag to compare

@dkastl dkastl released this 23 Oct 14:09
Immutable release. Only release title and notes can be modified.
v0.14.1
d0d2ddb

The decision comment's train shows where the pull request really is (#200).

For deployments:

  • Move ref in engine.json to the commit of v0.14.1. No migration, no new secrets, no new permissions.
  • For every deployment with the connector: each run on an open, non-draft pull request now makes one GraphQL read (the review decision and the last 100 reviews), with or without the comment, because check runs draw the line too. A second one only in runs that approve or dismiss.

What changed:

  • Approved comes from GitHub's own review decision (reviewDecision, what the merge box shows under the repository's rules): the train is at "approved" only when it is APPROVED, so an approval counts exactly where the ruleset counts it (also an AI review service's), and a drive-by approval never does. CHANGES_REQUESTED, REVIEW_REQUIRED and no review rule at all never show it. The caption says "approved by Pointsman on this commit" when the app's own latest review approves the head, "approved on this commit" when someone's does, else "approved".
  • Reviewed: any review of the current head by someone other than the author (dismissed and pending ones don't count).
  • Merged and closed: on closed, the comment gets one last update, without asking Pointsman: the train at "merged", or "closed without merging". A reopen runs as usual. The connector accepts closed events only when the comment is on.
  • Filled stations: the train's station and every station before it are filled.
  • No names or review text in the comment.
  • Fail safe: if the reviews can't be read (an error, a rate limit, a push in between), the run goes on and the train stays where the last read put it on this head, else at "ready". After the app dismissed its own approval, a failed read never shows "approved".

Pointsman 0.14.0

Choose a tag to compare

@dkastl dkastl released this 23 Oct 12:52
Immutable release. Only release title and notes can be modified.
v0.14.0
ab5ec05

The GitHub connector can show its decisions inside the pull request: one comment, railway style (#195, #196).

For deployments:

  • Move ref in engine.json to the commit of v0.14.0. No migration, no new secrets.
  • The decision comment is off unless GITHUB_CONNECTOR sets "comment": { "profiles": [...] } (1 to 10 profiles, all from profiles). Keys of "signals" must be profiles in profiles; the config check refuses anything else. It needs the connector app's Pull requests: Read and write; the tokens ask for it only when the comment or an action is on.
  • For every deployment: check-run titles now start with the signal, for example 🟢 approve or 🔴 review (shadow). The action word, (shadow) and external_id stay, and the details now show the line and the switch.

What changed:

  • The decision comment: one comment per pull request, updated in place, never a new one per decision. A table with each chosen profile's signal (always with a word), decision and rule; a track with stations (draft, ready, reviewed, approved, merged) and ▲ under the station where the pull request is (draft, ready, or approved while the app's own approval of the commit stands); and per profile a set of points: the facts read or missing, the AI answers, the track taken (action ← rule N, or the default) and the one not taken. It is found again only by its marker together with the app's own bot login; a person's or another app's comment with the marker is never touched. At most one write per run, only when the text changed. When nothing is left to show, an existing comment changes to a short neutral text.
  • Signals: GITHUB_CONNECTOR → "signals" maps a profile's actions to red, yellow or green, optionally with a word (1 to 40 letters, digits, spaces and , . ' ( ) -). Defaults: review and ask-person red; wait, in-progress, queue and retry yellow; approve, pass and done green; any other action yellow "decided: "; a decision a person still checks red.
  • Text art: every rail starts at column 0 and is only box characters up to where its text starts (names, rules and reasons come after the rails), no emoji inside the art, at most 60 columns. In a font that draws box characters two columns wide the rails stay consistent; labels indented with spaces may drift.
  • No pull-request text in the comment: profile and action names are checked names, fact reasons are reduced to plain characters, everything sits in code blocks. Test decisions and invalid answers never put anything in it (an approval they withdraw removes its row).
  • Failures never stop the run or the actions: a refused write (for example no permission) is noted on the check runs and not tried again until the text changes; a busy or rate-limited GitHub (5xx, 429, a rate-limit 403) is tried again on the next run.
  • The check-run summary now cleans the engine's fact reasons the same way, and fact names of 65 to 100 characters are counted (cut) instead of left out.

Pointsman 0.13.1

Choose a tag to compare

@dkastl dkastl released this 23 Oct 11:40
Immutable release. Only release title and notes can be modified.
v0.13.1
719ea9d

The GitHub connector checks the engine's answer before it acts, and never acts on a test decision (#193).

For deployments:

  • Move ref in engine.json to the commit of v0.13.1. No migration, no new secrets, no new permissions.

What changed:

  • The engine's answer is checked once, for both the HTTP adapter and the service binding: decision_id (a UUID), action (an action name), profile and ref (the ones asked for), profile_version, rule, and facts, review and test when present must have the right shape. A decision kept for once_per_head is checked again before it is reused. An answer that does not fit is an invalid answer.
  • Test decisions are never acted on: a decision with test: true (made with a test token) does nothing.
  • For an invalid answer or a test decision the connector does nothing (no approve, keep_approval, comment, label or reviewer request), keeps nothing, sends nothing on through requires and schedules no recheck. In a profile that maps approve, an approval of the head commit is withdrawn, as for any decision that does not keep it. For a test decision the check run also says to use a token made without --test. The check run is neutral and says invalid answer: nothing done or test decision: nothing done; the log names the field, never its value. It is not retried; the next event asks again.
  • A 2xx body that is not JSON (HTTP) or not an object (binding) used to be retried; it is now an invalid answer.