A redeploy now finishes draining browser sessions instead of being killed
Finish the drain before the door closes
fixeddeployoperators
The node's shutdown drain gave up after 8 seconds even though the container allows 60, so a redeploy killed sessions it had time to close cleanly.
#3097
· 2026-08-21
Cite code by symbol, not by line number, in the credential guides
A citation that survives the code moving
fixeddocsdevelopers
Code citations in the credential guides now name a module and symbol instead of a file and line, so they stay true when the file changes.
#3103
· 2026-08-21
Every code citation in the credential security guide now resolves
Pointers that all land somewhere real
fixeddocsdevelopers
The credential security guide no longer cites code by file and line. All 35 pointers are now module and symbol names, checked against the source tree on every CI run.
#3104
· 2026-08-21
Explain how Nightjar works, with figures, under its own nav label
The label finally cashes its cheque
addeddocsdevelopersoperators
The 'How Nightjar works' section now contains an explanation, not just a glossary.
#3118
· 2026-08-21
A session ended by a redeploy now says so, instead of later looking abandoned
Say why the session ended
fixednodedevelopersoperators
A session closed by a node redeploy recorded nothing at the time, and was later reported as abandoned - which says the client went stale when the host had actually restarted.
#3119
· 2026-08-21
Choose your organization when signing in with more than one
The sign-in page finally asks which organization you mean
addedcontroloperators
Signing in to an application while your account belongs to several organizations now shows a page asking which one to use, instead of an error naming a header a browser cannot set.
#3120
· 2026-08-21
Two explanation pages: what Nightjar refuses, and what things are not
Explain the no, not only the yes
addeddocsdevelopersoperators
The docs site gains two explanation pages: the deliberate refusals and the reasoning behind them, and the category corrections where a name suggests one thing and the system means another.
#3124
· 2026-08-21
Browser sessions can no longer reach link-local addresses on the direct route
Every route through the same gate
securitynodeoperatorsdevelopers
Sessions using split or platform egress were launched without a proxy, so their direct traffic reached the cloud metadata address unscreened. They now run through the same chokepoint every other route uses.
#3125
· 2026-08-21
Published API descriptions no longer open with an internal issue number
The first words belong to the reader
fixedsdkdevelopers
Nineteen schema descriptions in the published spec began with an internal issue number. The number moved into a source-only comment; the description now opens with what it describes.
#3126
· 2026-08-21
Serialize the CLI test that reached a process-global through production dispatch
A lock excludes only those who take it
internalclidevelopers
A test reached the process-global diagnostics context through a production dispatch without taking the test lock, racing the tests that did.
#3129
· 2026-08-21
Add the two boundary pages to the docs sidebar
A page nobody can find is a page nobody reads
changeddocsdevelopersoperators
The How Nightjar works section now lists What Nightjar refuses and What these things are not, between How it works and the Glossary.
#3130
· 2026-08-21
The SDK drift record is regenerated and CI now fails when it goes stale
The record that shows drift had drifted
internalsdkdevelopers
SDK-versus-spec coverage is now a machine-checked number instead of a snapshot someone remembered to re-run.
#3133
· 2026-08-21
A direct-path SSRF denial now leaves a per-session audit record
Both routes write it down
securitynodeoperators
An SSRF denial on the direct egress route bumped its counters but emitted no EgressAuditEvent, so the same security event the tunnel-floor deny journals was invisible per-session on that route. It now emits one.
#3143
· 2026-08-21
Move rationale out of the API spec and into the concept pages
Contract at the call site, reasons on the page
docsdocsdevelopers
Thirty-two OpenAPI descriptions shed their rationale paragraphs, which now live verbatim on two concept pages. Each field keeps a one-line pointer.
#3150
· 2026-08-21
Declare a changelog position or the contract job now fails
A position declared beats a position inferred
changeddocsdevelopers
The changelog contract job now fails a PR that declares no position at all — neither an entry nor the changelog:none label.
#3151
· 2026-08-21
act upload now says what SUCCESS does and does not mean
Set is not attached
docsmcpdevelopers
act upload issues CDP SetFileInputFiles, so it cannot observe whether the page accepted the file - but the description never said so, and consumers read SUCCESS as attachment. It now states the limit and names the discriminating field.
#3153
· 2026-08-21
act upload's receipt names what it SET on the input, not what the page attached
Set, not attached
docsmcpdevelopers
The uploadedRefs receipt said the refs were ATTACHED. They are the refs the verb resolved and set on the file input, before the page is handed anything - so a page-side upload failure is invisible to the caller.
#3156
· 2026-08-21
Make the how-it-works page's Where to go next section actually link
A named destination should be a door
fixeddocsdevelopersoperators
The concept page's closing section named three destinations in bold prose with no links. All three are now links, and each target route was verified to exist.
#3158
· 2026-08-21
Group the harvested spec rationale by the kind of mistake it prevents
Sort by the shape of the error, not the shape of the thing
changeddocsdevelopersoperators
The rationale moved out of the spec is now grouped by what it protects you from, and sits before each page's closing section rather than after it.
#3160
· 2026-08-21
Approving an access request for reach:self no longer 403s the operator
A gate no human could pass, on the surface built for exactly this
fixedcontroloperatorsdevelopers
An agent could file an access request for reach:self and no human could ever approve it. The approve gate checked the scope against the approver's own ceiling, and reach:self appears in no human role, so the click always failed.
#3165
· 2026-08-21
A blank org header no longer dead-ends a multi-org operator
One definition of no org selected, not two that agree by luck
fixedcontroloperators
On the OAuth sign-in leg, a present-but-empty X-Nightjar-Org header made a multi-org operator see an error telling them to set that same header, instead of the org picker.
#3167
· 2026-08-21
Pin the scan budget clock seam, and record the bound itself as untested
An untested bound, honestly named
internalcontroldevelopers
The provenance scan's time budget now reads a runtime clock at its three enforcement sites, with a test pinning that production behaviour is unchanged. The bound itself remains untested, and the reason is recorded in the source.
#3186
· 2026-08-21
Pin the egress-cap env shape production actually passes, not the unset one
The flag decides, not the default
internalnodedevelopers
The default-off test used remove_var, pinning the unset case. Deployment passes an empty string, which nothing pinned. Adds that arm, and fixes a lock that let the two tests race.
#3189
· 2026-08-21
Declaring an advisor origin also bounds the hosts its page fetches
One origin, many hosts
docscontroloperatorsdevelopers
The declaredAdvisorOrigins description now states that the set bounds subresources, not just navigation, and that host matching is exact with no wildcards.
#3193
· 2026-08-21
Every concept page now links back to the API reference
A pointer that only goes one way is half a link
addeddocsdevelopersoperators
The spec's doc comments point at the concept pages, but no concept page pointed back. All four now link to the API reference, in prose that already named it.
#3195
· 2026-08-21
CI now fails when a writable governance setting has no console control
A setting nobody can reach is a setting nobody can fix
internalcontroldevelopersoperators
A governance field that can be changed by API but has no control in the console now reds CI, unless it is exempted with a written reason.
#3197
· 2026-08-21
Declared advisor origins can now be edited in the console
The last field with no control
addedconsoleoperators
Data governance gains an editor for declared advisor origins, the field that previously had no console control at all.
#3204
· 2026-08-21
Advisor origins accept a wildcard, so a CDN change no longer breaks cloak
One entry, every subdomain
fixednodeoperators
A declared advisor origin can now use a leading wildcard label and will match any subdomain. Previously only an exact host matched, so a provider that generates hostnames could break a cloak session with no config change on your side.
#3205
· 2026-08-21
A drained session now closes with its own code, distinct from a plain end
A redeploy is not a refusal
addednodedevelopers
The session-ended journal event now carries a typed cause beside its human reason, and a session drained by a redeploy closes the events socket with 1012 instead of 4410.
#3213
· 2026-08-21
Add nightjar mcp install to wire a repo to a saved login
The repo names the login, never the key
addedclidevelopersoperators
nightjar mcp install points a repo's .mcp.json at a saved login, and replaces an older entry that carried an Authorization header in the same write.
#3215
· 2026-08-21
Tell docs authors that merging does not deploy the docs site
Merged is not deployed
docsdocsdevelopers
The docs app now carries a README saying a merge to main does not reach the live docs site, and how to verify a change actually shipped.
#3231
· 2026-08-21
Warn that a website merge deploys the console and ships nothing
Green, and the wrong app
docsdocsdevelopers
The public website app now carries a README saying a merge there triggers the console deploy, goes green, and ships none of the site.
#3240
· 2026-08-21
v2026.08.19.9
2026-08-20
Agents can find a page region by the hash of its content
The hash is the address
addedmcpdevelopers
A new projection_search tool asks which subtree projects to a given sha256 — the inverse of the projection-hash check that wait and act already carry.
#3013
· 2026-08-20
Pin the act response wire shape in an end-to-end guard
Pin the shape, catch the drift
internalcontroldevelopers
The workspace jail end-to-end suite now pins the shape of the act success and refusal envelopes against committed fixtures, so an unannounced field addition or removal fails CI instead of shipping silently.
#3019
· 2026-08-20
Command-scoped provenance: one call for what a command touched
Ask the command what it touched
addedcontroldevelopers
A new v1 route resolves a command span id to its occurrences: the verb, the outcome, and the artifacts it touched.
addedsdkdevelopers
The SDK gains commands.provenance, mirroring the existing artifacts.provenance.
#3020
· 2026-08-20
Provenance now records what the node did to an artifact's bytes
Two axes, not one
addedcontroldevelopers
Artifact provenance gains an optional processing field: raw, derived or unknown. Read it together with direction.
#3021
· 2026-08-20
Ask the provenance oracle about many hashes in one request
Many questions, one pass
addedcontroldevelopers
POST /v1/artifacts/provenance takes a list of content hashes and answers one entry per hash. A hash nothing produced comes back as an entry with an empty set, never a 404, so absence stays a usable answer.
#3026
· 2026-08-20
Redeploy drains browser sessions instead of stranding them
Let them out before the gate shuts
fixednodeoperators
The node now shuts down on SIGTERM, and drains live browser sessions before stopping — under a time budget, so it exits cleanly inside the container grace period.
#3030
· 2026-08-20
Report what a profile-store reclaim would remove, removing nothing
Count it before you cut it
addedcontroloperatorsdevelopers
An opt-in control worker logs what a profile-store reclaim would remove, reconciling the node's directory list against session records. It deletes nothing, and cannot: this build has no delete capability at all.
#3031
· 2026-08-20
Provenance answers now say how far the scan looked
An empty answer should say why
addedcontroldevelopers
Every scan-backed provenance response reports how many sessions it read, the cap, and which bound ended the scan.
addedsdkdevelopers
ScanExtent and ScanCompletion are exported so a client can branch on why a scan stopped.
#3033
· 2026-08-20
Record the cross-suite test collision that no single file can reveal
Your green is someone else's red
docsdocsdevelopers
AGENTS.md now records the collision class where a new test suite breaks a neighbour's global-count assertion, and why seeding-side fixes relocate the problem rather than removing it.
#3040
· 2026-08-20
The identity check in AGENTS.md passed on another agent's handle
Resolving is not owning
docsdocsdevelopersoperators
AGENTS.md told you to verify your own address with a bb send --dry-run. That proves a handle exists, never that it is yours, so the check returned a clean pass on a peer's identity.
#3043
· 2026-08-20
A CI watcher settled while two required checks did not yet exist
Absent is not incomplete
docsdocsdevelopersoperators
AGENTS.md prescribed a count floor for merge watchers. A job whose dependencies have not resolved is never created, so it cannot be incomplete, and the floor passes straight over it.
#3051
· 2026-08-20
A session with no profile no longer fails the reads that scan it
One bad row should not sink the org
fixedcontroldevelopersoperators
Provenance and session-replay reads now tolerate a session whose profile column is null, instead of failing the whole request.
#3054
· 2026-08-20
Pin the NULL-profile filter in the reclaim report so removing it turns CI red
A comment is not a signal
internalcontroldevelopers
The reclaim report reads a nullable column into a non-Option String and is safe only because its query filters the NULLs out. That filter now has a regression test instead of a comment.
#3057
· 2026-08-20
Document the four Run fields that are always null
Say what the empty fields mean
docscontroldevelopers
The API reference now says which Run fields are always null today, why, and what would change that.
#3060
· 2026-08-20
Correct why the Run targetId field is always null
A reason can expire before the fact does
fixedcontroldevelopers
The API reference said targets do not exist yet. They do - a run simply cannot be bound to one.
#3063
· 2026-08-20
Say why three API fields are always empty
An empty field can still say why
docscontroldevelopers
Three fields the API returns are never populated. The reference now says so, and says why.
#3067
· 2026-08-20
Clearer sign-in message when your account belongs to several organizations
Two organizations, one sign-in, no way to choose
fixedcontroloperators
The multi-organization sign-in page no longer tells you to run an approval from the CLI. That step does not exist on this flow, so the message now says plainly what happened and what will actually work.
#3069
· 2026-08-20
Two more ways a clean-looking issue turns out to have nothing to build
Reading the artifact is the check
docsdocsdevelopers
The dedup guidance listed two ways an issue can pass every structural check and still not be takeable. Four screens in one day found four reasons, and two of them were new.
#3072
· 2026-08-20
Give the node time to finish draining browser sessions on redeploy
Let it finish before you pull the plug
fixeddeployoperators
The node now gets 60 seconds to drain its browser sessions on redeploy, instead of the 10-second default that killed the drain part-way through.
#3075
· 2026-08-20
A seat records when its own failure mode fires hardest
Urgency is when a guess travels furthest
internaldocsdevelopers
The SW6 seat keeps a list of times it measured something correctly and published it wrongly. Two more were added, along with the condition under which it happens.
#3076
· 2026-08-20
api-types now ships spec provenance, so drift checks can answer for it
A fingerprint must cover every source
addedsdkdevelopers
api-types is generated from the OpenAPI document and the WS event schemas but shipped no record of which revisions it came from. It now stamps both, so the release check can say a bump is due instead of reporting NOT APPLICABLE.
#3077
· 2026-08-20
The documentation is reachable from the marketing site
A door nobody can find is a wall
addeddocsoperatorsdevelopers
The marketing site carried no link to the documentation at all. It now closes with one, so the explanation layer is reachable from the front door.
changeddocsoperatorsdevelopers
The docs sidebar group Concepts is now How Nightjar works, at the same rank, so it reads as an argument rather than a cabinet of terms.
#3081
· 2026-08-20
Console screens can point at the explanation for what is on them
Answer the question where the question is asked
addedconsoleoperatorsdevelopers
Reach grants and Identities now carry a contextual link into the docs, naming the question the screen raises rather than sending you to a docs front page to search.
The PageHeader showcase. After adds a third example carrying a contextual docs link, and documents the two new props. Captured from a pristine build and this branch, both asserted to have the component's styles applied.
#3083
· 2026-08-20
A docs guide can no longer claim a tool count the manifest disagrees with
A count must come from the thing it counts
addeddocsdevelopersoperators
The credentials guide said the MCP surface was a closed set of exactly 9 tools. It is 38. Both numbers now render from one validated selection, and CI refuses a tool table that has drifted from it.
#3089
· 2026-08-20
v2026.08.18.9
2026-08-19
Retention keeps every idempotency ticket a replay can still reach
Keep every ticket a replay can reach
fixedcontroldevelopersoperators
Retention keyed on session status, so it reclaimed idempotency tickets that the API would still serve replays for. It now keys on the handler's own reachability condition, and sweeps the fill-credential store too.
#2942
· 2026-08-19
Docs deprecate the env-var Bearer pattern, now that a saved login exists
A frozen copy is not a credential
deprecateddocsdevelopersoperators
Every MCP host recipe now leads with nightjar auth login. Carrying the key in an environment variable or header template is marked deprecated, with the incident that motivated it as the reason. No recipe is removed.
#2946
· 2026-08-19
Stop the recording gate's anti-vacuity control arm from flaking under load
One deadline cannot serve two opposite polarities
internalcontroldevelopers
One mock-node helper served two opposite expectations through a single timeout, so the deadline expiring was the PASS for four denial tests and the FAILURE for the arm that proves them non-vacuous.
#2949
· 2026-08-19
Terminal reach grants are listed for 90 days, then reclaimed
History has a stated length
changedcontroloperatorsdevelopers
A revoked or expired reach grant stays in the owner-scoped list for 90 days after it became terminal, and its row is then reclaimed.
#2951
· 2026-08-19
OAuth tokens are reclaimed once their grant is revoked, not once they expire
The revoked row is the evidence
fixedcontroloperators
The retention sweep deletes oauth tokens past their expiry whose grant is already revoked. An expired token under a live grant is kept: revoke reads it with no expiry filter, so deleting it would make revocation a silent no-op.
#2955
· 2026-08-19
The provenance oracle now tells you its answer may be incomplete
Empty is not not-found
fixedcontroldevelopers
The provenance route's docs presented two causes of an empty answer as the complete set and called the ambiguity a security property. A third cause, the 500-session scan bound, is a completeness limit and now says so.
#2959
· 2026-08-19
The SDK can now ask which session produced an artifact
A hash is a question
addedsdkdevelopers
artifacts.provenance(hash) resolves a content hash to the sessions that produced it, with the verb, page and time.
#2965
· 2026-08-19
A reaped session's recording is finalized before its browser is torn down
Finalize first, then tear down
fixedcontroloperators
The transport reaper tore down a crashed session's browser without first asking the node for its recording, so an opted-in capture was left unsealed and unindexed - and therefore unreadable.
#2968
· 2026-08-19
Artifacts are not collected with the session, whatever our docs said
Say what is true, and say the negative out loud
fixedcontroldevelopersoperators
The download-to-artifact endpoint promised that artifacts are garbage-collected with the session. Nothing collects them at session end.
fixedmcpdevelopers
The download_to_artifact tool carried the same false guarantee. An agent read it, ended its session, and nothing was collected.
#2971
· 2026-08-19
Dead session capabilities are reclaimed instead of waiting for org deletion
A spent key is not a record
fixedcontroloperators
A revoked or expired session capability row had no release path at all: only deleting the organisation removed it.
#2972
· 2026-08-19
Restore the reach namespace's lost documentation in the SDK
A comment must touch what it describes
fixedsdkdevelopers
The SDK reach namespace lost its docs when artifacts was inserted between the comment and the member it described. Hover and the published types showed nothing, including the note that claim is excluded on purpose.
#2976
· 2026-08-19
You can now collect a profile's unreachable artifacts through the API
Expose what exists, at the authority it declares
addedcontroloperators
POST /v1/artifacts/collect runs the node's reachability-based artifact sweep for one profile and returns what it collected.
#2979
· 2026-08-19
An upload now names the artifacts it attached
Echoed, not observed
addedcontroldevelopers
act with verb upload now returns the artifact refs it attached, on the receipt. Proving N files are attached no longer means finding N chips in a perception digest that is capped and gets denser as N grows.
#2980
· 2026-08-19
Describe what perceive actually returns in its MCP output schema
Declare the shape you send
fixedmcpdevelopers
The perceive output schema said its perception field was passed through verbatim. That is only true in full mode, and the default is compact.
addedmcpdevelopers
The 12 keys the renderer adds to perception are now declared and documented, so clients can read the shape they receive.
#2981
· 2026-08-19
Make a chromiumoxide upgrade trip the workaround it could make removable
The upgrade is the reminder
internalnodedevelopers
A same-document navigation workaround is pinned to the chromiumoxide version it was reasoned against, so the next upgrade fails the build instead of quietly outliving its cause.
#2985
· 2026-08-19
Reclaim expired controller idempotency records after a grace period
The tombstone still speaks
addedcontroloperators
The controller idempotency table now has a reaper. It was the fourth ticket store and nothing had ever deleted from it.
changedcontroldevelopers
An Idempotency-Key reused long after its retention horizon now re-executes instead of returning an expired error. Well before that, the error is unchanged.
#2990
· 2026-08-19
A fully swept run no longer reports itself as active forever
A mark that outlives its evidence
fixedcontroloperatorsdevelopers
Run status is computed on read, and its "this run never had activity" test asked whether the sessions and connections tables were empty. Once retention reclaimed those rows the test passed again, so a finished run looked new.
#2991
· 2026-08-19
Artifact provenance now reports which way the bytes flowed
One hash, two possible origins
addedcontroldevelopers
The provenance oracle now reports a direction for each artifact plus the command span that minted it. Direction is derived from a closed verb set and reports unknown rather than guessing when the verb cannot determine it.
#2992
· 2026-08-19
Locate a region by the hash of its content, not by a container that re-renders
One region, four depths
addednodedevelopers
The node can now answer which subtree projects to a given sha256, the inverse of the projection-hash check that wait and act already carry.
#2993
· 2026-08-19
The act result's delta is now a declared shape, not an untyped blob
Declare what the wire already carries
fixedmcpdevelopers
act and credential_fill declared their delta with no type at all. The wire carried 28 fields and 6 closed enums that no generated client could see.
#2998
· 2026-08-19
Find a region by the hash of its content, over the v1 API
A verb earns its own gate
addedcontroldevelopers
The v1 API can now ask which subtree projects to a given sha256 — the inverse of the projection-hash check that wait and act already carry.
#2999
· 2026-08-19
Tool descriptions no longer say no artifact collector exists
A warning outlived the fact it rested on
fixedmcpdevelopersoperators
The artifact tool descriptions told every agent that no hosted surface exposed a collector. That stopped being true when POST /v1/artifacts/collect shipped, so the text now names the endpoint and the authority it needs.
#3007
· 2026-08-19
Superseded auth-state versions now follow your org's retention window
History fades, the head remains
addedcontroloperatorsdevelopers
Captured auth-state versions older than your organisation's retention preset are now reclaimed. The active version is never removed, nor is one a live session could still resume from.
#3008
· 2026-08-19
v2026.08.17.2
2026-08-18
Docs qualify the OAuth login as remote-MCP, before a second one lands
Name it before there are two
docsdocsdevelopersoperators
Nine docs sites that said OAuth login now say remote-MCP OAuth login, so the shipped host flow stays distinguishable once nightjar auth login adds a second one.
#2853
· 2026-08-18
Docs honesty gate now checks that cited symbols exist in the tree
A citation that names nothing is not a citation
internaldocsdevelopers
A Today page that cites a symbol now fails CI if that symbol resolves to no source file.
#2857
· 2026-08-18
Artifacts now record the page they were produced against
Every artifact remembers where it came from
addednodedevelopers
Session artifacts now carry the page URL they were minted against, captured best-effort at mint time.
#2869
· 2026-08-18
Credential store errors now speak the auth surface's words
One word, one meaning
fixedclioperatorsdevelopers
Credential store errors now say credential rather than profile, which had three other meanings a reader could land on.
#2871
· 2026-08-18
Fetch a session's timeline for a time window, not just from a cursor
A cursor cannot name the ten minutes it went wrong
addedcontroldevelopers
The journal and session-activity reads take since and until, so you can ask for the window a session misbehaved in instead of paging from a cursor.
addedcontroldevelopers
Journal events now carry the tab they belong to, and the journal read takes a coarse verb filter.
#2874
· 2026-08-18
The v1 error contract now says which token the code field carries
Same name, different token
docscontroldevelopers
V1Error.code now documents that it carries the RENDER token, and which field the same token rides on the other paths that emit a Nightjar error.
#2875
· 2026-08-18
Troubleshooting now states which field carries what, on each path
Match the code, not the message
addeddocsdevelopers
A troubleshooting section stating which error field rides which path, and where to read it.
fixedmcpdevelopers
Corrected a module header that described the MCP error result as carrying only a code and a message.
#2878
· 2026-08-18
CLI help now describes the full locator grammar it accepts
Say what the flag really takes
fixedclioperatorsdevelopers
Sixteen selector flags said CSS selector while accepting eight locator forms; four that really are CSS-only were left alone.
#2879
· 2026-08-18
Network log entries now name the act that was in flight when they started
Which requests did this act cause
addedcontroldevelopers
Each network_log entry can now carry _commandSpanId - the command span in flight when that request STARTED - so act-caused traffic is identifiable without matching timestamps.
#2881
· 2026-08-18
An act receipt now names the span its network traffic is stamped with
Start from the act, not the journal
addednodedevelopers
ActReceipt now carries commandSpanId - the same key network_log entries publish as _commandSpanId - so a client can go from an act straight to the traffic it provoked.
#2882
· 2026-08-18
The console selector fields no longer claim CSS is the only form
One parser, eight forms, three surfaces
fixedconsoleoperatorsdevelopers
The Drive panel's selector inputs said "CSS selector", but the value is resolved with the full eight-form locator grammar — so seven forms were advertised as unavailable.
The session Drive panel's act selector: the placeholder now demonstrates both a bare CSS selector and a prefixed form, and the hint names all eight.
#2883
· 2026-08-18
The typed client can now ask for part of a session journal
Ask for the window, not the whole capture
addedsdkdevelopers
journal() and journalWithMeta() take an optional args object, so a caller can narrow a recorded journal by sequence cursor, time window, or verb instead of fetching all of it.
#2885
· 2026-08-18
The typed client can filter a session's console log and network capture
Take the slice, leave the document whole
addedsdkdevelopers
consoleLog() and networkHar() take an optional args object, so a caller can narrow by cursor, tab, level, URL, method or status range instead of refetching everything to poll.
#2887
· 2026-08-18
Identity lease transitions are now recorded as events
Write it down before it disappears
addedcontroloperatorsdevelopers
Taking, releasing, force-releasing and reaping an identity lease now each write an event.
#2888
· 2026-08-18
MCP handshakes are now queryable per API key, not only greppable in logs
Ask the platform, not the logs
addedcontroloperatorsdevelopers
Each MCP handshake now records its outcome per API key, so a connect-failure rate is one security-log query instead of a day of log forensics.
#2889
· 2026-08-18
Whether a command needs the server is now declared, not defaulted
Absence of a declaration is not evidence of a value
internalclidevelopers
Every operation declares whether it needs the server; the CLI reads that instead of a denylist of one.
#2892
· 2026-08-18
Look up which session produced an artifact, by its content hash
Ask the hash who made it
addedcontroldevelopers
A new provenance read on the /v1 artifacts path answers which session minted an artifact, with which verb, against which page, and when.
#2895
· 2026-08-18
nightjar auth login: a saved login, so no token ever sits in a repo file
The login names the destination, not the repo
addedclidevelopersoperators
'nightjar auth login NAME' signs you in by device flow and saves the credential to an owner-only local store under a name you choose. Nothing is typed at a prompt and no token is passed on a command line.
addedcontroldevelopers
The OAuth token response now names the binding it minted: the org and agent ids, plus their display names when the deployment has them. All value-free ids, never secret material.
#2914
· 2026-08-18
Reclaim stale MCP transport connection rows in the retention sweep
Nothing else drains this table
fixedcontroloperators
The retention sweep now deletes transport_connections rows that no live session can still be reaped through.
#2916
· 2026-08-18
The crashed-session reaper now reaches sessions that never held an identity
A filter is not a definition
fixedcontroloperators
The reaper's candidate query joined identity leases, so a session that never assumed an identity could never be a candidate for reclamation.
#2928
· 2026-08-18
The egress-audit dedup set now belongs to its session instead of the process
Owned, so nothing is left to forget
fixednodeoperators
The egress-audit drain kept one dedup set for the whole node process, keyed by session and never pruned, so entries outlived the sessions that produced them.
#2933
· 2026-08-18
v2026.08.16.2
2026-08-17
Declare the mcp serve command, its operation contract and its error family
Declared before it is built
addedclidevelopers
A repo can now declare its MCP entry as a command that names a saved login, rather than an HTTP entry carrying a credential in a header template.
#2828
· 2026-08-17
Document where the agent credential store lives, and why it refuses to guess
No fallback for a secret
docsdocsoperatorsdevelopers
The credential-security guide now states the store root, the NIGHTJAR_CREDENTIALS_DIR override, and why an unset home is an error rather than a fallback.
#2830
· 2026-08-17
The SDK now refuses a publish that would ship an uninstallable package
Publish with the tool the manifest was written for
fixedsdkdevelopers
0.1.0 reached the registry uninstallable, because npm publish neither applies publishConfig nor rewrites a workspace range. The tree is fixed for 0.1.1, and a prepublishOnly guard now refuses the wrong publisher.
#2832
· 2026-08-17
The credential security guide promised a scope clamp that no longer holds
A gate is not a wall
fixeddocsoperatorsdevelopers
The published guide said a grant can never carry a write or admin scope. Since the owner-consent addendum an owner may consent to one, so the guarantee was false in the reassuring direction.
#2838
· 2026-08-17
The publish guard now covers every package, and builds before it checks
An empty package is a broken package
fixedsdkdevelopers
api-types 0.1.0 shipped with a correct manifest and an empty tarball, so the SDK installed and imported but failed every consumer tsc. The guard is now shared, and prepublishOnly builds first.
#2840
· 2026-08-17
v2026.08.15.2
2026-08-16
The credential leaves the environment
Read at request time, not at launch
addeddocsdevelopersoperators
ADR-056 decides the agent credential binding: a local multi-profile credential store consumed by a stdio MCP proxy that attaches authorization at request time, replacing the env-var Bearer header pattern that cost a five-hour incident.
#2759
· 2026-08-16
Name the hosted URL when the CLI cannot reach a Nightjar server
Say where else the server might be
changedcontroloperatorsdevelopers
When the CLI cannot reach a server it now names the hosted platform URL as well as the local options, so a first run against the cloud does not fail with only localhost advice.
#2773
· 2026-08-16
Stop a required reach test flaking when a sibling test reaps first
Assert the row, not the batch
internalcontroldevelopers
Three reach tests asserted on the reaper's batch report instead of on the grant they were testing, so a required postgres check could fail with a zero-scan signature.
#2776
· 2026-08-16
Changelog entries can name the CLI as their component
The audience arrived, so the slot opened
addeddocsdevelopers
The changelog contract gains a cli component, so a change to the command-line tool can be classified as what it is instead of borrowing a neighbouring slot.
#2778
· 2026-08-16
Assert reaper idempotence on the row rather than a global batch counter
Two sweeps pass, the row is unchanged
internalcontroldevelopers
Four assertions in the transport reap suite compared a globally-scoped batch counter, so a sibling test's candidate could red a healthy run while never asserting anything about the row under test.
#2783
· 2026-08-16
Type-check the Windows-only code that CI could never compile
No code ships that no compiler has read
addeddocsdevelopers
CI now type-checks every crate that contains Windows-only code, instead of skipping it in silence.
#2787
· 2026-08-16
Split the credential id so a stale token binding is visible
One id says which; only two say which one, now
internalclidevelopers
A session credential now carries a stable id and a per-refresh instance id, instead of one id that conflated them.
#2789
· 2026-08-16
Ask for a fresh reach claim code when the old one is lost
One lost code, one deliberate replacement
addedcontroloperatorsdevelopers
POST /v1/reach/ensure accepts remintClaim. Declare it and the outstanding claim code is revoked and replaced atomically; omit it and repeated polls reuse the live code exactly as before.
addedmcpdevelopers
The local reach ensure tool gains the same optional remintClaim argument, defaulting to false.
#2792
· 2026-08-16
Lock the credential store to its owner on Windows, and prove it
A permission you did not verify is a permission you do not have
securityclioperatorsdevelopers
On Windows the credential store's files are now restricted to their owner, and the restriction is read back and proven rather than assumed.
#2793
· 2026-08-16
The token response now names which credential AND which instance
One stable anchor, one moving marker
addedcontroldevelopersoperators
The OAuth token response gains two value-free extension members: a credential id that is stable across refreshes, and a token instance id that is new on every refresh. Both are ids, never secret material.
#2794
· 2026-08-16
Refuse a spec check that would compare the branch against itself
A file is not the file you asked for
fixeddocsdevelopers
A spec drift check could fetch its baseline from the wrong commit and report no drift forever, without ever failing.
#2796
· 2026-08-16
Reach claim now retires every superseded join token
One live key at a time
securitycontroloperatorsdevelopers
Claiming a reach grant now revokes the join tokens it supersedes, so an older secret stops authorizing a daemon join the moment a newer one is issued.
#2798
· 2026-08-16
Refuse to open a credential store on a root we cannot lock
A locked door in an open corridor is a locked door
securityclioperatorsdevelopers
Opening the credential store now locks and checks its directory first, and refuses rather than proceeding when it cannot.
#2800
· 2026-08-16
Add the MCP proxy credential-attach policy for ADR-056 C2
The credential goes one place only
addedmcpdevelopers
The stdio MCP proxy re-reads its credential per request, sends it only to the profile's pinned origin, and reports which credential it attached without ever printing it.
#2806
· 2026-08-16
Document the agent credential store's shipped storage guarantees
Storage is part of the security model
docsdocsdevelopersoperators
The credential security model now covers where an agent's own platform credential lives on disk, and what the file backend guarantees about it.
#2812
· 2026-08-16
Motto gate: arcs are no longer rejected for their flags
fixeddocsdevelopers
The changelog gate read an elliptical arc's flags and radii as coordinates, so any motto drawn with a curve failed the safe-band check wherever its art actually sat. Path data is now parsed per command.
#2817
· 2026-08-16
Guard the workspace member and node Dockerfile COPY invariant
A member with no COPY line is a build that cannot start
internalnodedevelopers
Adding a crate to the workspace without a matching COPY line in the node Dockerfile now fails a lane-tooling arm that names the crate, instead of failing the image build much later.
#2818
· 2026-08-16
Refuse a pasted credential where a saved login name is expected
A token is not a name
securitymcpoperatorsdevelopers
Pasting a Nightjar key where a saved login name belongs is now refused, instead of being repeated back inside the error message.
#2821
· 2026-08-16
Pin an MCP origin to an IPv6 address without naming a port
The brackets are the boundary
fixedmcpoperatorsdevelopers
A bracketed IPv6 literal without a port was refused, because the authority was split on its last colon and an IPv6 address carries colons inside the host.
#2822
· 2026-08-16
Changelog summaries may now name the identifier they are about
changeddocsdevelopers
The underscore enters the summary allowlist, so an entry can write NIGHTJAR_REQUIRE_DB_TESTS instead of circumlocuting it. Headlines keep the narrow set and stay scannable at chip size.
#2823
· 2026-08-16
Credential refusals name the profiles you have, never the one you typed
Answer the next question, not the last mistake
securitymcpoperatorsdevelopers
Pasting a credential where a profile name goes no longer puts it into an error message, and so into every log or screenshot that captures one.
#2824
· 2026-08-16
The changelog contract now tells you what to do when no component fits
Count the gap you cannot see
docsdocsdevelopers
The live contract now carries the rule for declaring changelog:none when no component fits, so an author meets it where they already look.
#2825
· 2026-08-16
v2026.08.14.7
2026-08-15
The grant screen stops claiming a key was shown when none was minted
Say only what happened
fixedconsoleoperators
Approving an access request now reads the receipt before deciding what to show, instead of always revealing a secret.
The access requests screen, where approving a request decides between revealing a key and handing off to pickup.
#2692
· 2026-08-15
Add the changelog authoring flow: a finalize script and a skill
Draft it, then give it a number
addeddocsdevelopers
A finalize script promotes your draft into its PR directory and stamps the number.
addeddocsdevelopers
A changelog-entry skill covers the fields, the prose rules, and how to draw a motto.
#2695
· 2026-08-15
A person on the OAuth approval leg gets a page, not a JSON blob
A human leg deserves a human answer
fixedcontroloperators
The three browser-facing legs of the device-approval flow now render a titled HTML error page instead of the API's JSON error body.
#2696
· 2026-08-15
The changelog is a page you can read, not a file you have to find
Every change, drawn and dated
addeddocsoperatorsdevelopers
The docs site gained a changelog page that renders every shipped entry, newest first, with its drawing.
#2697
· 2026-08-15
Report a suppressed screenshot as a confirmed failure, not as never started
The capture ran; the answer never arrived
fixednodedevelopers
A screenshot withheld because a secret field could not be safely redacted now reports its outcome certainty as a confirmed failure, not as an operation that never started.
fixednodedevelopers
The same corrected certainty is visible to MCP clients reading the error envelope of a suppressed screenshot.
#2701
· 2026-08-15
Approving a device sign-in now works when you are signed out
The code survives the trip
fixedcontroloperators
Following a device sign-in link while signed out used to drop the code and leave you on the console with nothing to approve. The approval page now renders after you log in.
changedcontroloperators
If you belong to more than one organisation, the approval page now asks which one to approve as, instead of returning an error that named an HTTP header.
#2713
· 2026-08-15
The console tells you when your build is behind the changelog
You are three releases behind
addedconsoleoperators
A banner appears when the console you are running is not current with the shipped changelog, and links to what you are missing.
#2719
· 2026-08-15
Drive the device-grant approval walk against a real control
Assert the form, not the status
internalcontroldevelopers
The device-grant approval leg is now exercised end to end against a real control and a real postgres, covering the six states a fixture can hold honestly.
#2720
· 2026-08-15
Pickup grants now say how long the agent has to collect its key
A window you can see closing
changedconsoleoperators
Approving a pickup grant now shows when the collection window closes, instead of only saying the agent will fetch its own key.
#2724
· 2026-08-15
A map of how work is modeled here
The map names what the territory assumes
addeddocsdevelopers
A new repo-root reference, WORK CONCEPTS, explains how work is modeled: the units of design, work, planning, tracking, specification and memory, their relations, and which concepts are materialized versus convention versus implicit.
#2725
· 2026-08-15
Retire the hand-maintained changelog and preserve its releases on the site
Nothing was deleted, only moved
changeddocsdevelopersoperators
The changelog page now carries the two releases that predate the per-PR system, under a Before the per-PR system section, and the root file is a dated pointer rather than a second source of truth.
#2728
· 2026-08-15
Add a console screenshot tool that refuses to shoot a broken page
Better no picture than a plausible one
addeddocsdevelopers
changelog-capture takes the console screenshots this changelog has required since day one, and refuses rather than write one it cannot vouch for.
addeddocsdevelopers
It refuses an over-size capture before the browser starts, with the arithmetic and a remedy.
#2732
· 2026-08-15
Flag path segments that could hide a test input from the CI gate
A short list beats a silent zero
addedcontroldevelopers
A guard now keeps an annotated review list of every path built from chained join() literals, and fails only on one whose segments could compose a path the CI filter drops.
#2733
· 2026-08-15
Underline inline links on the docs site, and put that site in the a11y net
A link you can find without colour
fixeddocsdevelopersoperators
Inline links in docs prose are underlined, so they are distinguishable without relying on colour. Nine of twelve pages carried this, and it was the only serious accessibility violation on the whole site.
internaldocsdevelopers
The docs site is now covered by the accessibility job, which previously ran two other apps and had no test files at all for this one.
#2736
· 2026-08-15
Pin that an opted-out org can never be handed self-reach by the key template
A gate is only as good as its refusal
internalcontroldevelopers
The agent-key template's opt-in condition now has a negative arm on the mint path: an org that has not enabled agent self-reach must never be handed reach:self.
#2739
· 2026-08-15
Show the changelog reminder on the checks tab, and say when it was not checked
A warning nobody reads is not a warning
changeddocsdevelopers
The entry-contract check now writes its advisories to the run summary, where they are visible without opening a log.
fixeddocsdevelopers
Running the check on your own machine now says that it did not look at whether this branch owes an entry.
#2745
· 2026-08-15
A key mint now says when the agent template did not apply, and why
A 2xx should not hide a surprise
addedcontroldevelopers
The 201 from POST /v1/keys now carries templateApplied, plus a closed-enum reason when the agent-key template was eligible but something blocked it.
#2750
· 2026-08-15
Verify which build a site is actually serving, not just that it answers
The deploy already told us; nobody was reading
addeddeployoperators
A deploy can now be checked against the build it shipped, rather than against a 200. Both sites answer 200 on every path, so the old check could not tell a current site from one serving an old build.
#2760
· 2026-08-15
Links inside prose are underlined again, everywhere, by default
Colour is not an affordance
fixeddocsoperatorsdevelopers
An inline link in a block of text no longer relies on colour alone to be recognisable as a link.
#2761
· 2026-08-15
The public changelog stops linking where visitors cannot follow
A link a visitor cannot follow is worse than none
fixeddocsoperatorsdevelopers
Every reference on the public changelog page that pointed into the private source repository is now plain text, so a visitor no longer clicks through to a login wall.
#2762
· 2026-08-15
The access-request deep link no longer says a pending request is resolved
Say only what you can see
fixedconsoleoperators
Opening a request deep link while a different org is active told you the request was already resolved. It now says only that the request is not in this org's queue.
The deep-linked request is absent from the active org's queue. Before: the note declares it already resolved with nothing left to action. After: the note states only that it is not in this org's queue, and offers the org switch.
#2763
· 2026-08-15
Tell the two screenshot refusals apart, so nobody hunts a build that works
Two silences that need opposite answers
fixeddocsdevelopers
When a capture refuses because it cannot find your text, it now says whether the page rendered or not.
#2764
· 2026-08-15
The deploy verify takes a ref, so an expected build cannot be mistyped
Do not check for the mistake; remove the chance
changeddeployoperators
The expected build can now be given as any ref, resolved internally, instead of a copied commit id. A ref has nothing to transcribe, and a bad one is reported as a caller error rather than as a failed deploy.
#2770
· 2026-08-15
v2026.08.13.4
2026-08-14
Rotate a key with no paste: the operator initiates, the key picks itself up
The last paste, removed
addedcontroloperatorsdevelopers
Rotating an agent credential no longer moves a secret by hand. The operator initiates the rotation, and the replacement is minted only when the key itself collects it.
#2682
· 2026-08-14
Add the illustrated per-PR changelog and its contract gate
Every PR tells its own story
addeddocsdevelopers
Every PR now ships a small illustrated changelog entry: what changed, who it affects, and a drawing.
addeddocsdevelopers
A CI gate validates every entry: schema, filing, prose, illustration and screenshots.
#2683
· 2026-08-14
Access request audits now name the human who approved them
A record that names a person
addedcontroloperators
An access request actioned by a signed-in human now records that person, not only the key they acted through. A row names a key approver or a human approver, never both.
#2684
· 2026-08-14
Refuse a mistyped access request instead of accepting it silently
A typo should not look like success
fixedcontroldevelopers
Filing an access request with a misspelled field now fails with a 400 that names the offending field. Previously the unknown field was ignored and the request was accepted, so a typo produced a scopeless request that looked like success.
addedcontroldevelopers
The create and status responses now echo back the scopes and delivery mode as recorded, including the defaulted delivery mode, so a caller can confirm what was actually stored.
#2687
· 2026-08-14
A malformed key-mint body now returns a readable error, not a bare 422
Refusing is only half; being readable is the rest
fixedcontroldevelopers
Sending a malformed body to the key-mint route now returns the normal error envelope, which names what was wrong. Previously the rejection arrived as a bare 422 with no envelope, so the explanation was discarded before the caller saw it.
#2693
· 2026-08-14
Before the per-PR system
Releases before ADR-055 — the decision that introduced the per-PR changelog you are reading —
were recorded by hand in the project's root CHANGELOG.md. That file is now retired
and its contents are preserved here unchanged, so this page is the complete record.
v2026.06.28.1 — 2026-06-28
⚠ BREAKING — egress
intranet_mode is now enforced unconditionally. A cloud session's
tunnel reach to undeclared private/loopback hosts (RFC1918, CGNAT, IPv6-ULA
literal IPs, loopback IPs, and localhost-family names) is now denied unless the org sets intranet_mode=true in governance — regardless of the NIGHTJAR_TUNNEL_REQUIRE_DECLARED operator
switch. Previously, with that switch at its default (off), private/loopback tunnel reach was
permitted. Every org defaults to intranet_mode=false, so any org
relying on undeclared private or loopback tunnel automation must turn intranet mode on
(Settings → governance, org:admin), or declare the specific host/CIDR on the
network's allowlist (a declared target stays reachable even with intranet mode off). The
always-on egress floor (cloud-metadata 169.254.169.254,
link-local, platform-internal CIDRs) and the env screens
(NIGHTJAR_EGRESS_SCREEN_INTERNAL, NIGHTJAR_PLATFORM_CIDRS) are
unchanged — only the private/loopback class decision moved under intranet_mode. (#653; ADR-021 amendment.) Rollback: deploy/deploy.sh --version v2026.06.27.6.
Added
Org capture-policy v1 (#652): a per-org default capture_mode (minimal / standard / diagnostic / forensic — the one capture ordinal the node enforces on
the start_session wire), alongside the existing per-org network_log default (all four tiers, node-enforced). Both are
authored from Settings → Data governance (org:admin). Migration 0027 is additive and nullable (NULL = no org default → the session falls through to the
node default diagnostic), so existing orgs are unchanged. The other model knobs
(separate journal/screenshots/dom_perception, viewport_recording, credential_fill_window) are deliberately not authored: the node has no per-facet param, so a separate org column would
be inert. (ADR-015 §8.)
Cross-language summarize() parity gate (#651): shared fixtures
assert the Rust (replay.rs) and TypeScript (real.ts) journal-event
summarizers produce identical output; CI fails on divergence. (Codegen-unification of the two
summarizers stays deferred; one best-effort fallback arm is a tracked known-divergence.)
Tunnel egress-floor integration test (#649): asserts the never-allow floor
denies a cloud-metadata target on the live CONNECT data path, not just in isolation.
Internal / architecture
Arch-tier guard (#648): a new rs-foundation-data-tower tier in .nj-arch.toml machine-enforces the nightjar-data decomposition's
no-back-edge invariant — the three pure leaves (nightjar-net-registry, nightjar-perception-data, nightjar-session-data) may depend down on rs-foundation but the base can no longer depend up on
them. nightjar-profile-data deliberately stays at rs-foundation (the
base legitimately depends on its ProfileSpec).
v2026.06.27.6 — 2026-06-27
Console power-user kernel (ADR-030) landed, with the design-system debt burned
down: every list screen sits on the kernel and the legacy ExpandableTable/ExpandableRow primitives are removed; an accessibility
gate guards the showcase.
nightjar-data god-crate decomposition (#601): three leaf crates
extracted (nightjar-net-registry, nightjar-perception-data, nightjar-session-data), plus nightjar-svc and ws-bind split into per-responsibility modules.
App-Surface hardening (ADR-033 Slice 1): loopback-only egress floor with
DNS-rebinding / TOCTOU dial-pinning on attach/backfill/observer, a deterministic size cap on
imported app-evidence payloads, and a perceiveControls() advisory instead of a
silent drop.
Org-default network-capture tier + honest /trust disclosure (#416 v0, #420), plus a per-agent default network_log tier with New-session
pre-fill (#417).
Migration-gate hardening (fail on duplicate / non-increasing migration version), the
architecture size-gate turned into a tightening ratchet, and adversarial KMS envelope-crypto
tests.