Skip to content

Releases: Kemetra/Seshat-BI

Seshat BI v2.1.0

Choose a tag to compare

@Kemetra Kemetra released this 25 Aug 14:15
f838ad3

Seshat BI -- v2.1

This note summarizes the changes merged after v2.0.0. The complete per-entry
record, including specification and pull-request references, lives in
CHANGELOG.md.

Why this is 2.1 and not 3.0

This is a MINOR release under
docs/operations/versioning-policy.md. It registers two additive rule IDs
(DL10 and DL11) and adds the optional seshat check --explain surface.
Existing commands, flags, default text, exit meanings, and rule IDs remain in
place.

The new design rules can report errors on design artifacts that were previously
ungoverned. That is the policy's explicit MINOR case: a new contract is introduced
in a new version rather than changing the meaning of an existing rule ID.

No migration is required for repositories that do not use the newly governed
design or two-table comparison surfaces. Consumers parsing seshat check output
continue to receive the v2.0 default shape unless they opt into --explain.

Governed actual-to-target ratios

Spec 156 (#711, #712) closes the mismatch between the sanctioned
variance-vs-target contract and the measure generator.

  • binds_to remains the scalar primary authority.
  • A sibling compares_to block names the governed target Gold table and columns.
  • One stdlib-only validator is shared by approved inventory and DAX generation.
  • Numerator and denominator tables must align with their respective bindings, and
    every source/filter column must be declared by the correct side.
  • Comparison PII is effective PII for finalization and statistical policy.
  • Statistical columns remain attached to their own source table.

Malformed table/column identifiers, a bare gold. prefix, or non-string filter
operators are refused before generation. DAX output remains text only: Seshat does
not write a PBIP, connect to Power BI, or grant an approval through this feature.

Evidence dates without invented freshness

Spec 157 (#712) gives readers the dates needed to judge whether an answer is
current without manufacturing a freshness verdict.

Source profiles disclose the reporting date, coverage end, and committed-evidence
observation date when those facts are parseable from committed evidence; an
unprovable value is an explicit GAP. The optional answerability summary carries
exactly three cited dates and Publish Ready guidance explains how to present them.
No new readiness field, freshness threshold, badge, score, or approval is created.

Findings explain themselves at the failure point

seshat check --explain (#706) renders the existing, governed means and fix
text from docs/rules/rule-fixes.yaml beneath each ordinary text finding.

The default finding line is byte-identical with and without the feature, and the
flag changes neither severity nor exit code. JSON, review, and SARIF formats refuse
the unsupported combination rather than pretending guidance was included.

Design references and vocabulary become checkable

Two new rules ship in #707 and #708:

  • DL10 reconciles the page-section vocabulary across the authoritative desktop
    grid, mobile grid, dashboard-page template, and filled report blueprints.
  • DL11 resolves the design file and token pointers whose grammars are actually
    machine-checkable, while deliberately excluding prose and store identifiers.

The follow-up also makes a fresh seshat scaffold-design pass the rules it emits:
referenced spec targets are packaged and scaffolded, and corpus membership is
derived from the real scaffold set.

Business questions reach the named owner

Across the twelve retail KPI domain packs, the governed layer now carries forty-one
owner-question cards (#709). Each card states the question, the silent failure if
unanswered, the layer default as context only, and the existing critical Decision
Store type that records the answer. The cards grant nothing: unanswered meaning
remains pending and no default is converted into a ruling.

Reliability and operator guidance

  • A zero Power BI MCP session deadline now stalls before any transport read (#702),
    fixing a Windows clock-boundary defect that could consume a frame despite a
    caller's zero wait budget.
  • Idea-engine candidates use assigned schema-validated IDs rather than fuzzy title
    reconstruction, and its model effort tier no longer requests an unsupported
    configuration (#703).
  • ONBOARDING.md now routes a new arrival into the existing Seshat BI entry points
    instead of presenting one maintainer's usage telemetry (#704).
  • README, Studio, F016, and adopted-idea status claims are reconciled with the
    shipped tree (#710-#712).

Publication surfaces

The coordinated release projects one owner-approved 2.1.0 version into the
Python package, the scoped and unscoped npm packages, Claude repository marketplace
metadata, and the generated Claude/Codex bundles. GitHub Release, PyPI, npm, and
repository-plugin availability are verified independently after publication.

Public Claude and OpenAI discovery-catalog submissions remain separate
identity-verified human actions; repository marketplace availability does not imply
either public catalog has accepted a listing.

Seshat BI v2.0.0

Choose a tag to compare

@Kemetra Kemetra released this 22 Aug 09:29
f252c74

MAJOR release. Two existing CLI contracts changed. If you script against seshat, read this before upgrading.

Full detail: docs/releases/v2.0.md · per-entry citations in CHANGELOG.md.

Breaking

1. seshat doctor's default text output is reshaped (M8, #689)

# v1.1.0 — flat, one line per finding
  [error] A1 <message> (<locator>)

# v2.0.0 — grouped by rule id
A1: 2 finding(s)
  [error] <message> (<locator>)
  hint: <non-mutating repair guidance>

next allowed action: <action>

Any consumer scraping doctor stdout will break. Migration: seshat doctor --format json — new in this release, emitting {"findings": [...], "finding_count": N} with a repair_hint per finding. Parse that; the text digest is a human surface and may be reshaped again.

2. seshat pbi-mcp preflight can now exit 2 where it exited 0 (spec 149, #659)

Server identity is now derived from the argument vector, not just name/command/url, and --readwrite=true is recognised as write mode. A .mcp.json could previously alias the official Power BI MCP server under an unrelated name, invoke it via npx in args, and classify as absent — handing the bypass guard a clean verdict while --skipconfirmation sat in the same entry.

This is a security fix, not a regression. If preflight newly exits 2, it is reporting a real bypass-shaped config that was previously invisible. Fix the config; do not pin to 1.1.0 to restore the 0.

What did NOT change

No seshat check rule id was added, removed, or renamed, and no existing rule's predicate or severity changed. src/seshat/rules/ has zero changed files in this range, and the registered id set is identical at both refs. A consumer's seshat check verdict on an unchanged repo is unaffected by this release — the blast radius is the two CLI contracts above, not the governance rule set.

Also in this release

  • Studio governed analyst workbench (spec 140, #695) and Studio operations and client review (spec 141, #697). 141 guards a disclosure where 140 guarded a write: contracts/export-boundary.md separates softening, leaking and acting.
  • Approval-gated Power BI MCP writes (spec 149, #659 + #670/#672/#674/#679). plan-write and apply against Microsoft's official local server (external, unforked, never vendored, ADR 0018). Every precondition is derived, never accepted as a caller assertion; twelve typed gate blockers, fail-closed. A successful write advances no readiness stage and grants no approval, and --skipconfirmation is refused everywhere.
  • Guided setup execution (spec 155) and capability derivation from committed evidence (spec 153).
  • seshat doctor --format json, grouped findings, non-mutating repair hints, next-allowed-action (M8). Hints are text only — nothing is executed on your behalf, and doctor still never modifies a file. It remains advisory: seshat check's exit code is the only gate.
  • The unit suite now runs on Windows in CI (#698, #699). Previously Windows CI ran only the CLI first-success journey and never invoked pytest, so POSIX-locked fixtures were invisible by construction (#691). Non-blocking while a baseline accumulates.

Install

pip install seshat-bi==2.0.0

Also on npm as @kemetra/seshat-bi and the unscoped seshat-bi.

Seshat BI v1.1.0

Choose a tag to compare

@Kemetra Kemetra released this 15 Aug 13:34
6e6dfaa

Seshat BI -- v1.1

This note records the changes merged after the frozen v1.0 release note. It
does not rewrite the historical claims captured in docs/releases/v1.0.md or
any earlier note.

The full per-entry detail (with spec and PR citations) lives in CHANGELOG.md;
this note summarizes the shape of the release.

The headline: Studio is installable for the first time

Read this before anything else in this note.

v1.0.0's published wheel carried no Studio frontend. Anyone who ran
pip install seshat-bi[studio]==1.0.0 got a seshat-studio console script that
fail-closed with "Studio frontend assets are missing." That defect was disclosed
honestly in docs/releases/v1.0.md and tracked as issue #623.

The fix (#636) merged roughly 11 hours after the v1.0.0 tag. Because the
tag is immutable and PyPI rejects re-uploading an existing filename, the fix
could not reach users through 1.0.0 at all -- a new version was the only
remedy. That is the reason this release exists.

scripts/build_studio_frontend.py now runs before packaging in both
release.yml and ci.yml, and the built assets ride in both the wheel and
the sdist (#641, #642).

Verified by building the artifacts and counting entries, rather than by reading
the workflow -- the tests that would catch this skip in the release job, so
a green CI run is not evidence for this particular claim:

WHEEL seshat_bi-...-py3-none-any.whl  studio/static entries: 3  index.html: True
SDIST seshat_bi-....tar.gz            studio/static entries: 3  index.html: True

The published 1.0.0 wheel scored 0 on that same measurement.

What else is in this release

Studio closes a technical approval round trip

Spec 139 Phase 6 (#625, #626, #632, #633) lands the half that v1.0 explicitly
disclaimed. A technical approval can be registered from a streamed turn,
decided exactly once with replays refused, relayed to the provider, and
returned to the browser with the readiness verdict attached.

The authority boundary has not moved, and this is the part to read
carefully.
This is the technical approval lane only:

  • Named-human approval authority is split from technical authority (T025).
  • Readiness forbidden scope is read fail-closed (T025).
  • Studio grants no business approval, moves no readiness stage, and
    emits no confidence score.
  • Approving a readiness stage remains exactly what it was: a human edit to
    readiness-status.yaml, read through the same approval_is_shape_valid the
    gate rule uses.

Studio also now lists the business decisions a named human still owes (T027,
#635). That is a read-only ledger of who owes what -- not a surface that
decides any of them.

Supporting fixes

  • agent_turns is derived from what the build can actually do (#638),
    not advertised statically, and is pinned in both directions by
    tests/unit/test_studio_capability_truthfulness.py.
  • A turn paused on an approval now outlives the stalled-provider timeout
    (#630).
  • The approval delivery seam is reachable in production, not from tests only
    (#628).

Governance and docs

Seshat Studio is classified in the authority taxonomy as a Product Module
(#627); Core remains functional without it. Phase 6 was re-verified against the
merges that closed it (#631), and T033 (#643) and T023 (#645) were closed on
recorded acceptance evidence.

What this release does NOT do

  • Studio is still not finished. It remains behind the optional studio
    extra, and a base pip install seshat-bi installs no FastAPI/Uvicorn.
    Running seshat-studio without the extra prints a named diagnostic naming
    both install lanes rather than an ImportError traceback (FR-006).
  • No business-approval surface ships. See the boundary above.
  • T032, T036, and T037 of spec 139 remain open. T036 needs an external
    signed-in Codex subscription and a real browser; T037 is an independent
    review of the completeness claim. Both are owner-gated by design and cannot
    be self-certified by the agent that built the work. T032's accessibility
    suite now runs and gates in CI (#647), but the box is the owner's read.
  • No verb, rule id, exit code, or required-argument change. The audited
    policy surfaces are unchanged from v1.0.0; all source change in this release
    is confined to src/seshat/studio/ and is additive.

Seshat BI v1.0.0

Choose a tag to compare

@Kemetra Kemetra released this 13 Aug 11:57
adefa70

Seshat BI -- v1.0 release candidate

This candidate records the changes merged after the frozen v0.8.2 release note.
It does not rewrite the historical claims captured in docs/releases/v0.8.md,
docs/releases/v0.8.2.md, or any earlier note.

The full per-entry detail (with spec and PR citations) lives in CHANGELOG.md;
this note summarizes the shape of the release.

The headline boundary: Studio ships as an INCOMPLETE PREVIEW

Read this before anything else in this note.

This release ships the first installable slice of Seshat Studio -- a
localhost analyst console (spec 139) -- and Studio is not finished. It is
published now, deliberately and knowingly, so the 86 commits behind it stop being
invisible to installed users; a second release follows when Studio completes.

What that means concretely, for anyone who finds the seshat-studio console
script in an installed 1.0.0:

  • Studio has no approve, apply, or reject surface. By design, not by omission.
    Spec 139 Phase 4 ships the read/observe half only. There is no handler in
    src/seshat/studio/ that grants an approval or applies a change. Approval
    remains exactly where it was -- a human edit to readiness-status.yaml, read
    through the same approval_is_shape_valid the gate rule uses.
  • The Codex bridge has no production caller. CodexBridge and its health()
    path are shipped, tested, and reachable only from tests; no CLI verb or
    endpoint drives them. This is tracked as open issue #618, "wire CodexBridge
    into startup, behind an off-event-loop turn drain," which this release does
    not close. Do not read "Codex integration" into this release as a working
    user-facing feature.
  • Studio is behind an optional extra and is absent from a base install. A
    plain pip install seshat-bi installs no FastAPI/Uvicorn. Running
    seshat-studio without the extra prints a named diagnostic naming both install
    lanes, not an ImportError traceback (FR-006).
  • The published wheel carries NO Studio frontend, so seshat-studio is not
    usable from PyPI in this release (issue #623).
    release.yml's
    build-validate job builds the wheel without running
    scripts/build_studio_frontend.py, and src/seshat/studio/static/ is
    gitignored generated output -- so there is nothing for pyproject.toml's
    artifacts re-include to collect. Measured on a wheel built exactly the way
    the release job builds it: 0 studio/static entries, while the
    seshat-studio console script ships. This fails closed, not blank:
    describe_missing_assets reports the missing build with a recovery action
    rather than serving an empty workspace. CI being green is not evidence against
    this -- ci.yml does build the frontend, so the wheel-content tests run and
    pass there, while in release.yml they never run at all
    (tests/unit/test_studio_frontend_build.py:39 skips without the build output).
    Tracked for the Studio completion release, when a working UI is the point.

Nothing in Studio grants an approval, moves a readiness stage, or emits a
confidence score. The governance boundary this kit exists to enforce is
unchanged by it.

Why this is a MAJOR release

Short version: two independent breaking CLI contract changes force the MAJOR
row -- see "TWO changes hit the MAJOR row" below, which is the section that
decides the number. The additive inventory in this section is what the release
adds; it is not what sets the version.

This candidate carries 86 non-merge commits across 27 merged pull requests --
31 feat, 26 fix, 14 docs, 10 refactor, and the remainder
build/test/style/ci.

The 27 is deliberately not the count of #-references in commit subjects, which
is 31: four of those references are issues, not pull requests (#618 among
them). Each of the 27 was confirmed to resolve as a pull request via the GitHub
API rather than inferred from the (#N) squash-subject convention.

Measurement cutoff: those totals are v0.8.2..18492bc -- from the commit
tagged v0.8.2 to the merge of PR #620, which was the head of main when this
inventory was taken. They deliberately exclude the release-preparation commits
that follow
, including the commit that adds this note and the version
projection commits prepare-coordinated-release creates afterwards. A count
stated inside the release it counts cannot include itself, so the cutoff is named
here rather than left for an auditor to infer.

Two additive surfaces would, on their own, have put this on the MINOR row of
docs/operations/versioning-policy.md:

  • A new console script, seshat-studio. Deliberately outside the
    seshat/retail dispatch chain, so it adds no subcommand to an existing verb
    and changes no existing verb's behavior. That is the policy's "NEW CLI verb,
    no change to existing verb behavior" row.
  • A new public subcommand, seshat spec-status [--fix] (64993f8),
    registered in src/seshat/cli/parser_core.py with a production handler and a
    capability entry. Absent at v0.8.2; same MINOR row.

The full verb inventory was diffed rather than sampled --
add_parser("...") across parser.py and parser_core.py goes from 40 verbs
at v0.8.2 to 41 at HEAD
, with spec-status the only addition and nothing
removed
.

No new seshat check rule id was registered in this release, and the rule-set
growth row does NOT apply.
This is stated explicitly because the diff invites
the opposite reading: git diff v0.8.2..HEAD --name-status -- src/seshat/rules/
reports 44 files, every one M, zero A. Those 44 modifications are the
rule-coverage migration (#589, #590) and are declaration metadata only --
each adds a Requirement/corpus declaration and, where applicable, a
requires=(...) entry plus a ReportsItsOwnAbsence note, so the framework can
distinguish "this rule was silent because the repo is clean" from "this rule was
silent because it never found its input." No rule predicate was broadened, no
new failure mode was added inside an existing rule id, and no severity moved
from warning to blocking.

That distinction is load-bearing, so it was measured rather than assumed: the
policy's MAJOR row covers "a broadened predicate, a new failure mode inside an
existing rule id," and 44 modified rule files would otherwise be the shape of
exactly that. A repo that was green on 0.8.2 is judged identically by these 44
rules on 1.0.0.

TWO changes hit the MAJOR row -- and they are why this release is 1.0.0

Both were found by external review on the release PR (#622), not by the
automated gates. They are independent: a consumer can be broken by the second
without ever invoking the four verbs in the first.

Breaking change 1 -- four PBIR verbs gain two required flags

1ac28b5 makes --repo and --table newly REQUIRED on four verbs that
already shipped in published v0.8.2
, and their handlers return exit code 2
when the new gate refuses. The verbs are pbir-apply-theme,
pbir-format-visual, pbir-set-page-background, and pbir-set-geometry.

Measured, not inferred:

  • All four verbs are present in v0.8.2:src/seshat/cli/parser.py.
  • _add_pbir_authoring_gate_arguments does not exist at v0.8.2 -- the two
    flags are new, and both carry required=True.
  • So a script that ran seshat pbir-apply-theme --theme X --report Y against a
    published 0.8.2 install fails with an argparse error after upgrading, and a
    gate refusal now exits 2 where the command previously proceeded.

docs/operations/versioning-policy.md classifies this on the MAJOR row: "A
CLI verb's existing flag/output contract changes (e.g. ... a flag is removed or
renamed, an exit-code meaning changes) -- Breaking for any consumer/script
parsing that output."

Breaking change 2 -- pbi-mcp doctor exit code and JSON shape

seshat pbi-mcp doctor now exits 2 where v0.8.2 exited 0, whenever
prerequisites are unresolved. Measured:

  • At v0.8.2, src/seshat/cli/commands/pbi_mcp.py ended _run_doctor with
    return 2 if rec.blocked else 0.
  • On HEAD (line 146) it reads
    return 2 if rec.blocked or rec.missing_prerequisites else 0.
  • tests/unit/test_pbi_mcp_cli.py records the flip directly -- an existing
    assertion moves from assert code == 0 to assert code == 2, and a new
    test_doctor_exits_two_for_unresolved_prerequisites pins it.

So seshat pbi-mcp doctor --intent published-query --json returns 0 on a
published 0.8.2 install and 2 on 1.0.0 for the same repository state. Any
automation treating this advisory command's zero exit as "success" breaks
--
and it never touches the four PBIR verbs above.

The --json payload also gains six fields (target,
target_semantic_model_ready, dashboard_ready, dashboard_ready_tables,
dashboard_design_approval, official_report_skills). Additive for a tolerant
reader, but it is an output-shape change on the same MAJOR row, so it is recorded
here rather than left for a consumer to discover.

Migration: pbi-mcp doctor is advisory -- treat a 2 as "prerequisites
unresolved," not as a hard failure. Automation that gated on exit == 0 should
read the JSON payload's own status fields instead of the process exit code.

The exit-code sweep, so this list is complete

After the second finding, every changed return-code line under src/seshat/cli/
and src/seshat/*.py was diffed rather than sampled. Exactly one existing
contract moved -- the pbi-mcp doctor pair above. The other changed returns are
in new code paths: spec_status.py is a new verb (documented above), and
integrations.py only gains an optional --harness flag with no change to its
existing returns. No other verb's exit-code meaning changed.

Both are disclosed rather than buried, following the precedent
docs/releases/v0.8.md set for the HR1 gold_placement change. Unlike that
case, neither of these is a bug fix restor...

Read more

Seshat BI v0.8.2

Choose a tag to compare

@Kemetra Kemetra released this 06 Aug 12:05
14bd41e

Patch release. Full detail in docs/releases/v0.8.2.md and CHANGELOG.md.

Install

pipx install seshat-bi==0.8.2

Why upgrade

Trailing anomaly detection returned wrong answers. seshat analyze run with method.id: detect_anomalies and parameters.model: trailing_mad misclassified observations on v0.8.0 and v0.8.1. Nothing in the output signalled it: the run completed, wrote schema-valid evidence, and recorded outcome: computed. An installed user could not detect the defect from the tool and could not work around it. (PR #564)

_Baseline.residual already holds observed - center, but the flag compared residual - center against the threshold, so the deviation carried the series magnitude:

deviation = (observed - center) - center = observed - 2*center

On a level-112 series, a point sitting exactly on its own baseline center produced a deviation of -112 against a threshold of 5.19, and was flagged.

The misclassification runs in both directions, because the injected term is the baseline center:

  • False positives. Two-sided on a level series: on a synthetic 48-week fixture the defect flagged 23 of 23 evaluated weeks; the corrected engine flags 1, the single injected excursion.
  • False negatives. direction: upper with a positive center suppresses real excursions. For center 112, threshold 5.19, and a genuine deviation of +6, the correct comparison flags it while the defective comparison tests 6 - 112 = -106 and does not.

So this is not uniformly a fail-open. Depending on the declared direction and the series level, anomaly evidence from v0.8.0 or v0.8.1 may contain fabricated flags, missing flags, or both.

The seasonal_mad path masked the defect in testing, because it centers on STL residuals where the center is near zero. Only trailing_mad, which centers on raw values, scaled the error with the data.

The correction is not a single subtraction. The two baselines center on different quantities, so _Baseline now carries an explicit deviation computed per baseline: the trailing baseline's residual is its deviation, while the seasonal baseline's residual must still be taken relative to the residual center. Thresholding the seasonal residual directly would shift both two-sided and directional limits whenever the residual median is displaced from zero.

Two regression tests sit on the property rather than on an incidental number: a point at its own center is never anomalous, and adding a constant to every observation must not change any verdict.

Who is affected

Only callers of seshat analyze run with method.id: detect_anomalies and parameters.model: trailing_mad. The method needs the optional stats extra and a governed analysis specification citing an approved metric contract, so the reachable surface is narrow — but every such run on v0.8.0 or v0.8.1 returned untrustworthy flags.

Anyone who accepted anomaly evidence produced by v0.8.0 or v0.8.1 should re-run the analysis on v0.8.2 before citing it. The evidence files themselves remain readable; only the anomaly:<key> estimates were wrong.

Also in this release

  • Every closed-catalog method now has an end-to-end worked example. Coverage went from one method (describe) to all eight, adding docs/worked-examples/statistical-forecast.md and docs/worked-examples/statistical-catalog.md. Both publish only numbers produced by committed fixtures, and integration tests assert those numbers, so engine drift breaks a test instead of leaving a page quietly wrong.
  • The closed method catalog marks required and optional parameters separately. forecast requires all ten of its parameters, including final_period and partial_period_policy — the same two that are optional for detect_anomalies. A contract test reads schemas/statistical-analysis-spec.schema.json as ground truth and fails when the prose disagrees in either direction.
  • A Contributor Covenant code of conduct (PR #563), completing the repository community health profile.

Release machinery

The npm package is now published from the same release leg as PyPI, with publish-npm declaring needs: publish-pypi. That guarantees ordering, not atomicity: three packages publish sequentially — seshat-bi on PyPI, then @kemetra/seshat-bi, then the unscoped seshat-bi alias — and no publish can be undone. See the per-package recovery table in docs/releases/v0.8.2.md.

All three packages are confirmed published at 0.8.2 for this release.

Verification

  • pytest tests/unit tests/contract — 4859 passed, 21 skipped
  • pytest tests/integration/test_statistical_artifact_flow.py — 9 passed
  • ruff format --check src tests and ruff check src tests — clean

Seshat BI v0.8.1

Choose a tag to compare

@Kemetra Kemetra released this 02 Aug 15:55
aec1d87

Patch release. Full detail in docs/releases/v0.8.1.md and CHANGELOG.md.

Install

pipx install seshat-bi==0.8.1

Why upgrade

The bundled governor MCP server no longer hangs. In v0.8.0, seshat_run_static_check never returned when the plugin ran the governor over stdio — over 11 minutes with no output, against a 12-second CLI baseline for the identical check. One of the six governor tools was unusable for anyone who installed the plugin, with no workaround. (#557, PR #558)

subprocess.run(...) without an explicit stdin gives the child the parent's stdin. For seshat mcp that handle is the live JSON-RPC pipe from the client: git inherited it and blocked reading it, while the parent blocked in communicate() waiting for git — and the pipe could only be fed by the MCP client, which was itself waiting for the response.

Only that one tool hung, because it is the only governor tool that shells out to git. The CLI was never affected, because there stdin is a terminal and inheriting it is harmless — which is the whole 12-seconds-versus-forever gap.

Fixed with a single gitutil.run_subprocess helper (stdin=DEVNULL plus a default timeout, so a residual stall fails loud rather than hanging), with 11 governance call sites routed through it. The dbt/dagster execution runners are deliberately excluded: they invoke user builds that legitimately outlive the shared cap and are not reachable from the read-only governor tools.

Covered by a regression test that spawns the real server and drives it over a pipe — the only shape that reproduces the defect, since the existing in-process tests return in 0.2s. Verified failing on the unpatched code before being trusted green.

Also in this release

  • Four corrected facts in the public-catalog submission guidance (#556). The runbook is copied into an external portal under a verified identity, so a wrong path or capability answer is a submission defect. It cited plugin manifest paths at the repository root that do not resolve, told the owner to declare no MCP server when both bundles ship seshat-governor, and gave a skill-count command that silently returned zero for the Claude bundle. The shipped Codex bundle README carried the same false "activates no ... MCP server" claim and was corrected at its template and regenerated.

What has not changed

  • No new capability, verb, skill, or rule. Both bundles still carry 21 skills.
  • No governance behavior changed. No tool advances a stage, grants an approval, writes a readiness artifact, or emits a score.
  • Spec 138 remains partially implemented — US2 and US3 delivered; US1, US4, and the external-acceptance half of US5 outstanding.

Note on MCP acceptance

This release fixes a defect in the bundled MCP server; it does not constitute external acceptance of that server. Spec 138 US1 (T021–T023) still requires operator-run verification in a clean workspace with no Seshat development checkout. Any public-catalog submission should declare the seshat-governor MCP server (local, read-only, stdio, no auth) and should not claim verified external MCP behavior.

Seshat BI v0.8.0

Choose a tag to compare

@Kemetra Kemetra released this 01 Aug 19:24
fc0015c

Minor release. Full detail in docs/releases/v0.8.md and CHANGELOG.md.

Install

pipx install seshat-bi==0.8.0

Headlines

  • PBIP X-Rayseshat xray builds a model graph by resolving measure/column references across parsed TMDL, reads PBIR visual bindings, and reports findings X0–X4. seshat model-diff classifies TMDL changes as semantic / cosmetic / additive / removed. Advisory and read-only: neither grants an approval, moves a readiness stage, or emits a confidence score. (#549, #550, #551)
  • The ten compass verbs now ship in the packaged bundles — the Claude and Codex bundles go from 11 skills to 21, behind a portability gate, with the capability inventory as the authored source of what ships. Spec 138 remains partially implemented (US2/US3). (#547, #548)
  • A governed statistical evidence engine (seshat analyze) — eight closed methods, strict schemas, immutable derived evidence, deterministic pending-human review. No result grants approval or changes readiness. (#529)
  • A headless TMDL doc-comment lint (seshat tmdl-doc-comment-lint) — one rule: a /// block must be followed by a declaration. Deliberately not a TMDL validator; a pass does not mean Power BI Desktop can load the model. (partial fix for #494)
  • Three further read-only surfacesseshat readiness-diff (#536), seshat cvd-evidence (#541), and seshat profile over a landed CSV/TSV/Excel file (#535).

Six new CLI verbs in total: xray, model-diff, readiness-diff, cvd-evidence, analyze, tmdl-doc-comment-lint.

One behavior change worth reading before upgrading

HR1 gold_placement now ERRORs on an unresolvable prefix (#499, #505), where it previously returned {} silently. This can newly fail a repo that was passing only because the resolution was empty.

Placement prefixes resolve against the physical bare dimension name. For a dimension declared gold.dim_product_rss, write dim:dim_product_rss.item — a schema-qualified dim:gold.dim_product_rss.item is parsed only up to the first . and will be rejected.

Classified under the bug-fix-restores-intended-behavior row of docs/operations/versioning-policy.md, which is why this release is MINOR rather than MAJOR.

Scope of this release

199 commits across 49 merged pull requests since v0.7.1, measured 363c41a..44bb00c — 158 non-merge commits (42 feat, 51 fix, 39 docs, 15 refactor). The cutoff excludes the release-preparation commits that follow it.

Spec 137 (the Finance GL genericity proof) landed in this window but ships no runtime change — it is fixtures, worked examples and mapping artifacts under mappings/, docs/worked-examples/ and benchmark/scenarios/, with no change to src/seshat/. It is evidence that the engine is not retail-specific, not a feature.

Provenance

Published to PyPI via Trusted Publishing (GitHub OIDC) with attestations, from the validated artifacts built at fc0015c. Public catalog listing (Claude plugin directory / OpenAI) is a separate owner action and has not been performed.

Seshat BI v0.7.1

Choose a tag to compare

@Kemetra Kemetra released this 24 Jul 19:23
363c41a

Seshat BI -- v0.7.1 patch release candidate

This patch candidate records the single change merged to main after the frozen
v0.7 release note (docs/releases/v0.7.md). It does not rewrite the historical
claims captured there or in any earlier release note.

Why this patch exists

The v0.7.0 tag is frozen by the repository's v* tag-immutability ruleset and
points at a commit whose packaged seshat/pbi_mcp/scan.py trips the release
artifact inspector (scripts/inspect_release_artifacts.py). Because a protected
tag cannot be moved, v0.7.0 can never publish to PyPI. This patch carries the
inspector fix forward on a fresh, publishable version.

The v0.7.0 publish attempt failed closed: the build-and-validate job blocked
and the publish job was skipped, so no v0.7.0 artifact ever reached PyPI. Every
capability described in docs/releases/v0.7.md first becomes publicly
installable with this patch.

What this patch fixes

  • Release inspector false positive blocking publication (PR #478): the
    macOS-user-path detection pattern in seshat/pbi_mcp/scan.py spelled the
    literal byte shape /Users/... that the release inspector scans shipped
    source for. The irony is structural -- scan.py is the secret scanner, and
    the flagged string was its own detection regex for leaked macOS paths in
    generated Power BI config, so the detector tripped on itself. No real path
    leaked: the matched text was /Users/[^/, i.e. regex syntax, and a repo-wide
    scan found exactly one hit. The pattern is now assembled from fragments so the
    literal never appears in shipped bytes; the compiled regex is identical and
    every detection case still fires. The inspector's regex is deliberately left
    strict -- no release guard was weakened. This follows the v0.6.1 precedent and
    a convention already used in tests/unit/test_pbi_mcp_generate.py.

Honest boundaries

  • This is a packaging-only patch: it carries no functional code, schema, or
    CLI-behavior change. The compiled detection pattern is byte-for-byte
    equivalent to the one it replaces, so seshat pbi-mcp refuses exactly the
    same generated content it refused before. Every capability claim in
    docs/releases/v0.7.md continues to apply unchanged.
  • Publication evidence is not asserted here. This candidate does not itself
    create a tag, publish to PyPI, create a GitHub Release, or submit to public
    Claude, Codex, or OpenAI catalogs. External marketplace publication and the
    GitHub Release object remain separate owner actions.

Seshat BI v0.5.2

Choose a tag to compare

@Kemetra Kemetra released this 20 Jul 11:16
f7aa26c

Seshat BI v0.5.2 — a new dashboard capability plus a batch of security and hardening fixes.

Highlights

  • seshat dashboard (#358): writes a self-contained, static HTML readiness view of the workspace — a Home page with portfolio KPIs and one card per table showing the seven-stage readiness track — from the recomputed readiness-status.yaml. No server, no external assets, theme CSS inlined, every value HTML-escaped; can write-and-auto-open. A read-only view of already-computed state — it fabricates no evidence or approvals.
  • Three credential-leak paths closed in dagster/portfolio redaction (#362, #364): a reformatted, schemeless driver error naming only the host/user of a DATABASE_URL-shaped secret could survive the whole-value replace — URI-component decomposition now scrubs each part.
  • Explicit secret-key set for dagster redaction (#357, #363): a POSITIVE ANALYTICS_DB_* credential set replaces the prefix scan, so config words (e.g. ENGINE=postgres) are no longer over-redacted while credentials stay scrubbed.
  • seshat-init writer hardening + init-project layout (#356) and the scaffold-source TOCTOU race (#345) — the follow-up tracked from v0.5.1 — are closed. The dagster command family now loads the workspace .env (#354).

Internal

  • One shared URI-redaction core (seshat/redaction_core.py) imported by the dbt, dagster, and portfolio redactors — pure refactor, no behavior change (#365).

Full detail: docs/releases/v0.5.2.md and CHANGELOG.md.

Install: pip install seshat-bi==0.5.2

Seshat BI v0.5.1

Choose a tag to compare

@Kemetra Kemetra released this 19 Jul 20:07
3b6fa31

Seshat BI v0.5.1 — a patch release with two bug fixes and one enhancement.

Highlights

  • seshat scaffold-source <table> (#339): pip-only workspaces can now produce the first Source-Ready artifact without the development repository. The three Stage-1 blank templates ship as wheel package data; the scaffolded readiness passes the RS1 governance gate as an honest unstarted journey.
  • validate / drift / value-check honor the workspace .env (#340): the live commands now load ANALYTICS_DB_* (and engine selection) from the gitignored .env exactly as the tool instructs — no more "no database connection configured" for a correctly-populated .env. No new dependency; malformed/invalid settings fail clean.
  • dbt plan surfaces the underlying parse error (#341): a failed non-database PARSE no longer emits an empty DBT_ARTIFACT_INTEGRITY: — the real Compilation Error now reaches the operator.

Full detail: docs/releases/v0.5.1.md and CHANGELOG.md.

Install: pip install seshat-bi==0.5.1

Follow-up tracked: #345 (scaffolder TOCTOU race, out of scope).