Skip to content

Releases: medici-finance/assay

v1.0.39

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:33
Immutable release. Only release title and notes can be modified.
08d194b

Highlights

Added

  • A new stdlib-only Go module, forgeread, is the importable fact reader: one narrow Reader API for the open issues of an explicit repository set, with the three-state result (read, known empty, unavailable) made a type. A repository appears exactly once, as data or as unavailable; a provider that keeps paginating past the walk ceiling is reported as truncated rather than as a short list; an envelope with an unknown schema is refused. Offline and frozen-result readers live in the root package, which imports no HTTP client, no process launch and no subpackage. The Go API and the JSON envelope are versioned separately.
  • Draft unified non-CI architecture, shared context-graph design, future-aware authoring delivery scope and verifier-first migration proposal; implementation and activation remain separate work.
  • Every exit the intake desk takes now lands one structured intake-exit-v1 record: scanloop run appends a mechanical record per landed exit, the new scanloop land verb records a judgment exit for a parked item, and statusgen --intake-exits --json exports the intake register's stamped entries with a stamped/unstamped/unmapped summary. Intake entries gain an optional triaged / triaged-by / triager-tier stamp, linted against a closed role set so no person's login can enter it. The record file holds one exit per inbound event (item plus its opened time): the drain's EMITTED report prints the scanloop land --opened command for each parked item, so an update parked after the same issue's earlier new-issue exit is recordable. A refused or unwritable record never costs an exit its audit land line or another batch member its exit, and land refuses a session that did not declare its loop.
  • Extend the proposal with resumable workspace retirement, bounded Git maintenance, durable feedback reevaluation, observable loop guards, governed context updates and sustained-work qualification.
  • Recording costs no extra forge reads: the Forge decorator records from the ChecksAtHead and rollup results the tools already fetch, and a recorder failure never changes what the read returns.
  • The desk tools now keep a CI check history: one ci-check-v1 line per finished check run or terminal commit status they read (repo, head SHA, PR, check name, attempt, conclusion, duration), so flake rate and check duration can be measured later. Check output, URLs and who posted a check are never recorded.
  • The history lives in the local desk state directory as ci-checks.jsonl, rotated daily, never committed and never deleted by the tools; deskkit.LoadCIChecks reads it back de-duplicated.
  • deskread issues marks a truncated repository with an optional class field on its unavailable entry (additive; the envelope schema number is unchanged).

Fixed

  • The forge-neutral/33 brief's Verify table can now be witnessed after merge: rows 17 and 19 name the implementation commit and the brief's authoring base instead of a merge-base that resolves to HEAD on merged main, row 19 asserts on the consumers summary line rather than exit 0 alone, the unwitnessable GitLab live row is withdrawn into a note, row 4's name counts are corrected, and the origin of the 25-page GitLab ceilings is stated beside the constants.
  • The scan-override audit identity (deskkit.OverrideIdentity) now resolves to the accountable roster login instead of the raw OS account name: the new ASSAY_OS_USER_LOGIN_MAP roster key (osuser:login entries, an extension key — a malformed or off-roster value empties only that map, never the roster) binds a machine account to a trusted-human login, with the human-name map and the trusted-login set as further resolution steps. Resolved rows carry the observed OS account as <login>(os:<account>); an OS account nothing resolves still produces an audit row under a clearly-marked os:<username> fallback — the identity label degrades, the audit write never blocks.
  • muhar parallel sweeps (-j > 1) no longer discard every run as "baseline RED" when the swept module's go.mod carries a relative replace pointing outside the copied tree (for example tools/desk's replace … => ../../forgeread). Each worker's isolated copy now re-points those filesystem replacements to their absolute location in the source tree; in-tree, versioned and absolute replacements, and fixture go.mod files under testdata/, are copied unchanged. Mutations still land only in the copy.
  • tools/desk tests no longer touch the operator's live cell Go-cache. A test run started from a cell shell inherited ASSAY_GO_CACHE_POLICY and took the live cache's exclusive lock through deskdispatch's storage admission and cellprocess's launch custody, so production dispatch on the same machine returned storage-deferred while the tests ran (and the tests failed while production held it). Every package whose code links the managed cache now clears the cell's storage-admission variables in its TestMain (new test-support package internal/cachequiet), and a static guard fails any new cache-linking package that does not.

Changed

  • Make the parser-bypassing admission regression use a valid configuration directory and assert the intended refusal, so an earlier fixture error cannot mask a removed domain check. Keep its policy fixture inside the Go module so isolated mutation workers execute the admission checks instead of skipping them.
  • Preserve current main’s deskd custody behavior through the new command tree: defer roster reads until the selected cell is entered, including no roster echo on an earlier selector or attendance refusal.
  • The container build files copy forgeread/ beside the modules that resolve it.
  • The hourly board-reconcile job is live. The statusgen board workflow now runs reconcile on an hourly schedule in this repository only: it computes generated stream-README changes under a read-only token and publishes them as one draft pull request on board/reconcile, minting the board-writer App token only in the publish step. Its job tests now run in the board workflow's PR lint job.
  • The open-issue paging and mapping for GitHub and GitLab now live once, in forgeread/adapters, and desk-tools' forge methods delegate to it over their own authenticated transport. Credential resolution and host and repository validation stay in desk-tools; the delegated reader refuses any repository other than the one a credential was admitted for before it builds a request. Behaviour is unchanged.
  • The shared fact reader's CI controls are live. forge-surface-control now runs on forgeread/** changes and executes the module's tests, the ambient-token rule over forgeread/, the lower-layer scope check and statusgen's import-path guard. The statusgen board workflow now triggers on forgeread/**, and its corroboration guard archives the sibling forgeread/ module into the base tree, so a base that already carries the module builds against statusgen's relative replace.
  • cellctl now parses its command line with Cobra and resolves its per-run settings through the shared desk adapter. Every verb, flag and precedence rule is preserved, and every refusal is preserved except where the recorded decision DR-cellctl-cobra names the change (as measured against the pre-migration binary over the lines the compatibility page lists): a line of a shape the old parser refused (a flag or a lone - before the verb or ahead of a verb's positionals, --cells-root anywhere but first or in another spelling, the single-dash spelling of a long flag outside scratch) is refused again, exit 3, before anything runs, and a relative --cells-root is refused first on every line, as before. cadence, cache and comms still compare --confirm-stopped as an exact word in its place, check and deskd still read the words after their cell by position, the first --kind on a desk, up or show line ahead of a bare -- is still the kind (also in another flag's value position, and refused there when it has no value or an unknown one) while a later --kind is skipped unread, and new still prints its usage for -h or --help anywhere on its line and takes a value flag left last with no value as empty. --help, <verb> --help and --version read no cell or credential (and the roster only to refuse a relative --cells-root), --flag=value and -- are accepted, and a parse failure carries Cobra's wording with the usage exit code (3, including scratch, which used 2, and desk, which used 1 for a flag-shaped word in its cell's place). A false help flag (--help=false, and -h=false on scratch) is read as no help and the line runs, under entries 4 and 9. The differences are listed in docs/cellctl-cli-compat.md against DR-cellctl-cobra, and the generated command list is docs/cellctl-cli-reference.md. The hidden shell-completion entrypoints are refused like any unknown command.
  • forge-ban.sh counts forgeread/ as its own tree (forgeread sites: N) and exits non-zero when it is above zero; the desk and statusgen columns stay advisory.
  • statusgen --scan-issues now derives gate: human on a new issue placeholder when the issue already carries the risk:high label (risk:med and risk:low do not gate). The intake-desk skill's scored-triage section says the gate is derived once at first write, and what a triage session does when the placeholder came first.
  • statusgen reads the shared types: its default forge reader is the library's offline reader, and its online reads still run the deskread verb.

assay release v1.0.39 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built sepa...

Read more

v1.0.38

Choose a tag to compare

@github-actions github-actions released this 11 Oct 06:06
Immutable release. Only release title and notes can be modified.
b78b495

Highlights

Added

  • Maintenance requires native Git hook inventory and holds repositories with listed relevant entries or unverifiable configuration, preserving existing hooks. Unrelated events remain usable.
  • deskwt maintain plans and applies bounded offline ref packing and commit-graph updates, with a shared-repository lock, attempt cadence, and before/after inventory. Object reclamation remains held until borrowed-object ownership can be established.
  • deskwt prune now garbage-collects stale local branches in the same sweep (Step C): a branch is collected only when its content is provably on refs/remotes/origin/main — ancestry-merged (which covers fresh, never-used handles) or cherry-clean (every unique commit's patch-id already in the mainline, the squash-merge case) — and never main/master, a branch checked out in any worktree, or anything whose proof cannot be completed. Deletes are compare-and-delete against the proven sha (no force verb), live sweeps print per-class counts only, and --no-branches / --branches-only split the pass from the worktree arms for cadence control. (#2504)
  • deskwt prune now pressure-checks every marked per-cell Go cache root under the cells root on each sweep — the cadence backstop for the managed caches that were previously checked only at launch and dispatch. Enforcement keeps the package's own semantics (reclaim only over the byte budget or under the free-space floor, never under a live consumer lease), a cache root whose owning directory the sweep removed is reaped as an orphan, and the pass stays silent unless it acts. New prune flags: --no-cache, --cells-root.

Fixed

  • Combining stale-lock reclamation with dead-session reaping is refused before mutation so named owner evidence is retained.
  • Decode repository-bound brief, PR and issue claim keys before live reconciliation; use the matching board or forge item reader, keeping unknown mappings and unreadable sources blind.
  • Dispatch storage admission checks checkout and temporary volumes even when managed Go caches reside elsewhere, and supports an explicit disk floor without managed caches.
  • Git reads and pushes from shared-object clones reuse alternate pack indexes instead of decoding them for every borrowed object.
  • Keep healthy claims and the standing supervisor running when a claim has an unknown owner, a future timestamp, or a refused stale release; report those claims blind. Already-released claims skip deletion.
  • Managed task scratch can retry an interrupted workspace cleanup after restart, preserving ownership and evidence receipts until the disposable workspace is removed.
  • Supervisor claim retirement compares the exact assessed claim version, preserving replacement holders, and reads immutable payloads from the active claim namespace. Live ticks use bounded pages with explicit continuation and hold malformed claims for inspection.
  • The mutation runners (muhar, loopadmin/mutate) no longer poison the ambient Go build cache: each mutation run now gets a throwaway GOCACHE (overriding any inherited one) that is removed when the run ends, including on interrupt and error exits. GOMODCACHE stays shared — module downloads are immutable and shared-safe.
  • The opt-in dead-session worktree reaper recognizes detached review heads preserved by remote refs after squash merges, requiring a named inactive owner and retaining unpublished commits and local review evidence.
  • cellctl passes each generated role session and the cell's roster and credential home to worktree initialization. Deskd resolves the repository from the cell checkout and uses the cell's custody context instead of the launching shell's.
  • graph-execution/07 Verify table re-authored after #1740: row 3 pins --since/--until to the fixture range (the default 28-day window made the row clock-dependent), row 7 reads the exit code from a built binary instead of go run, row 8 uses --base with a pinned SHA instead of the --lint-only --diff-base, rows 3 and 5 capture the report to a per-run mktemp file before jq so a pipefail shell cannot report the report's own exit 3 as the row's and jq never reads a file the run did not write, row 4 escapes its Command-cell pipe and the other rows drop theirs so the witness runs each full command, rows 7, 8 and 9 end in a status-carrying test with an output is Expect so each can fail under the execution witness, and rows 1, 2 and 6 anchor their -run selectors and assert the --- PASS: line.

Changed

  • Route all six live board-writer credential consumers through the main-only board-writer Environment. Evidence auto-merge uses a default-branch metadata poll, and changelog rolls require a non-dry-run dispatch on main.

assay release v1.0.38 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built separately by docker-publish.yml, daily-immutable-tag; pin the ref in .assay-versions):

  • ghcr.io/medici-finance/assay/desk-tools:v0.1.0

See checksums.txt for every asset sha256.

Release authorization (traceability to the person authorizing release):
authorized-by: kryton (dispatch actor)
This records who authorized the release cut, not who or what built the artifact; the pipeline carries no signature or provenance attestation, and the human approval in the gated release environment (not this line) is the authorization it names.

v1.0.37

Choose a tag to compare

@github-actions github-actions released this 10 Oct 02:42
Immutable release. Only release title and notes can be modified.

Highlights

Fixed

  • deskevidence lands Evidence rows and outcome records again. Since v1.0.33 every landing, including --dry-run, exited 5 with "refusing to reach the forge with no minted verifier token": pre-work admission reads the dispatcher's attestation record from the forge, and it ran before the verifier token was minted, so the tool's own custody step refused the read. The landing now mints the token and resolves its forge first, then runs admission through that same forge, so admission and the write use one forge under one minted token. Admission still runs before the landing reads the evidence file or the branch and before any write, no check is skipped or made optional, and there is still no fallback to an ambient identity. One visible change: a landing that admission or a later local check refuses (for example a --root that is not the dispatched verifier home, or an oversized file) now mints a token before it is refused. On a GitHub-served repository that mint reuses a cached token inside its reuse window; on a GitLab-served repository the mint rotates the role credential, so such a refused landing now spends one rotation it did not spend before. The refusals placed before admission still refuse without minting: a malformed or unlisted repository, an unsanctioned main, bad or conflicting flags, a generated or appended-log target, and an outcome record that does not parse, is future-dated or cannot be named. Two refusals that need only the command line sit after admission, as they did before this change, and so now mint first: a target outside docs/streams/, and an absolute --evidence-file with --root that is not a --brief-path fragment outside it.

assay release v1.0.37 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built separately by docker-publish.yml, daily-immutable-tag; pin the ref in .assay-versions):

  • ghcr.io/medici-finance/assay/desk-tools:v0.1.0

See checksums.txt for every asset sha256.

Release authorization (traceability to the person authorizing release):
authorized-by: kryton (dispatch actor)
This records who authorized the release cut, not who or what built the artifact; the pipeline carries no signature or provenance attestation, and the human approval in the gated release environment (not this line) is the authorization it names.

v1.0.36

Choose a tag to compare

@github-actions github-actions released this 09 Oct 23:51
Immutable release. Only release title and notes can be modified.

Highlights

Changed

  • The release workflow pins actions/upload-artifact v6.0.0 and actions/download-artifact v7.0.0 (both run on Node 24), replacing v4.6.2 and v4.3.0, which target the deprecated Node 20 runtime and drew a deprecation warning on the test (deskmerge) legs of every release run. Inputs are unchanged. The staged and proposed copies of the workflow carry the same pins.

assay release v1.0.36 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built separately by docker-publish.yml, daily-immutable-tag; pin the ref in .assay-versions):

  • ghcr.io/medici-finance/assay/desk-tools:v0.1.0

See checksums.txt for every asset sha256.

Release authorization (traceability to the person authorizing release):
authorized-by: kryton (dispatch actor)
This records who authorized the release cut, not who or what built the artifact; the pipeline carries no signature or provenance attestation, and the human approval in the gated release environment (not this line) is the authorization it names.

v1.0.35

Choose a tag to compare

@github-actions github-actions released this 09 Oct 22:48
Immutable release. Only release title and notes can be modified.
c80c4ce

Highlights

Added

  • A read that fails while the verifier packet's commit list is built is stated in a fixed sentence of the tool's own; a test fails each of the provider's reads in turn and holds the reader's error text out of the file (#2439).
  • A staged copy of the board workflow (ci/staged-workflows/assay-statusgen.yml) adds an hourly reconcile job, pending maintainer promotion into .github/workflows/. It writes the generated Briefs tables in stream READMEs by pull request only: it flips Status cells witnessed by a merged PR's Brief: trailer, re-renders the tables, and carries any change as one draft pull request on board/reconcile. It never pushes the default branch, scheduled runs have their own concurrency group so they cannot displace a pending push regen, and the schedule runs only in this repository, never a fork. Each tick recomputes from the default branch, so a change on the default branch never wedges it; it refuses to overwrite a branch carrying a commit whose subject or change is not its own, anywhere on the branch (the check reads a commit's subject and what it changes, renames included, not who made it, and a failed read fails the tick); and it fails when the remote, the pull requests or the PR list cannot be read. Its pull request is the open one from this repository's own branch into the default branch, whoever opened it: a fork's same-named branch, or a pull request from that branch into another base, never stands in for it, and two candidates fail the tick. Each push rewrites the PR title and text from that tick's report, and the report, including any held rows, is printed to the job log. statusgen runs holding only the read token; the board-writer App token is minted only when there is a commit to publish, narrowed to contents and pull-request writes, and only the step that pushes and opens the PR holds it. The job uses the same isolation as the corroborate job (a job-local, checksum-verified Go toolchain and caches, a pinned gh), with Go workspace files off so none left above its temporary directory is read, and reads no git state an earlier job on the runner could leave: it clones the default branch fresh under the job's temporary directory instead of checking out into the workspace, uses git and gh configuration of its own with hooks off, pushes to the forge by URL, and binds its credential helper to that host. Once the file is promoted, the board workflow's pull-request lint runs the job's tests.
  • A worker packet shows every value it did not write — a title, a login, a branch, a label, a
    check or file name, a finding's id and state, an error's text — inside a code span the value
    cannot end, and quotes longer text between boundary lines. It reads a finding record only
    from a review the forge attributes to the reviewer identity: a review by any other account
    is listed under its own heading as not the reviewer's, and when that identity cannot be
    resolved no review is listed as the reviewer's, no record is read and no body is quoted.
  • Both worker kits gain three clauses about how a run gathers and waits — batch independent
    reads into one request, read the packet first when the assignment names one, and wait on a
    check or a review in one bounded command — none of which changes what a worker must do or
    wait for.
  • Every deskread envelope carries an additive identity object (app-custody with the role, or ci-workflow-token with the repository and run id), and one stderr line names the transport. The token never appears in output.
  • In a worker packet for an open change, a finding record in a review at an earlier commit is
    judged against that review's commit: resolved with no evidence commit of its own is not a
    resolution at the current head, and the line says so. Comments are quoted newest first, so
    the packet's cap leaves out the oldest; each comment, and each review by another account,
    says whether its author is the reviewer identity, on the trusted list, not on it, or not
    checked because no list is configured; a comment by an account that is neither is quoted
    only up to 16 KiB (#2439).
  • Review kit clause 20 and the pr-review-desk skill make the lane round cap bind: from a lane's fourth round, a finding first raised then, in code unchanged since the lane's first review, is advisory or an arbiter hand-off, except a safety-relevant finding, which still blocks. A late finding the reviewer cannot place with confidence blocks, the cap never changes a security verdict, and a finding whose evidence did not exist at the first review (the base branch moved, the description was edited, a check result at the head, a could-not-check gap, an undeclared decision) is not a late finding.
  • Text taken from the change is marked as data in the packet two ways. Multi-line text sits between two boundary lines that carry a random value made for that one file; inside them, a line that would begin with three less-than signs is prefixed with [quoted] , and line-break characters other than the newline are written as \uXXXX, so no quoted line begins with a boundary mark. Single-line values (title, branch, check and file names, logins, error texts) are written in code spans in which a backtick is shown as an apostrophe. The packet's opening lines tell the reader both.
  • The // regression: #<N> doc-comment tag (also F-<slug>, class #<N>) on the line above a test says which incident it pins; seven existing regression tests carry it. Only a line holding refs of those shapes and nothing else is a tag: doc-comment prose that happens to wrap onto a regression: line is not.
  • The outbound-write check can consult a deployment's own executable, the house callout. Set ASSAY_OUTBOUND_CALLOUT in the roster to an absolute path; every outward write the compiled checks have passed is put to it AFTER them (a push: once for the branch name, once per commit message, once for the added lines), as one JSON object on stdin with the text as plain JSON strings (no HTML escaping), and it answers allow or block <reason>, the first word exact and lower case. It can only narrow: a compiled refusal is never put to the callout, and a callout allow clears nothing. Any failure of the callout (missing, writable by group or world, non-zero exit, timeout, empty or oversized output, an answer that is neither word) refuses the write, and the message names the failure. Every refusal is the house.callout rule and is not overridable by --force-scan-override. Everything the callout printed — a block's reason, an answer outside the vocabulary, its own stderr — goes to stderr only, on one line, never to the audit log, the error text or the forge. The callout runs with an environment of exactly PATH, HOME, TMPDIR and LANG, holding the calling process's own values; a callout sets its own PATH and its own locale, as the example does (PATH=/usr/bin:/bin, LC_ALL=C), so the caller's PATH or LANG cannot decide its answer. When the callout answers allow, anything it wrote to stderr is still printed to stderr.
  • The review kit gains two clauses on every lane. Clause 17 tells a reviewer to read a file in the fewest requests (normally one read, whole; one targeted read of a large file the PR barely touches), to send independent reads in one request, and to gather a PR's state in one command, because every request re-reads the whole conversation. Clause 18 tells a reviewer to read a prepared review packet first when the assignment carries a Packet: line; it is inert when no such line is present, only the dispatcher's assignment block can arm it, and the PR's head and every check are still read from the forge before the verdict (#2437).
  • The verifier kit gains clause 7, "Packet first — a reading aid, never evidence": read the packet first, whole, in one read, fetch only what it lacks, and never copy a packet line into an observed cell or count a row as run because its command is quoted. A row's result comes only from running the row at the verified commit (#2439).
  • The verifier packet finds a brief's Evidence and Verify headings the way the repository's own readers do, with the white space around the line taken off first, so an indented heading no longer leaves an Evidence section in the packet. It no longer says it holds no result: it says what it cut, and where it finds no Evidence heading it says it could not determine whether the carried text records an earlier result. The result-like-column check now covers every table in the carried text, and a numbered or emphasised Evidence title cuts too (#2439).
  • The verifier packet writes every value it read from the repository and shows at its own level — the brief's path, a commit id, the brief id — with packet.Code, so a path chosen by a brief's author cannot close its code span or start a line of its own; copied text stays between a boundary pair, where a line that would begin like a boundary line is shown with [quoted] in front (#2439).
  • The verifier packet's commit list says how many commits it left out when it stops at its limit of six, and says when no commit message was searched because the item key gives no brief id. The verifier kit's packet clause says what to do when one read does not return the whole packet (#2439).
  • The worker-desk skill adds a rule for new dependencies, plugins and MCP servers: before install, file an issue with an agent-generated risk summary covering source, permissions and persistence. The minimum release age is 7 days, and a younger release also needs a driver bless. The worker dispatch prompt carries the same rule.
  • Versioned source obligations and project applicability: spec/project-obligations-v1.md, schemas/project-obligations-v1.json and an offline loader library in statusgen (tested, not yet called by any lint check, command or workflow) that bind a permitted source revision to existing requirement ids and accept an applicability decision only as a link to...
Read more

v1.0.34

Choose a tag to compare

@github-actions github-actions released this 09 Oct 09:21
Immutable release. Only release title and notes can be modified.

Highlights

Added

  • Design-decision record DR-forge-neutral-34 (docs/streams/decisions/): a transcription of the
    driver's ruling on decision issue #2315, which answered option 1 — approve as briefed the
    deskread CI workflow-token transport, an explicit, CI-only, read-only opt-in beside the App
    custody default. Brief forge-neutral/34 now cites it through design:, which is what the
    design-approval gate reads. The record does not decide the implementing pull request (#2377)
    or the brief's later sign-offs.
  • deskevidence --outcome-record now writes the verify-wake receipt on every verify-fail or blocked record. The receipt's inputs are one file: hash per path in the brief's files: list that exists at the record's sha (every file under a listed directory), the brief as it lands, and the tool version. blocker_kind and blocker_ref are required. A blocker_ref that is not an issue or change reference, such as to file, is refused with exit 5. A verified record carries no receipt.
  • deskevidence --outcome-record stamps the landing repository as the record's repo when the caller gave none. A record that already carries a verify-wake-v1 receipt lands only if that receipt is complete; otherwise it is refused with exit 5, naming the missing field.
  • docs/verify-wake.md documents the hold rule.
  • verifyloop plan --no-forge reads no blocker issue, so every held brief's blocker is could-not-check.
  • verifyloop plan holds a non-pass brief until something it depends on moves, following the hold table in docs/verify-wake.md. It hashes the declared inputs again, and it reads the blocker issue through the forge as the verifier App. A brief whose inputs are unchanged and whose blocker is open prints a WAIT line naming the blocker, the wake condition and the next actor. A new summary line reads verify-desk plan: wait=<n> dispatchable=<n> could-not-check=<n>. A missing or rejected token, or any other failed read, is could-not-check, never a closed blocker. A newer explicit-recheck receipt still overrides a hold.
  • verifyloop plan reads a blocker only in a repository inside the configured repository set. A reference outside the set is could-not-check, and no credential is requested for it. Each repository is named on stderr before its first read. A bare #N in a record with no repo resolves in the plan root's origin repository.

Changed

  • The STATUS.md Awaiting board now sorts each brief into one of four owned queues (Awaiting human gate, Awaiting implementer rework, Environment-blocked, Runner-pending) or into Desk-actionable, which keeps only rows that need judgement. Every row names its owner and next act, and the headline shows a count for each owner. A row whose Evidence or verify-outcome records cannot be read renders as could-not-check instead of being placed in a bucket. The rules are in docs/board.md. The Env-blocked heading is renamed Environment-blocked. A recorded blocker (verify-fail, fail, blocked, needs-context) routes by its kind: implementation and check-definition to workers, human-action to the driver, environment to the operator. A recorded hold stays a blocker whatever the Evidence says. A recorded fail is dropped only when the Evidence's live PASS was written on a later day than the record; when the two cannot be ordered, the row is could-not-check. A human-gated brief with a recorded blocker stays with the driver, and its next act names the blocker instead of the sign-off. A runner-pending row needs at least one row left to run, and an unrecognised or future-dated outcome record is could-not-check. Could-not-check rows count toward the verification-debt measure, so an unreadable input cannot switch the alarm off.
  • The pr-review-desk skill's generated-table bounce gains carve-out C. A one-row hand flip to implemented is admitted for a brief delivered into another repo when the delivering PR could not carry the brief's trailer. The flip PR carries that row and nothing else; it names one merged delivering PR, which must have merged after the brief was authored and added at least one file the brief's files: list names; and every concrete file in that list exists on the delivery repo's main. Carve-outs A and B are unchanged.

assay release v1.0.34 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built separately by docker-publish.yml, daily-immutable-tag; pin the ref in .assay-versions):

  • ghcr.io/medici-finance/assay/desk-tools:v0.1.0

See checksums.txt for every asset sha256.

Release authorization (traceability to the person authorizing release):
authorized-by: kryton (dispatch actor)
This records who authorized the release cut, not who or what built the artifact; the pipeline carries no signature or provenance attestation, and the human approval in the gated release environment (not this line) is the authorization it names.

v1.0.33

Choose a tag to compare

@github-actions github-actions released this 08 Oct 23:37
Immutable release. Only release title and notes can be modified.

Highlights

Added

  • Offline acceptance runner tests/stream-brief/32.sh (legacy, identity, negative, flow, dereference, mutation) with fixtures under statusgen/testdata/streamview.
  • Optional authored mission: block in stream README frontmatter (outcome, success criteria with evidence references, commitments, exclusions). Legacy streams need no migration; an invalid block is a statusgen lint problem with explicit diagnostics and is never replaced by README prose.
  • Stream view contract v1 (statusgen/streamview, docs/stream-view-contract.md): an importable, versioned wire type for one stream's state — repository-qualified identity (owner/name + slug, cell context kept outside the key, renames start a new identity), per-section provenance with explicit availability (available, partial, could-not-check, not-assessed; missing never reads as a value), a fixed trailing 24-hour changes window, version negotiation, a strict Decode consumer, and CheckBindings to dereference recorded revisions and evidence in the repositories they name. Every recorded revision must be a full commit id, and the window must end at the view's generated_at.
  • A findings entry can now carry an effectiveness record (effectiveness:, effectiveness-date:, effectiveness-by:, required together or not at all). statusgen --lint fails a resolved: yes finding dated on or after 2026-10-08 that has none, and advises on earlier ones. The check covers presence and attribution only, not whether the named command would catch a recurrence.
  • A source or bundle dated after the caller's "now" answers could-not-check, never fresh.
  • Design-decision record DR-cellctl-cobra (docs/streams/decisions/): a transcription of the
    driver's ruling on decision issue #2240, which answered option 1 — accept the preserved
    source/admission boundaries and the listed help and parse changes of the cellctl Cobra and
    Viper migration, subject to independent review and all required validation passing. Brief
    desktools-v2/16 now cites it through design:, which is what the design-approval gate reads.
    The ruling came after the implementing pull request (#2391) was opened, and the record says
    so; it does not decide that pull request's review or its merge.
  • Design-decision record DR-outbound-callout (docs/streams/decisions/): a transcription of
    the driver's ruling on #2375, which answered option 1 ("As proposed") for the deployment-supplied
    executable the outbound-write check may consult. Brief desktools-v2/11 now cites it through
    design:, which is what the design-approval gate reads. The record states that the
    implementing pull request #2383 was built before the ruling, and it does not decide that pull
    request's review or merge.
  • Existing quality evidence informs a scoped remediation decision; high complexity or touching a file does not automatically authorize a refactor.
  • Existing results carry the fields statusgen's remaining forge sites read: PullRequest.MergeCommitSHA (merged changes only, never an open change's test-merge SHA), Issue.ClosedBy (closed issues only, so a reopened issue no longer names its former closer), ChangedFile.Patch with PatchAbsent stated when the forge withheld a diff, Comment.UpdatedAt (empty when unread, never the creation time), and ChangeRef.Author, BaseRef, CrossRepo and HeadRepo (an unreadable fork stays empty, never same-repository or the base). Author Type stays empty wherever the forge did not resolve it.
  • House-cell startup opens one configured comms service surface in tmux, Herdr or Orca; shutdown stops its supervised processes and preserves mailbox data.
  • Its queries tell present, known-negative, stale and could-not-check apart.
  • New pure Go module deskcore (no third-party dependencies) with four effect-free packages:
  • Opt-in cell-owned Go caches persist across task homes, with byte budgets, filesystem free-space floors, active-consumer protection, JSON cleanup reports and retryable storage deferral before dispatch claims work.
  • The App inventory in docs/adopting-assay.md now records the workflow App: the single identity holding workflows: write, scoped to exactly contents: write + workflows: write + pull_requests: write + metadata: read with zero webhook events, and with administration, actions, checks/statuses: write, members and secrets/variables withheld. It stands beside the desk-role Apps as a capability, not a desk role or a tier.
  • The forge seam grows four typed reads under the freeze rule (forge-neutral brief 33), each with a deskread kind as its consuming call site and both backends pinned on recorded fixtures: ListIssues (any state, one optional label, the issue population only, with Incomplete and PageCap when it overflows the page ceiling), IssueStateEvents (close and reopen events with their actors, plus the changes that closed the issue, with Complete=false on overflow or on any closer whose merged state cannot be read), ListChangeCommits (a change's commit SHAs, Complete=false when the change's own commit count is larger than the list) and RepoDefaultBranch (an empty answer is could-not-check, never main).
  • The fork-test block is read by a strict, fail-closed grammar (tools/desk/README.md):
    fenced code blocks and HTML comments are blanked first, following CommonMark for those two
    constructs (a fence closes only on the same character, at least as many repetitions and
    under 4 columns of indent; an unclosed comment hides everything from its line to the end,
    wherever on the line it opens; a blanked line stays as an empty line, so it never joins what
    came before it to what came after it). The heading must be followed directly by the block,
    and the block is the contiguous run of column-zero <lowercase-key>: <content> lines. Prose
    between the heading and the first key line is refused as a malformed block, naming that
    problem. The strip models only fences and comments; a backstop drops the declared subject
    when the raw body has more than one fork-test heading, when a reading of the raw body
    disagrees with the stripped reading, or when the raw body opens a raw-HTML block kind a
    renderer drops whole (processing instruction, declaration, CDATA). One known limit is
    stated: a subject: line placed directly under the block's last line, with no blank line,
    joins the block.
  • The host contract for a split run, stated in verifyloop usage: the host writes its own dispatch record (repo, head sha, dispatch time) before starting the fence and runs the composer with --repo/--sha from it; signs only after the composer exited 0 with exactly one sha256= value and the fence has fully exited; passes all five binding flags, taking repo, head and both time bounds from its own dispatch record and only the digest from the composer; takes the signed body from stdout, never from a .out the fence could write; and signs only a payload moved by rename into a directory the composing uid cannot write. The binding is checked only at signing: the host refuses a payload whose digest, repo, head or ts does not match its own dispatch record. It does not limit what the payload's entries claim, and nothing after signing checks head or ts again (statusgen's transcriber checks only the repo), so a hostile row can still invent results that the host then signs.
  • The notice lane reads its reversible signal from the block's own subject: line alone,
    never the title or body prose, and only when the bounded block carries exactly one such
    line; none or several admit nothing. A shape-only needle (lint level, lint severity,
    notice or error, port-or-drop) never admits and vetoes any content needle beside it,
    in its plural spellings too (-s, -es, and -ies for a needle ending in y).
    Needles match on word boundaries, with runs of spaces, underscores, dots, slashes and
    hyphens treated as one space. The CI check/job backstop reads the subject the same way, and
    any non-ASCII character in the subject fails closed.
  • The reader refuses unknown schemas, inputs over 16 MiB, and any key the schema would refuse.
  • Two workable options plus a gate the driver still holds can file on a NOTICE LANE
    (desk-decided, off the driver's queue, with the shared desk-r3-decision v1 marker)
    rather than needs-decision. Admission fails closed: the item must carry a positive,
    content-bearing R-3 reversible signal (docs wording, typo, phrasing, a table column — never
    a shape-only tool default / default value / flag default / rename the, and never a
    lint level / lint severity / notice or error / port-or-drop example either, which is
    always a classification question about some check or job, named or not) AND no one-way
    signal — a one-way caller
    label (human-only, security, gate:human), a deskkit.HumanOnlySignals needle, or a
    deskkit.OneWayPatterns match (merge, ready-flip, main push, tag/release, weakening a
    security control, secrets/keys/PII, money, identity/auth, deleting or overwriting data,
    sending or publishing outside, live infrastructure, App permissions, approval authority,
    gate:human, direct writes to main, draft-to-ready, required reviews, 2FA/MFA, hooks and
    signatures, the trust gate and roster, owners and roles, archive/transfer/visibility,
    auto-closing driver-owned items, charges, and turning a control off). A one-way term
    outranks a reversible one, and the ruled-check: line is read for one-way terms (exempt
    only from the ruling needle). The same one-way check refuses --no-fork and withholds
    the re-routes from the fewer-than-two-options refusal. The patterns are a floor, not a
    guarantee: review of the filing and the digest's veto window are the layers around them.
    deskdigest lists notice-lane items in its desk-decisions section with their veto date,
    and drops a desk-decided item from the...
Read more

v1.0.32

Choose a tag to compare

@github-actions github-actions released this 04 Oct 21:36
Immutable release. Only release title and notes can be modified.

Highlights

Added

  • A class guard over the desk tree refuses any new function that reads a forge token (GH_TOKEN, GITHUB_TOKEN and the like) from the process environment unless a reviewed permit names it.
  • A class guard refuses any shipped function that looks a comment up by id on the untyped first-page comment read; such lookups must use the typed read, which walks the whole thread.
  • A pull request read now reports whether its head lives in the base repository or in a fork, on both the GitHub and GitLab backends.
  • CI now runs the findings-register transition check: statusgen --corroborate in its own corroborate job of assay-statusgen.yml (statusgen/06 deliverable 7, #1855). No PR-authored code runs in that job. The guard binary is built from the merge commit's base parent, with a job-local, checksum-pinned Go toolchain and caches (GOENV=off, GOTOOLCHAIN=local) and the pinned gh, and the PR tree is read only as data. Before building, the job checks that this parent is the merge-base of the base branch with the merge commit, so the guard compares against the commit it was built from, and that the event's base sha is its ancestor. A base retarget or a PR edit re-runs the job, no later event cancels a pending run of it, and a retarget during a run fails it. It runs on PRs that touch docs/streams/findings/, and fails closed when the base cannot be read or tied, or no human-login map is configured. Residual: under pull_request the workflow file itself comes from the PR, so a PR that edits assay-statusgen.yml can change this job; that edit is caught by human review of workflow changes, not by the job.
  • CLI routing registry (docs/streams/desktools-v2/cli-migration.json) and its check (tools/desk/internal/clicontract): every Go command and script launcher in the tree is discovered independently and routed to an owning migration brief or a classified exclusion; TestCLIInventory fails on an unrouted, stale, orphaned or over-budget row, and TestCLIOwnerMigrated runs each migrated package's contract tests.
  • Check descendant files for directory readers on both workflow events, and retain rejecting controls. Give preserved shell fixtures bounded runtime headroom with a cancellation control.
  • Design record DR-desktools-v2-03 for the read-path custody ruling.
  • Design-decision record DR-cellctl-go-port (docs/streams/decisions/): the operator's
    ruling that cellctl is ported from bash to Go, with the bash kept as the oracle until the
    Go port reaches parity. Brief desk-containers/10 now cites it through design:, which is what
    the design-approval gate reads before that brief can move to in-progress. The record
    describes the tree as it stands (the Go cellctl already ships in the release tarball since
    #1377) and does not decide the brief's cutover sign-off, which stays its own human gate.
  • Desk CLI adapter (tools/desk/internal/cli): a fresh Cobra tree and command-local Viper per invocation, help and version answered before any config, credential or effect, allowlisted configuration sources with unset kept apart from empty, no secrets on argv, and parse errors exiting 2 (desktools-v2/15).
  • Findings-register parks are capped: a parked-until that is added or extended may run at most 90 days past the date of the commit that sets it (a value not yet committed counts as set today, and a commit dated in the future counts as today). A later date is a --lint PROBLEM and MISSING in the --corroborate register lane, whoever authorized it. A landed park left as it is, or narrowed, is not re-judged.
  • Register 26 inherited desk-tool and statusgen behaviors with parent-counterfactual evidence, a manifest guard, and fixture-only regression entry points.
  • Route a durable task controller, runner conformance/adapter, immutable candidates, bounded specialist review and exact-candidate publication into nine implementation briefs.
  • Rule-register rows R-ambient-token-read and R-signoff-read-whole-thread in docs/contracts.md.
  • Run every floor fixture that starts git, directly or through a shell, without the caller's GIT_* variables, so a GIT_DIR exported by a git hook cannot redirect fixture writes; a hostile-GIT_DIR control and a structural guard pin it.
  • Stage the additive statusgen full-test CI case; its enforcement remains held until the maintainer applies the workflow patch.
  • Start every floor runner's go tool through one wrapper that clears the caller's GIT_* variables and global git config, so reused manifest rows cannot write to a repository an exported GIT_DIR names; a runner-level hostile-GIT_DIR control, a choke-point guard and a mutation mode pin it.
  • The shared CLI contract (docs/streams/desktools-v2/cli-contract.md) and migration briefs desktools-v2/18–54, one complex command or up to five simple ones each, with desktools-v2/17 now depending on all of them.
  • The shared loop-admin runner protocol (spec/loop-admin-runner-v1.md, schemas/loop-admin-runner-v1.json) and the independent loopadmin Go module that implements it (loopadmin/runner): start, observe, cancel and reconcile under a stable launch identity, strict standing-desk and workflow-stage modes, capability declarations with mandatory-field refusal, a generation fence on result acceptance, credential exclusion that decodes and walks extension values (nested keys, escaped tokens, Basic credentials, auth, bearer, private-key and access-key slots in any spelling or prefix, a secret written after a setting word, URLs carrying a password), with a short list of described exceptions (auth: disabled, auth_method, pallbearer, a port with an @ in the query), strict decoding (exact-case keys, no repeated key, no null for a defined field or a list element (refused at decode), no blank tool name (the schema refuses empty, validation refuses whitespace too), nothing after the request), terminal states that absorb any later report, a result that must echo its invocation identity and a reported model, refusals that never echo request or result content, adapter and fence errors sealed to the contract's sentinel (still matchable with errors.Is) on every verb, and records the caller and the adapter cannot rewrite after the call. Unknown outcomes, missing usage and unconfirmed cancels stay unknown. It ships an in-memory fake adapter, an offline conformance kit, a fixture that bypasses the contract's fence to show the caller's own claim-generation check still refuses a fenced result, and a mutation gate. No provider client or provider call. The module's CI job is staged at ci/staged-workflows/loopadmin.yml pending maintainer promotion.
  • assay:cut-release — a release-cutting skill in the public bundle, written against the single vX.Y.Z umbrella release. It sets the order of the chain: four live preconditions, then both release-workflow runs handed to the driver as exact commands — the dry run first, with its dry-run input set explicitly because the workflow defaults it to off, then the publish — since both wait at the release environment's human approval and record their dispatcher as the release's authorizer. Publication inputs such as the image push stay off unless the driver decides otherwise. Hashes are taken only from the published checksums.txt, then every consumer is re-pinned. The chain is done only when every consumer is green on the new pin. A bad release is fixed forward; a tag is never moved. Adopters cutting their own releases use the same skill. It is registered in the skills README, SOURCES.yaml, the Codex and Cursor packaging rosters, the per-harness capability tables, and the Codex smoke protocol's skill list.
  • statusgen --corroborate --pr N gains a findings-register transition lane: for a PR that touches docs/streams/findings/, every caution-removing move of a finding's resolved / affects / ack / parked-until since the PR merge-base needs a human named in the entry's authorizing key to have approved or approved-by-comment on that PR. An anchor already on the entry no longer authorizes a later change by itself. Whether a PR touches the register is read from the local tree against the merge-base, so a forge file listing that stops short (it caps at 3000 files) cannot hide a touched entry. An unresolvable merge-base with a listing that cannot be shown complete, or an unparseable touched entry, fails closed.

Fixed

  • A plain statusgen --lint (no --forge) no longer reaches the forge: before this change it ran the claim read (git ls-remote --heads origin) and dead-claim decay (gh pr list, or the GitLab API). Offline, the claim set now reads could-not-check, and --require-claims fails closed on it. The offline-lint test now records every forge/network process and HTTP request, so a read that starts and then fails is caught.
  • A role transport failure after the URL writes restores the worktree's prior push destination, and no inherited credential helper answers inside the retained worktree.
  • Desk-tools tests that depend on a newer git now skip with a named reason on an older one instead of failing for the wrong reason. On a Linux verify witness whose image ships git 2.39, the deskevidence merge-tree proxy test reports "needs git >= 2.43 for merge-tree --attr-source; have 2.39.5", and the deskwt add --role / role-init transport tests (plus one deskkit push-transport case) report that they need git 2.46 for the empty-entry URL list reset. On git that meets the floor every one of these tests still runs in full. A new stdlib-only internal/gitversion package holds the shared RequireGit guard.
  • Deskboard no longer shows MERGE-NOW for a ready, risk-classed PR that has a correctness approval at head but no Security-Review: pass at head. The security hold used to apply only to drafts, so a ready PR that took a new head and a correctness re-approval, with no fresh security pass, read MERGE-NOW. Such a row now reads SECURITY-REVIEW-REQUIRED whether i...
Read more

v1.0.31

Choose a tag to compare

@github-actions github-actions released this 02 Oct 07:29
Immutable release. Only release title and notes can be modified.

Highlights

Added

  • Advice can only restrict.
  • Agentic admission draft (spec/agentic-admission-v1.md, schemas/agentic-assessment-v1.json, deskkit EvaluateAgenticAdmission). It is a pure, deterministic policy that maps hard facts and recorded advice to one of five dispositions: bounded-agent-work, supervised-agent, human-led, discovery-only or blocked.
  • Malformed input fails closed: empty bindings, invalid or oversized subjects and inputs, and out-of-vocabulary values. Reason codes never echo an assessed string, and a refused subject is never echoed into the result or its PolicyResult projection.
  • Mandatory graph gates are the union of the brief's risk verdict and the disposition's.
  • Nothing activates it yet; dispatch wiring is a separate gated change.
  • Unknown readiness holds implementation.
  • discovery-only stands only on a discovery grant whose read scope covers the subject; otherwise the result is blocked.

Fixed

  • Forge-ref claim writes fail closed without a complete matching receive-pack acknowledgment; HTTP refusals retain their original status marker. Optional trace receipts retain bounded request and pack metadata without claim payloads or credentials.
  • The build-less-brittle/04 and /06 Verify tables now reach a verdict after the briefs land. Each consumers: row runs in a throwaway clone pinned to the delivering squash, and Expect names exit 0 and the exact summary line. Row 9 of /06 prints one gated count. Row 7 braces its revision variables, so zsh can no longer pass it at 0 ≤ 0. Row 3 keeps its scratch files in the checkout. What each row proves is unchanged.
  • The outbound check no longer refuses a brief's own frontmatter id: as a session id (#2022). The exemption covers exactly one shape: a lowercase UUID that is the whole value of the single id: line inside the frontmatter of a docs/streams/**/brief-*.md file. The check reads the file's full content to establish that shape, on the push path, the forge file write and the evidence pre-flight. A UUID in brief prose, in any other file, in a commit message or in a PR body is still refused.
  • The publish-identity gate in deskpr update now judges only the commits the push adds, so a PR
    whose head already carries a commit by another trusted App can be updated. The narrowing fails
    closed: a missing, stale, diverged or oddly-spelled remote tip falls back to the whole
    origin/<base>..HEAD range, and update re-checks against the forge's live PR head before it
    pushes.
  • deskpost no longer carries the retired per-item +1 reaction gate's read path: the orphaned reaction-read method on its forge-backed adapter is gone, the adapter's interface comment now names only the live-visibility read the :public write gate consumes, and a structural guard test fails if any reaction/award read reappears anywhere in deskpost.

Changed

  • Define Go launch and session contracts for the native Windows cellctl work, with strict record parsing, independently bound launch permissions and compiled process fixtures. Production Windows integration remains separate work.
  • deskboard actions no longer skips review of a PR authored by a trusted or blessed human: the HUMAN-OWNED action is retired, so such a PR is NEEDS-REVIEW (or RE-REVIEW on an advanced head) like any other admitted PR and counts toward the UNREVIEWED neglect alarm. The trust gate (trusted roster login, else a current blessing) is now the only authorship filter: an unblessed author stays quarantined in EXTERNAL / UNBLESSED, and an unreadable trust read or roster still keeps the PR out of dispatch. reviewloop drops the matching table key, so an older board that still emits HUMAN-OWNED reads as an unknown action and fails closed (#2028).
  • ci: promote the staged Windows CI leg and the winparity PowerShell 5.1 parse check into live workflows.

assay release v1.0.31 - statusgen + qualgen + desk-tools + drainloop.

Binaries (pin per-platform by sha256 in .assay-versions):

  • statusgen-
  • qualgen-
  • desk-tools-.tar.gz

Source components (cloned or imported at this tag; pin the umbrella , never a per-component tag):

  • github.com/medici-finance/assay/drainloop

desk-tools image (built separately by docker-publish.yml, daily-immutable-tag; pin the ref in .assay-versions):

  • ghcr.io/medici-finance/assay/desk-tools:v0.1.0

See checksums.txt for every asset sha256.

Release authorization (traceability to the person authorizing release):
authorized-by: kryton (dispatch actor)
This records who authorized the release cut, not who or what built the artifact; the pipeline carries no signature or provenance attestation, and the human approval in the gated release environment (not this line) is the authorization it names.

v1.0.30

Choose a tag to compare

@github-actions github-actions released this 01 Oct 22:47
Immutable release. Only release title and notes can be modified.

Highlights

Added

  • A new forgeban rule stops any package outside internal/deskkit from naming a backend type, so no code can build an unchecked backend or unwrap the checked one.
  • Document the native Windows implementation plan for cellctl, with dependency-ordered briefs covering Orca and Herdr launchers, Docker lifecycle, credential custody, and Windows acceptance checks. Runtime support remains planned.
  • Draft continuing-operations specification and parked stream proposal, with fourteen delivery outlines covering user journeys, portable measures, expected impact, outcome review, adopter packaging and cockpit integration. These are review materials, not released runtime capabilities.
  • Every new brief now carries a design-fit: block in its Context (owner, contract, retires, weight, why-add), so the author answers which module owns the change, what it retires and how much weight it adds before a worker starts. Defined in spec/brief-v1.md §4.1, with an example in docs/brief-template.md and the author-brief skill template.
  • Every write verb takes the same audited --force-scan-override. Credential, personal-data and self-containment refusals can be overridden, and each override leaves an audit row that holds the rule id and a digest of the text, never the text itself. A withheld identifier on a public or unknown target, and a ruling claim, can never be overridden.
  • Hotspot report for tools/desk: a test-only package (internal/hotspot) that ranks files by churn × indentation complexity over first-parent git history and reports temporal-coupling pairs (go test ./internal/hotspot/ -run TestPrintHotspots -v -args -since=… -until=… -top=N). A shallow clone reports could-not-check, never an empty ranking. No verb or flag is added to any shipped binary.
  • Known limit of the critical tier's inputs: a brief's issues: list (the main-red fix linkage), a README stamp cell, and a findings entry's control: are repo text that an ordinary reviewed PR can write. Only the red itself (--main-health) and the stamp authority set (roster configuration) come from outside the tree, so tier membership is as trustworthy as the review and merge of those files.
  • Negative-path tests pin the custody contract of the desk's native GitHub read client: a read with no minted token is refused before any request, even with a GH_TOKEN, GH_ENTERPRISE_TOKEN or gh login present, and the installation a read's token is minted for is the account of the repo being read, never one GH_REPO or GH_TOKEN names. A committed mutation spec proves each check is load-bearing.
  • New ReviewQueueSnapshot Forge operation. It returns every open change together with its reviews in one backend round-trip: a single GraphQL query on GitHub. On GitLab it is degraded: it marks each change incomplete, so reviews are still read per item.
  • One outbound-write check now runs on every Forge write the desk tools make, and on every push made through deskpr or from a checkout with the deskpushguard pre-push hook installed, before the write leaves the machine. It combines the credential scan, the ruling-claim guard, a new personal-data pass (e-mail addresses and international phone numbers) and, for public or unlisted targets, the self-containment categories and the withheld register. The target's configured visibility decides which layers run.
  • Platform path, custody ordering, private fixture directory, hook argument forwarding shared forge contracts, backend read boundaries, GitLab outbound note and rewrite cases, and two-forge ambient credential checks. The compatibility brief remains incomplete pending owner scope clarification for environment resolution and Windows outbound-machine-path recognition.
  • Review gains a design-fit stage that runs before the correctness pass on any PR that grows a ratcheted weight dimension, adds an R- rule row, touches a brittle-marked module, or reddens an internal/arch test. Each trigger applies only where the repository carries the instrument it reads; a missing instrument is recorded as could-not-check, never as a design-fit finding. It asks three questions: is the change in the right layer, could removal fix the symptom instead, and are retires:/why-add: true. A "no" answer is a finding with the new scope basis design-fit (deskkit.BasisDesignFit, pinned to the review kit's reviewscope block). The class starts advisory: the finding is recorded and does not hold the PR. Promoting it to blocking later is a one-cell edit in the pr-review-desk finding-class register.
  • The observe evidence kind (spec/workflow-pattern-v1.md, schemas/workflow-pattern-v1.json):
    a signal watched over a window after a change lands, declared only where a deploy
    exists.
  • The check sits in two places. The Forge that ResolveForge returns wraps every write that carries text, so a verb cannot hold an unchecked Forge. The push path (deskpr before it pushes, and the deskpushguard pre-push hook) checks the branch name, every commit message and the added lines of the diff. A file written through the Forge checks the branch it lands on the same way. A comment, review or edit on a numbered item carries that number into the check, so a bare #N above it is still named as a probable cross-repo reference.
  • The worker-desk skill states the drive worker floor: for drive work, the floored deskboard dispatch reading wins over the wider fanoutloop plan board queue.
  • Verify rows can name their command explicitly: in a Command cell that mixes prose and code spans, a code span starting cmd: (for example `cmd: go test ./pkg/ -count=1`) is the command. statusgen verifyrun, the check:ci re-execution lane, newbrief, the row lint, verifyloop and deskrebaseline all take the first cmd: span. A cell whose first span is already its command needs no marker. A cell without the marker lifts exactly what each tool lifted before, so no existing row changes command. A marker counts only where the rendered brief shows it as code: one between escaped backticks, or in a cell whose prose carries raw HTML, a comment, a link, an image, a dollar in any spelling ($, \$, or a character reference such as &#36;, which GitHub can render as math) or any character reference, or in a cell where a span's opening backticks are fused to the text before them (an autolink or ~~ can swallow them), is ignored, and the marker span itself must be set apart by whitespace or the cell edge (plain punctuation may follow it), so hidden text cannot replace the command a reader sees.
  • Work-input dependencies (graph-execution/03 work-input amendment): a manifest's
    policy, build and environment dependencies are fingerprinted at the witness's commit
    and the item's revision. A changed one holds only the claims that depend on it, as
    wrong-revision naming it; one that cannot be fingerprinted is could-not-check. A
    reused ancestor pass names its derivation and keeps the witness's own revision, so
    an old receipt is never retargeted to a new subject.
  • TestOracleShellcheckClean in tools/desk/cmd/cellctl runs shellcheck over the whole oracle inside go test, so wherever shellcheck is installed a new finding at any site is a red test. CI does not install shellcheck yet, so there the test skips, and a non-verbose go test prints that skip as a plain ok; the install step is tracked in #1875. A planted-SC2086 positive control makes a broken or stubbed shellcheck fail the test rather than pass it; with no shellcheck on PATH the test skips as could-not-check.
  • cellctl manages local Docker cells directly in Go through CELL_CONTAINER_CONFIG, including registration, preflight, status and shutdown. Native cells no longer need an external host launcher.
  • deskapps init --manifest <file> — registers a single arbitrary GitHub App (e.g. a
    leak-sweep gate App) from a manifest JSON file instead of a tier's fixed App set, through
    the same loopback bind, state-nonce, callback/conversion/PEM-write and identity-mismatch
    machinery as --tier, keyed by the App's manifest name rather than a desk role. Mutually
    exclusive with --tier; refuses a manifest that specifies its own redirect_url or
    hook_attributes.url.
  • deskapps init — the loopback web app that drives GitHub's App Manifest flow: it posts
    the chosen tier's manifest (team: read+act; family: one App per desk role) to GitHub's
    own new-App page, exchanges the returned code for the App's credentials, and writes the
    private key (0600, never printed or logged), apps.env and the role→App bindings. Binds
    127.0.0.1 only, refuses a /callback whose state does not match a pending row, and refuses
    a conversion whose App owner is not the account the operator named (gh login or --org), failing closed when either owner is empty.
    The posted manifest carries no hook_attributes key (this flow sets no webhook URL, and
    GitHub's schema rejects a url-less hook_attributes).
  • deskboard dispatch applies the same floor across every configured root, summing in-flight drive work, and names the floor in its held-back line. Its merged queue keeps the critical tier ahead of score, so a critical row takes the shared headroom before routine drive rows, and each row it offers is tagged drive:<slug> / critical:<arm>. The cross-root floor needs statusgen at this version on every root: a root on an older statusgen reports no cap, and with no root reporting one no cross-root floor applies.
  • deskboard's actions sweep now reads each repo's open PRs and their reviews with this operation, instead of one review read per PR. On GitHub that means 1 call per repo instead of 1 + N. Each PR's head and its reviews now come from one consistent snapshot, and the board output is unchanged.
  • docs/contracts.md gains a Rule register: one row per enforced rule (owner, invariant, the semantic-index row it serves, justifying publ...
Read more