Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
625 commits
Select commit Hold shift + click to select a range
a5fff04
feat(orgs): an org id that would take another org's notify hooks, or …
claude Oct 8, 2026
7d0584f
fix(studio): the journeys' notify hints name this org's hook variable…
claude Oct 8, 2026
f6bfa00
test: expectations follow the host's path rules — an env path through…
claude Oct 8, 2026
b87fc50
test(fixtures): a child's environment as Windows reads it — the fetch…
claude Oct 8, 2026
0b17ef6
test: a refused connection goes to 127.0.0.1:2, a port nothing hands …
claude Oct 8, 2026
55575ef
test(browser): an absolute OBSERVOGRAM_PLAYWRIGHT is imported as a fi…
claude Oct 8, 2026
9ed56b1
feat(tools): tap-summary — the end of a CI log for a node --test TAP …
claude Oct 8, 2026
e4f932a
test: every wall-clock bound the runner can miss prints what it measu…
claude Oct 8, 2026
9ebfe32
test(store): a child's output is read to its end on Windows — child()…
claude Oct 8, 2026
51d8439
test(journey): the hung receiver's bound: line is the time past its t…
claude Oct 8, 2026
5ba7d0d
ci: a Windows leg — npm ci && npm test on windows-latest, Node 22.16.…
claude Oct 8, 2026
2de4373
docs: Windows is tested in CI — README "Platforms", Quickstart and th…
claude Oct 8, 2026
de5f2bd
fix(studio): in the identity and open postures too, the MCP panel's n…
claude Oct 8, 2026
104f6fc
fix(journeys): on Windows a studio-run journey's org scope compares p…
claude Oct 8, 2026
aeb61bc
fix(server): the policy re-check's approved-host submit is sent again…
claude Oct 8, 2026
9cd8233
fix(store): on Windows the export, in-place, purge-org, backup and re…
claude Oct 8, 2026
b133894
docs(journeys): notify hooks — DOWNSTREAM §17, MCP_INTEGRATION, READM…
claude Oct 8, 2026
bcedacf
fix(server): under OBSERVOGRAM_AUTH=off the open loopback server's re…
claude Oct 8, 2026
eabd432
fix(docs): the policy-worker journey names the flakes the suite measu…
claude Oct 8, 2026
569d9e6
fix(docs): the policy-worker notes say the 502 under node --max-old-s…
claude Oct 8, 2026
6832765
fix(server): evaluatePolicy's doc says a worker that fails counts as …
claude Oct 8, 2026
a2b9556
fix(journeys): a delivery error never carries an IPv6-literal hook's …
claude Oct 8, 2026
fda8daf
fix(studio): after a failed read of the MCP policy, an empty list rea…
claude Oct 8, 2026
13f79cc
fix(journeys): an org whose every notify hook name another org's id t…
claude Oct 8, 2026
bd930a9
fix(journeys): a run's notify refusal names the file the run loaded —…
claude Oct 8, 2026
fb0cfc9
fix(docs): the policy worker's line names the error's class only for …
claude Oct 8, 2026
6916095
fix(journeys): on Windows a studio-run journey's org scope refuses a …
claude Oct 8, 2026
e86c979
fix(journeys): a delivery error never carries a hook host under 4 cha…
claude Oct 8, 2026
80ed264
fix(studio): a picker's read again after a failed policy read unreads…
claude Oct 8, 2026
2725555
fix(journeys): the start never reports an org's own notify hook as a …
claude Oct 8, 2026
f75eb34
fix(test): the path-comparison suites run the default host once on a …
claude Oct 8, 2026
e2ece6a
fix(studio): the Neuron view's Notification row says the server's ref…
claude Oct 8, 2026
a407d9e
fix(test): S10 holds each suites, summary and compare step whole, eve…
claude Oct 8, 2026
9a30180
fix(test): the NTFS fixture's header names both suites it proves the …
claude Oct 8, 2026
d545706
fix(studio): the open loopback subtest pins Test connection's nothing…
claude Oct 8, 2026
d6ba5cd
fix(tools): tap-summary reads a TAP cut inside its totals as an unfin…
claude Oct 8, 2026
b2a30ec
fix(test): a failing assertion in test-tap-summary shows each line th…
claude Oct 8, 2026
51bb951
fix(journeys): the schedule snippets tell a token refused beside the …
claude Oct 8, 2026
f6ed1b5
fix(ci): validate's suites step times out at 8 minutes, twice its slo…
claude Oct 9, 2026
a85690f
fix(docs): the CHANGELOG's notify follow-up says what its head does —…
claude Oct 9, 2026
e95bdd6
fix(server): the settings policy loads without the id clocks — a load…
claude Oct 12, 2026
1056e2a
fix(tools): tap-summary --win32-skips readme with no README.md in the…
claude Oct 12, 2026
ebd4e51
fix(studio): a notify hook's names break inside the Neuron view's foc…
claude Oct 12, 2026
f8dabe5
fix(studio): the Neuron view's refusal line says "not run" once — The…
claude Oct 12, 2026
6442a89
fix(test): S9 runs --compare on the three shapes CI passes — the floo…
claude Oct 12, 2026
4f769e2
fix(studio): a picker's failed read never takes the list another read…
claude Oct 12, 2026
50c6f63
fix(docs): DOWNSTREAM §17.2's step 1 says its grep's packB.mcp.authEn…
claude Oct 12, 2026
a037bde
fix(tools): tap-summary cuts each line of an unfinished run's tail at…
claude Oct 12, 2026
5d01640
fix(journeys): on Windows a studio-run journey's org scope places a l…
claude Oct 12, 2026
843e9d9
fix(tools): tap-summary reads a capture in which npm test never start…
claude Oct 12, 2026
2eb24cb
fix(studio): beside a failed read of the MCP policy the pickers draw …
claude Oct 12, 2026
f5acc1a
fix(tools): tap-summary's capture command hands the shell the file as…
claude Oct 12, 2026
f26bda4
fix(server): evaluatePolicy answers a policy without rules — none, or…
claude Oct 12, 2026
3383b6a
fix(test): S6 holds the verdict to a failing leaf on its own — totals…
claude Oct 12, 2026
a061828
fix(docs): the CHANGELOG sizes the Windows step timeout as the workfl…
claude Oct 12, 2026
bc30c14
fix(studio): the deploy history's roll back toast is one sentence ove…
claude Oct 12, 2026
cdaafa0
fix(store): on Windows the store's checks place a path by file id acr…
claude Oct 12, 2026
e3668d7
fix(docs): the bundle build's settings-policy loader keeps the id clo…
claude Oct 12, 2026
36b358b
fix(docs): the README's journey scope says what "outside the workspac…
claude Oct 12, 2026
e708720
fix(studio): beside a failed read of the MCP policy the picker's hint…
claude Oct 12, 2026
ee81f9a
fix(tools): tap-summary cuts each line of a failure's annotation at 5…
claude Oct 12, 2026
6a8048b
fix(test): S10 holds the report-command step whole, as it holds the s…
claude Oct 12, 2026
b633b09
fix(docs): the CHANGELOG says what an empty capture's block names — t…
claude Oct 12, 2026
7f9e902
fix(journeys): the schedule snippets tell an org whose every notify h…
claude Oct 12, 2026
c67ee54
fix(studio): ada's deploy-modal subtest waits for the first opening's…
claude Oct 12, 2026
23e1300
fix(server): evaluatePolicy never rejects for a policy whose rules li…
claude Oct 12, 2026
9017c0c
fix(server): the pass-through's 409 for a missing acknowledgement say…
claude Oct 12, 2026
1ba25bd
fix(store): on Windows a path through a share no file id places may l…
claude Oct 12, 2026
4c36065
fix(docs): the CHANGELOG's roll back toast before is develop's — "Cho…
claude Oct 12, 2026
5e708d8
fix(docs): the README's journey scope on Windows says a path is read …
claude Oct 12, 2026
8bc61c8
fix(studio): the server-settings modal draws the acknowledgement of a…
claude Oct 12, 2026
e4aef09
fix(studio): the notify hints tell an org whose every notify hook nam…
claude Oct 12, 2026
9a7311a
fix(journeys): the schedule snippets tell another of the org's hook t…
claude Oct 12, 2026
cd870a6
fix(classify): the id clocks charge a pattern its own work — the smal…
claude Oct 12, 2026
4a51e42
fix(tools): tap-summary --win32-skips readme on a README.md that stat…
claude Oct 12, 2026
55f1932
fix(test): S10 holds the windows and node-floor jobs to end with the …
claude Oct 12, 2026
93d5325
fix(docs): the CHANGELOG's before for the pickers beside a failed pol…
claude Oct 12, 2026
bc18be3
fix(journeys): the schedule snippets tell the org's hook token named …
claude Oct 13, 2026
6f38599
fix(lib): one collation for every tools/lib sort — localeCompare(…, '…
claude Oct 13, 2026
bc8a653
fix(tools): tap-summary shows a failure's error lines behind `| `, as…
claude Oct 13, 2026
5cbfcf7
fix(journeys): the schedule snippets tell a name of the org's hook sh…
claude Oct 13, 2026
03a5c72
fix(studio): the tick a pass-through 409 asks for keeps the line aski…
claude Oct 13, 2026
dc9ff00
fix(store): on Windows a path through a share that cannot be reached,…
claude Oct 13, 2026
488259f
fix(tools): tap-summary reads a CI run step's own `command not found`…
claude Oct 13, 2026
50b72fc
fix(studio): the taxonomy binds as it is served — compileTaxonomy and…
claude Oct 13, 2026
131e7ab
fix(studio): Deploy in the static bundle — explained instead of openi…
claude Oct 13, 2026
40730fc
fix(classify): the CPU clock overturns a wall-clock refusal only by m…
claude Oct 13, 2026
9a56cb3
fix(studio): a declared action that carries a field the rule a pass-t…
claude Oct 13, 2026
1d1c8f8
fix(docs): README's GET /api/journeys/:name/runs row says what a reco…
claude Oct 13, 2026
3105bbd
fix(server): the pass-through's 409 says unevaluated: true for a valu…
claude Oct 13, 2026
302e28c
fix(store): on Windows a share of another machine cloned from the wor…
claude Oct 13, 2026
58ca282
feat(bundle): every bundle carries Observogram's MIT licence — a text…
claude Oct 13, 2026
7516bbc
feat(bundle): npm packages from the lockfile — a bare import a listed…
claude Oct 13, 2026
0d822ab
fix(server): evaluatePolicy never rejects for a rules list that canno…
claude Oct 13, 2026
5cbfb5b
fix(server): the policy re-check case pins that the pass-through's 40…
claude Oct 13, 2026
de01ad8
fix(tools): the vendor manifest's purity rule sees `process?.` and al…
claude Oct 13, 2026
5014ca5
feat(bundle): retrofeed in the bundle — POST /api/packs/:id/retrofeed…
claude Oct 13, 2026
fa5f330
fix(studio): BROWSER 14 pins that a submit the 409's box does not blo…
claude Oct 13, 2026
4301eb9
fix(studio): BROWSER 15 pins that a later 409 naming another rule add…
claude Oct 13, 2026
cb1263e
fix(store): on Windows a file id only makes a store check more conser…
claude Oct 13, 2026
63cf61e
fix(classify): the default id clock is driven on win32 and off it — i…
claude Oct 13, 2026
faee9ad
fix(store): on Windows purge-org refuses a users file recorded throug…
claude Oct 13, 2026
849eb58
feat(bundle): Compare in the static bundle — GET /api/diff in the shi…
claude Oct 13, 2026
c8278f9
feat(bundle): the service audit report in the bundle — GET /api/packs…
claude Oct 13, 2026
2e696b2
fix(classify): a first pass over the budget but within twice it is re…
claude Oct 13, 2026
c6b3c20
fix(studio): the static posture's remedies — every remedy a bundle re…
claude Oct 13, 2026
ca4983b
fix(studio): a declared action that carries a field a pass-through 40…
claude Oct 13, 2026
0278fc7
test(bundle): Compare in Chromium — the in-page diff byte-equal to a …
claude Oct 13, 2026
c85f6f2
docs(classify): the id-clock entries say what the re-time cannot do —…
claude Oct 13, 2026
953a7b9
build(docker): the image carries LICENSE
claude Oct 13, 2026
d7cb569
docs(studio): the server-named box goes on an edit of any value but a…
claude Oct 13, 2026
fcf2a74
docs(bundle): Compare in the static bundle — DOWNSTREAM §10 (what the…
claude Oct 13, 2026
b2e99f7
Merge pull request #154 from MoebiusX/codex/studio-followups
MoebiusX Oct 13, 2026
8d92c4b
Merge branch 'develop' into codex/policy-worker
MoebiusX Oct 13, 2026
234d363
Merge pull request #155 from MoebiusX/codex/policy-worker
MoebiusX Oct 13, 2026
2915789
fix(tools): tap-summary shows the runner's older command form in the …
claude Oct 13, 2026
7881c8f
docs: restore #155's CHANGELOG and UPDATE_JOURNEY entries that its de…
claude Oct 13, 2026
e5f68ec
Merge origin/develop (234d363, #154 and #155) into codex/journey-noti…
claude Oct 13, 2026
b6ec1dd
Merge codex/restore-policy-worker-docs (#155's restored docs) into co…
claude Oct 13, 2026
6abf399
Merge origin/develop (234d363, #154 and #155) into codex/id-clock-tol…
claude Oct 13, 2026
640cb1b
Merge codex/restore-policy-worker-docs (#155's restored docs) into co…
claude Oct 13, 2026
6ed7277
fix(test): the jumping clock that pins the settings policy's untimed …
claude Oct 13, 2026
5f76bf9
docs: re-chain journey-notify-env-ownership's eight Tests pairs from …
claude Oct 13, 2026
d84671a
fix(tools): tap-summary --compare shows a harness file in quotes, as …
claude Oct 13, 2026
9217110
docs: re-chain the id-clock follow-up's Tests pair from the restored …
claude Oct 13, 2026
3203811
docs(classify): the policy-worker and id-clock texts agree after the …
claude Oct 13, 2026
03ca22e
Merge origin/develop (234d363, #154 and #155) into codex/windows-path…
claude Oct 13, 2026
ffbc198
Merge codex/restore-policy-worker-docs (#155's restored docs) into co…
claude Oct 13, 2026
59458c6
Merge origin/develop (234d363, #154 and #155) into codex/windows-ci
claude Oct 13, 2026
4f22861
Merge codex/restore-policy-worker-docs (#155's restored docs) into co…
claude Oct 13, 2026
335b3ad
docs: re-chain windows-path-scope's Tests pairs from develop's restor…
claude Oct 13, 2026
64ace92
docs: re-chain the Windows CI leg's Tests pairs from develop's restor…
claude Oct 13, 2026
29f7442
fix(studio): Remediate's deploy texts in the static bundle — no hint,…
claude Oct 13, 2026
cbe83f4
fix(tools): tap-summary shows a `##[` in an annotation's file= as `#\…
claude Oct 13, 2026
00248ca
Merge pull request #160 from MoebiusX/codex/restore-policy-worker-docs
MoebiusX Oct 13, 2026
471776f
fix(studio): Remediate's unavailable decision buttons in the static b…
claude Oct 13, 2026
4123bc7
Merge pull request #156 from MoebiusX/codex/windows-path-scope
MoebiusX Oct 13, 2026
7441c45
test(tools): tap-summary --compare holds every harness difference to …
claude Oct 13, 2026
defe2d7
fix(tools): tap-summary --win32-skips readme's refusals show a `##[` …
claude Oct 13, 2026
c89e472
test(tools): tap-summary --compare's green line holds a harness file'…
claude Oct 13, 2026
c175c56
Merge origin/codex/windows-ci (develop 234d363 and #160's restore) in…
claude Oct 13, 2026
cba293d
Merge origin/develop (4123bc7, #156) into codex/windows-ci
claude Oct 13, 2026
7085377
docs: the CHANGELOG's tap-summary entry names every place the summary…
claude Oct 13, 2026
f1c8b91
fix(store): on Windows purge-org refuses a users file whose recorded …
claude Oct 13, 2026
ca88dba
fix(studio): the static bundle's unavailable deploy controls without …
claude Oct 13, 2026
ce75fd2
test(store): the store paths suite pins purge-org's refusal descripti…
claude Oct 13, 2026
7c3ec00
Merge origin/develop (4123bc7, #156) into codex/journey-notify-hooks
claude Oct 13, 2026
e3be07c
fix(studio): the static posture's no-live-pack texts over a live Pack…
claude Oct 13, 2026
d4d524a
docs: re-chain journey-notify-env-ownership's eight Tests pairs from …
claude Oct 13, 2026
203625b
fix(studio): the compiler's Deploy to live in the static bundle names…
claude Oct 13, 2026
c97baed
Merge origin/develop (4123bc7, #156) into codex/id-clock-tolerance
claude Oct 13, 2026
f67644a
docs: re-chain the id-clock follow-up's Tests pair from develop's 142…
claude Oct 13, 2026
e82a7a4
fix(bundle): the parity suites ask a child server on a connection of …
claude Oct 13, 2026
2a7e569
fix(bundle): the mutation rows' named tests bite — T3 pins the four p…
claude Oct 13, 2026
5cbd8d1
fix(docs): the Chromium parity claim says where it runs — README and …
claude Oct 13, 2026
66b5beb
fix(store): on Windows purge-org refuses a users file whose recorded …
claude Oct 13, 2026
0112913
fix(studio): the static remedies say "the <product> server", not an a…
claude Oct 13, 2026
83c6cd9
fix(docs): the CHANGELOG counts the deploy controls a bundle without …
claude Oct 13, 2026
817084b
fix(tools): tap-summary shows a `##[` in the TAP file's path as `#\#[…
claude Oct 13, 2026
e2e950f
fix(store): on Windows purge-org refuses a users file recorded throug…
claude Oct 13, 2026
91e3c7f
fix(studio): the compiler's Deploy to live on a generated board in th…
claude Oct 13, 2026
11ee368
fix(studio): Remediate's strategy cards that need a live pack say, in…
claude Oct 13, 2026
d6120cc
fix(store): purge-org decides whether it would delete the users file …
claude Oct 13, 2026
b83d0ff
fix(store): purge-org decides a recorded users file that does not exi…
claude Oct 13, 2026
0f25ead
docs: README's "Purge A Removed Org" names what purge-org refuses bef…
claude Oct 13, 2026
e76efb7
fix(studio): the compiler's list names the server first on a generate…
claude Oct 13, 2026
af6a3d3
fix(studio): the Assessment's comparison with no baseline, in a bundl…
claude Oct 13, 2026
90e0fc5
test(store): the users-file place suite fails when purge-org's walk f…
claude Oct 13, 2026
4070262
fix(studio): Remediate's strategy cards drawn disabled in the static …
claude Oct 13, 2026
ad93aea
fix(store): purge-org takes <base>/users.json, when no users file is …
claude Oct 13, 2026
941c92c
fix(store): purge-org refuses a mount point under the root, or the ro…
claude Oct 13, 2026
5be4fa2
fix(studio): Remediate's primary with no Pack B names the Assessment …
claude Oct 14, 2026
ba10a1b
Merge origin/develop (4123bc7, #154, #155, #160 and #156) into codex/…
claude Oct 14, 2026
e297c52
docs: re-chain compare-in-bundle's nine Tests pairs from develop's 14…
claude Oct 14, 2026
4e5e31f
fix(store): purge-org reads each directory under the root again befor…
claude Oct 14, 2026
6b15327
fix(store): purge-org's refusal of a users file seen on another files…
claude Oct 14, 2026
f5bc546
fix(store): purge-org takes a file on another filesystem than its dir…
claude Oct 14, 2026
84c12b5
test(store): purge-org's suite expects the refusal of a recorded user…
claude Oct 14, 2026
b656e5a
fix(store): purge-org reads a name under the root that is not valid U…
claude Oct 14, 2026
13d77ca
fix(store): purge-org refuses an entry under the root with the users …
claude Oct 14, 2026
4439b0e
fix(store): purge-org goes on for a users file that does not exist wh…
claude Oct 14, 2026
cc5c468
fix(store): purge-org's walk keeps nothing of a file it passes, and o…
claude Oct 14, 2026
4da1239
test(store): the users-file place suite fails when purge-org takes a …
claude Oct 14, 2026
c86f545
fix(store): purge-org passes over a mount /proc/self/mountinfo lists …
claude Oct 14, 2026
0f53b12
fix(store): purge-org refuses a users file that does not exist whose …
claude Oct 14, 2026
b76ff7e
fix(store): purge-org goes on for a users file that does not exist wh…
claude Oct 14, 2026
93382ab
test(store): the users-file place suite fails when purge-org passes a…
claude Oct 14, 2026
2edb379
docs(store): the CHANGELOG's purge-org heap figures name the tree's s…
claude Oct 14, 2026
dacac21
fix(store): purge-org refuses a mount under the root while a mount is…
claude Oct 14, 2026
48df057
Merge pull request #157 from MoebiusX/codex/windows-ci
MoebiusX Oct 14, 2026
d14eb8b
Merge origin/develop (48df057, #157) into codex/id-clock-tolerance
claude Oct 14, 2026
54c2487
Merge origin/develop (48df057, #157) into codex/journey-notify-hooks
claude Oct 14, 2026
0ecf5e9
fix(test): test-notify-target-policy drops the inherited per-org vari…
claude Oct 14, 2026
228bd81
docs: re-chain the id-clock follow-up's Tests pair from develop's 143…
claude Oct 14, 2026
00f9dfb
feat(bundle): the bundle loads no font over the network by default — …
claude Oct 14, 2026
03717bf
fix(test): test-journey's seam and redaction cases use CLOSED_LOOPBAC…
claude Oct 14, 2026
654ac9b
fix(test): test-journey's two refusals through the real fetch allow a…
claude Oct 14, 2026
a5ea1d8
fix(store): purge-org's refusal of a mount point under the root names…
claude Oct 14, 2026
c638933
docs: re-chain journey-notify-env-ownership's eight Tests pairs from …
claude Oct 14, 2026
cbbd874
Merge origin/develop (48df057, #157) into codex/purge-org-unresolvabl…
claude Oct 14, 2026
eac1e35
docs: re-chain purge-org-unresolvable-links' Tests pairs from develop…
claude Oct 14, 2026
1b7a9d5
fix(store): purge-org refuses a covered mount under the root whose pa…
claude Oct 14, 2026
1fcd2f8
docs: DOWNSTREAM §10 gives the empty bundle's size as measured — 5,45…
claude Oct 14, 2026
63d5174
test(smoke): adopting a stale scan registers through /api/validate un…
claude Oct 14, 2026
6a9fcf3
test(store): the users-file place suite fails when purge-org takes a …
claude Oct 14, 2026
71e5d0a
fix(test): smoke's stale-scan adopt expects the YAML's own content id…
claude Oct 14, 2026
860d5dd
Merge pull request #158 from MoebiusX/codex/journey-notify-hooks
MoebiusX Oct 14, 2026
b77dfcb
Merge origin/develop (860d5dd, #158) into codex/id-clock-tolerance
claude Oct 14, 2026
1520ee6
Merge origin/develop (860d5dd, #158) into codex/purge-org-unresolvabl…
claude Oct 14, 2026
1a71bd7
docs: re-chain purge-org-unresolvable-links' Tests pairs from develop…
claude Oct 14, 2026
c31b9e4
docs: re-chain the id-clock follow-up's Tests pair from develop's 146…
claude Oct 14, 2026
ace5b35
Merge origin/develop (860d5dd, #158) into codex/bundle-compare
claude Oct 14, 2026
9acebed
docs: re-chain compare-in-bundle's ten Tests pairs from develop's 146…
claude Oct 14, 2026
c271b14
fix(test): C8 holds CI's workflow to installing no Playwright by its …
claude Oct 14, 2026
98b0017
fix(test): C8's Playwright loader imports an absolute OBSERVOGRAM_PLA…
claude Oct 14, 2026
2c41af5
Merge origin/develop (860d5dd, #158) into codex/smoke-stale-adopt-id
claude Oct 14, 2026
2ff689f
fix(store): purge-org passes over a covered mount under the root in a…
claude Oct 14, 2026
bd9abd3
docs: re-chain the smoke-stale-adopt-id entry to the measured total a…
claude Oct 14, 2026
1049f5f
test(store): the users-file place suite fails when purge-org places a…
claude Oct 14, 2026
ca89ada
fix(store): purge-org's refusal of a covered mount under the root say…
claude Oct 14, 2026
bf1ad37
fix(store): purge-org's refusal of a mount point under the root names…
claude Oct 14, 2026
eef0747
test(store): the users-file place suite fails when purge-org, in a ch…
claude Oct 14, 2026
37b1032
test(store): the users-file place suite fails when purge-org names th…
claude Oct 14, 2026
cae7d96
Merge pull request #159 from MoebiusX/codex/id-clock-tolerance
MoebiusX Oct 14, 2026
08ba554
Merge origin/develop (cae7d96, #159) into codex/purge-org-unresolvabl…
claude Oct 14, 2026
fe8c84d
Merge origin/develop (cae7d96, #159) into codex/bundle-compare
claude Oct 14, 2026
9a76fdd
docs: re-chain purge-org-unresolvable-links' Tests pairs from develop…
claude Oct 14, 2026
3c4d41b
docs: re-chain compare-in-bundle's ten Tests pairs from develop's 147…
claude Oct 14, 2026
7e1345d
fix(test): the Windows leg's tooling counts the eighth browser suite …
claude Oct 14, 2026
661cce1
Merge origin/develop (cae7d96, #157, #158 and #159) into codex/purge-…
claude Oct 14, 2026
07503ec
docs: re-chain purge-org-users-file-identity's Tests pairs from devel…
claude Oct 14, 2026
b1b377f
Merge origin/develop (cae7d96, #159) into codex/smoke-stale-adopt-id
claude Oct 14, 2026
ff68318
docs: re-chain the smoke-stale-adopt-id entry to the measured total a…
claude Oct 14, 2026
e630147
test(store): a purge refusal that does not match names what was throw…
claude Oct 14, 2026
c73329c
Merge pull request #164 from MoebiusX/codex/smoke-stale-adopt-id
MoebiusX Oct 14, 2026
737630f
Merge pull request #161 from MoebiusX/codex/purge-org-unresolvable-links
MoebiusX Oct 14, 2026
be67d0b
Merge origin/develop (737630f, #164 and #161) into codex/bundle-compare
claude Oct 14, 2026
fdb1603
fix(store): on Windows purge-org reads a directory's volume through a…
claude Oct 14, 2026
2f76b69
docs: re-chain compare-in-bundle's ten Tests pairs from develop's 147…
claude Oct 14, 2026
96f7f37
Merge origin/develop (737630f, #164 and #161) into codex/purge-org-us…
claude Oct 14, 2026
933cb03
docs: re-chain purge-org-users-file-identity's Tests pairs from devel…
claude Oct 14, 2026
00e0601
docs(store): on Windows purge-org refuses a users file recorded as a …
claude Oct 14, 2026
8500b48
Merge pull request #162 from MoebiusX/codex/bundle-compare
MoebiusX Oct 14, 2026
84c1598
Merge origin/develop (8500b48, #162) into codex/purge-org-users-file-…
claude Oct 14, 2026
84a80e2
docs: re-chain purge-org-users-file-identity's Tests pairs from devel…
claude Oct 14, 2026
49d82ba
fix(store): on Windows the path comparison reads a path's volume thro…
MoebiusX Oct 14, 2026
abd56a7
Merge pull request #163 from MoebiusX/codex/purge-org-users-file-iden…
MoebiusX Oct 15, 2026
cd24602
Merge branch 'develop' into codex/paths-volume-through-handle
MoebiusX Oct 15, 2026
4e43023
docs: restore purge-org-users-file-identity's CHANGELOG entry and re-…
claude Oct 15, 2026
aac37c8
Merge pull request #165 from MoebiusX/codex/paths-volume-through-handle
MoebiusX Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
131 changes: 126 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ OUTPUT=examples/production-live.pack.yaml
# Per-request MCP timeout in milliseconds (default 30000, capped at 300000).
# OBSERVOGRAM_MCP_TIMEOUT_MS=30000

# Transport hook (docs/MCP_INTEGRATION.md "Transport hook"): a module whose
# prepareRequest({ url, headers }) and/or fetchImpl(url, init) shape EVERY
# MCP request — fetch-live, record-fixtures, the live probes, journeys and
# the studio server. A path (absolute, or relative to the working
# directory) or a file: URL. Loaded once per process; a hook that fails to
# load or breaks its contract is a hard failure (exit 1, nothing written;
# the server refuses to start). Unset: inert.
# OBSERVOGRAM_TRANSPORT_HOOK=./hooks/gateway.mjs

# The MCP origin allowlist (README "Fetch Live From MCP"): comma-separated
# origins the studio server may send a credential to — an endpoint's
# server-held token, a caller's mcpAuth (every deploy), a credential in a
# typed URL, or anything while a transport hook is loaded. Loopback always
# passes. Unset: no credential leaves for any other origin. Per org:
# OBSERVOGRAM_ORG_<ORG>_MCP_ORIGINS (unioned with this one). `*` = any.
# OBSERVOGRAM_MCP_ORIGINS=https://otel-mcp.example.com

# ---------------------------------------------------------------------------
# Identity (docs/PRODUCTIZATION_PLAN.md Stage 1). Three postures:
#
Expand Down Expand Up @@ -82,6 +99,49 @@ OUTPUT=examples/production-live.pack.yaml
# "confirm": true); it applies to IdP users created after the change.
#OBSERVOGRAM_OIDC_JOIN_ROLE=

# Identity from a reverse proxy (README "Behind a reverse proxy"). Opt-in:
# the proxy in front of this port terminates SSO and sends who the caller is
# in headers; no cookie, no login page. Safe ONLY when clients cannot reach
# this port — the ACK is a sentence you type once the proxy strips these
# headers from every client request. Beyond loopback the shared secret is
# required (the proxy sends it in the secret header). Users are recorded as
# proxy://<realm>#<user> (kind oidc): `npm run users -- owner proxy://proxy#alice`.
# Groups → roles are authoritative in OBSERVOGRAM_PROXY_AUTH_ORG (default
# the default org); owner is grant-only. Refuses to start beside OIDC.
#OBSERVOGRAM_TRUST_PROXY_AUTH=1
#OBSERVOGRAM_TRUST_PROXY_AUTH_ACK=only-the-proxy-reaches-this-port
#OBSERVOGRAM_PROXY_AUTH_USER_HEADER=X-Forwarded-User
#OBSERVOGRAM_PROXY_AUTH_EMAIL_HEADER=X-Forwarded-Email
#OBSERVOGRAM_PROXY_AUTH_NAME_HEADER=
#OBSERVOGRAM_PROXY_AUTH_GROUPS_HEADER=X-Forwarded-Groups
#OBSERVOGRAM_PROXY_AUTH_GROUP_ROLES=sre=admin,dev=operator,*=viewer
#OBSERVOGRAM_PROXY_AUTH_ORG=
#OBSERVOGRAM_PROXY_AUTH_JOIN_ROLE=none # first-sight role when no groups header is configured; refused beside one
#OBSERVOGRAM_PROXY_AUTH_OWNERS=
#OBSERVOGRAM_PROXY_AUTH_SHARED_SECRET= # >=32 chars; required beyond loopback
#OBSERVOGRAM_PROXY_AUTH_SECRET_HEADER=X-Proxy-Auth-Secret
#OBSERVOGRAM_PROXY_AUTH_LOGOUT_URL=

# Rebadging (README, "Rebadge The Studio (brand config)"). One brand object
# feeds the studio shell, the chrome, the sign-in pages and the design
# tokens; unset, everything is Observogram and the shell is served byte for
# byte. A JSON file (name, shortName, wordmark, tagline, titleSuffix,
# description, logo {url|svg}, favicon, docsUrl, footer {text, links},
# about {changelogUrl}, hero {src, alt}, tokens {light, dark}) and/or the
# scalars below, which win over the file. One name derives every other
# string. An unreadable or invalid file refuses the start. Also honoured by
# `npm run build:studio` when `--brand` is absent (the file and the scalars).
#OBSERVOGRAM_BRAND_FILE=./brand.json
#OBSERVOGRAM_BRAND_NAME=
#OBSERVOGRAM_BRAND_SHORT_NAME=
#OBSERVOGRAM_BRAND_TAGLINE=
#OBSERVOGRAM_BRAND_LOGO_URL=
#OBSERVOGRAM_BRAND_DOCS_URL=
#OBSERVOGRAM_BRAND_FOOTER=
#OBSERVOGRAM_BRAND_ACCENT=
#OBSERVOGRAM_BRAND_ACCENT_DARK=
#OBSERVOGRAM_PROXY_AUTH_REALM=proxy

# Tenancy (Stage 2 — workspace-per-org). No env var and no file: always on.
# Every /api request runs in an org; a flat workspace is the default org, at
# the workspace root. A legacy <workspace>/orgs.json is imported once, at the
Expand Down Expand Up @@ -124,10 +184,71 @@ OUTPUT=examples/production-live.pack.yaml
# Run records kept per journey (oldest pruned after every run; 0 = unlimited).
#OBSERVOGRAM_JOURNEY_RUN_RETENTION=1000

# MCP read tokens an org's endpoints may name: OBSERVOGRAM_ORG_<ORG>_<NAME>
# (ORG = the org id, upper case, - → _; NAME of [A-Z0-9_]+). An admin of an
# org may name only its own (POST /api/mcp-endpoints { readTokenEnv }); the
# server reads the variable at request time when POST /api/refresh-live or
# /api/draft-from-mcp picks the endpoint by mcpEndpointId and the request
# sends no mcpAuth. The owning org is the one whose prefix is the longest
# match (OBSERVOGRAM_ORG_ACME_EU_X is acme-eu's, not acme's), so pick a
# NAME that is not another org's id followed by _, nor a notify hook's
# (OBSERVOGRAM_ORG_<ORG>_NOTIFY_<HOOK>_URL or _TOKEN, below — refused). Never
# a write token: deploys and rollbacks take theirs per request. Set on the
# studio (the k8s Deployment's env, from a Secret), never on the CronJob.
#OBSERVOGRAM_ORG_DEFAULT_MCP_TOKEN=

# A journey's own env-var names — packB.mcp.authEnv, notify.urlEnv,
# notify.authEnv — are read literally (process.env[<name>]), not through the
# OBSERVOGRAM_/TOMOGRAPH_ fallback: set exactly the names the journey file
# declares, e.g.
# notify.authEnv — are read literally by the CLI (packc journey run reads
# process.env[<name>], not through the OBSERVOGRAM_/TOMOGRAPH_ fallback): set
# exactly the names the journey file declares, e.g.
#MY_MCP_TOKEN=
#MY_JOURNEY_WEBHOOK_URL=
#MY_JOURNEY_WEBHOOK_TOKEN=
#
# The studio server reads only the journey's org's own notify hook (README,
# "Saved Journeys"; docs/DOWNSTREAM.md §17): notify.urlEnv must be
# OBSERVOGRAM_ORG_<ORG>_NOTIFY_<HOOK>_URL (HOOK: words of A-Z and 0-9 joined
# by single _) and notify.authEnv that hook's _TOKEN, or absent; any other
# name refuses the server's run before anything runs (400), and capture
# refuses it. Name the hook in journeys the studio also runs; the CLI reads
# the same names. Set the pair here and restart; GET
# /api/journeys/notify-hooks lists the org's hooks (never a value). Below,
# the default org's hook ONCALL when its id is `default` (npm run orgs --
# list).
#OBSERVOGRAM_ORG_DEFAULT_NOTIFY_ONCALL_URL=
#OBSERVOGRAM_ORG_DEFAULT_NOTIFY_ONCALL_TOKEN=
#
# The notify origin allowlist: comma-separated webhook origins
# (scheme://host[:port]; `*` = any) a server-run journey may post to.
# Loopback always passes. Unset: only loopback — a webhook off this machine
# needs its origin here. Per org: OBSERVOGRAM_ORG_<ORG>_NOTIFY_ORIGINS
# (unioned with this one). A separate list from OBSERVOGRAM_MCP_ORIGINS. An
# http: origin carries the URL and the token in clear.
#OBSERVOGRAM_NOTIFY_ORIGINS=https://hooks.slack.com

# Artefact taxonomy override (README, "Classify Typed Packs"): a JSON file
# mapping foreign artefact type names and id patterns onto Observogram's
# families, so a pack from another toolchain gets the grouped Discover board
# and the full compare. Read once at start; an unreadable or invalid file
# refuses the start. Unset = Observogram's own families only. Also honoured
# by `npm run build:studio` when `--taxonomy` is absent. Schema version 2
# adds a `glossary` (definitions the studio shows beside family labels and
# spec terms); a version 1 file stays valid.
#OBSERVOGRAM_TAXONOMY=./taxonomy.json

# MCP server-settings policy (rebadge batch 4): a JSON file of rules that
# add friction to the studio's Server settings modal — a warning on a field
# value that matches a pattern, and an acknowledgement ticked before the
# send — and an optional `generic` block prefilling the generic form's path
# and field names. `{ "version": 1, "rules": [{ "when": { "field" | "type",
# "pattern", "flags"? }, "warn", "require"?: { "ack" } }], "generic"?: {...} }`,
# strict (an unknown key is refused). Read once at start; an unreadable or
# invalid file refuses the start. Unset = no policy.
#OBSERVOGRAM_MCP_SETTINGS_POLICY=./mcp-settings-policy.json

# The MCP server-settings pass-through (rebadge batch 4): `1` lets the
# studio's Server settings modal send through the studio server
# (POST /api/mcp-settings/describe and /submit, admin only) when the browser
# cannot reach the MCP server or it sends no CORS headers. The studio server
# then holds the typed settings for one request — never logged, kept or
# audited by value — and passes back only the outcome shape. Read per
# request. Unset (the default): the browser talks to the MCP server directly.
#OBSERVOGRAM_MCP_ADMIN_PROXY=1
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Every text file is LF so goldens, fixtures and the vendor manifest's sha256
# verify under any core.autocrlf (the rules below stay as the explicit list).
* text=auto eol=lf

# Vendored upstream spec files MUST remain byte-identical to upstream so the
# sha256 checksums in vendor/observability-pack-spec/VERSIONS.json verify on
# every platform. Force LF regardless of core.autocrlf.
Expand Down
58 changes: 48 additions & 10 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ is the condensed, agent-facing version — when in doubt, those docs win.
render the affected view, check the console) before the work is called done.
- Conventional commit messages (`feat(server): …`, `fix(studio): …`,
`docs: …`) whose body says *why*, not just what.
- A red CI leg on develop, Linux or Windows, is fixed forward or reverted
within a working day; the summary at the end of the job's log names the
failure.

## Pinned sources of truth — edit the source, run its gate

Expand All @@ -37,16 +40,27 @@ them; change them at the source and update the gate in the same commit.
fails the build. Changing the registry requires updating
`EXPECTED_TOOL_SURFACE` in that guard in the same commit; the diff is the
wire-surface changelog.
- **Compiler and crawler output is golden-gated.** Any change to what the
crawler or a compiler *emits* must pass `npm run test:golden` (crawl) and
`npm run test:golden:compile` (per target, per version band). For intended
- **Compiler, crawler and board output is golden-gated.** Any change to what
the crawler or a compiler *emits* must pass `npm run test:golden` (crawl)
and `npm run test:golden:compile` (per target, per version band); any
change to how artefacts are classified or grouped must pass
`npm run test:golden:board` (the Discover board and the artefact families
of every catalogue pack). For intended
output changes, regenerate with the matching `:update` script in the same
commit and explain the golden diff in the commit/PR description. An
unexplained golden diff is a blocker, not a formality.
- **Product/protocol version facts** live in the data tables
`tools/lib/profiles.mjs` and `tools/lib/protocols.mjs`, each fact with an
upstream `evidence:` reference. Do not scatter version checks or feature
knobs into compiler code.
- **The vendorable module surface** is `VENDOR-MANIFEST.json`, generated by
`npm run vendor-manifest` (`tools/gen-vendor-manifest.mjs`) and never
hand-edited. Changing a listed `tools/lib` module regenerates it in the
same commit; changing a listed module's *exports* also names the module
under `## Unreleased` in `docs/CHANGELOG.md` (path or backticked
basename) — `tools/test-vendor-manifest.mjs` fails the build otherwise.
A new module under `tools/lib` is listed or added to `EXCLUDED` with a
reason; the guard refuses neither. `docs/DOWNSTREAM.md` is the workflow.
- **The vendored spec** under `vendor/observability-pack-spec/` is synced,
never hand-edited: use `npm run sync-spec`; `npm run sync-spec:check`
verifies SHA256 integrity and runs in CI.
Expand All @@ -58,18 +72,42 @@ them; change them at the source and update the gate in the same commit.
`server/test-authz.mjs` fails the build on an unclassified, unguarded or
unprobed route (add its probe to `PROBES`); a class change updates
`EXPECTED_CLASS` there in the same commit.
- **Identity rules:** every user, org, membership and join-role rule lives
once in `server/identity-admin.mjs`, applied by the CLIs (`npm run users`,
`npm run orgs`) and by the identity API (`server/routes/identity.mjs`,
with `surface: 'api'`, which changes only the way out a refusal names).
A refusal's `kind` (invalid / missing / conflict → 400 / 404 / 409) and
both surfaces' texts are pinned in `server/test-store.mjs`; never fork a
rule into a route.
- **Identity and service rules:** every user, org, membership and join-role
rule lives once in `server/identity-admin.mjs`, applied by the CLIs
(`npm run users`, `npm run orgs`) and by the identity API
(`server/routes/identity.mjs`, with `surface: 'api'`, which changes only
the way out a refusal names); every service, environment and MCP endpoint
rule — the tier enum, the MCP URL word rule and the per-org
`OBSERVOGRAM_ORG_<ORG>_*` token variable, an MCP target picked by
`mcpEndpointId` — lives once in `server/service-admin.mjs` (over
`server/store/mcp-endpoints.mjs`), applied by `server/routes/services.mjs`
and the refresh, draft and deploy routes; the audit reader's query rule
— the scope by principal, every filter, the 500-row cap — lives once in
`server/audit-admin.mjs` (`GET /api/audit` in `server/routes/audit.mjs`;
`packc store audit` in `tools/store-admin.mjs` — the `cli` surface of the
same rule),
and the file-first routes write their row through
`server/audit-after.mjs`, after the file, never inside the operation. A
refusal's `kind` (invalid / missing / conflict → 400 / 404 / 409) and the
texts are pinned in `server/test-store.mjs`,
`server/test-service-admin.mjs`, `server/test-services-api.mjs` and
`server/test-audit-api.mjs`; never fork a rule into a route.
- **Browser-safety rule:** modules under `tools/lib/` (including
`tools/lib/contracts/`) are imported by the studio in the browser — they
must not import `node:*` APIs or read `process.env`. Node-only code lives
in `tools/*.mjs`, `server/`, or `tools/lib/journey.mjs` (the known
exception).
- **Studio conventions** (`docs/UI_CONVENTIONS.md`): views import
`studio/host.mjs`, never `app.mjs`; a journey's actions ride
`host.<namespace>` (`host.build`, `host.services`, `host.settings`); the
services and Settings loaders go through `requestJson()` /
`servicesRefusal()` in `studio/services-api.mjs` (never a bare `fetch`,
never a raw body in a status line); a `.svc-*` rule lives under the
`==== Services` marker and a `.set-*` rule under the `==== Settings` marker
in `studio/app.css`, which the AA scan in `tools/test-build-model.mjs`
reads; a secret (an MCP token, a password) is never logged, stored or put
in a title or link — the token is a server variable's name, and a temporary
password is shown once, in its dialog, and nowhere else.

## Git hygiene

Expand Down
Loading
Loading