morgana: row 295 r2 old-test setup (mos-1436 option a): message-filter's :117 and governance-pin tests get an alice collaborator access document, spec-fixtures fixture() takes an optional access (null default); asserts and bindLaunch lines byte-identical; BUILD.md gate record, assertion preservation, N1 revoke window
This commit is contained in:
1 parent
9f29e1b2fd
commit
f652dfa5b8
3 files changed
+56
-5
No files matched your search
@@ -151,3 +151,47 @@ the kill, a run that polls would exit 22 on not-holder and hide the mutant.
|
||||
packages/cli/tests/access-boot.test.mjs and packages/webui/tests/granted-user.test.mjs run whole at
|
||||
the gate with the touched files. stack-release.test's copy list carries access.mjs, which adds
|
||||
no import here.
|
||||
|
||||
## Gate on 07802dc57 (sage-3318)
|
||||
|
||||
- First run, merge b42c591f8 (tree 0626929e5): access-revoke.test went 4 pass, 6 fail. These were
|
||||
first-run reds in the row's new tests, placed per mos-1272 in 9f29e1b2f (sage-3326, Dewey
|
||||
dewey-0905). Five claim-row compares failed because store rows have a null prototype, so they're
|
||||
now spread; thread-revoke:207 had the same compare and got the same fix. The demo business switches
|
||||
on the pi harness, which startBroker's harnessOn needs. In thread-revoke, Alice binds at her first
|
||||
call, because a second host's bind after the hand edit refuses access-revoked.
|
||||
- Second run, merge 38591cf96 (tree f719c0dc5): 12 whole files green. suite-bus stopped on 2
|
||||
old-test reds in packages/bus/tests/message-filter.test.mjs. ":117 trail on a decision ..." and
|
||||
":165 governance pin ..." each threw thread-revoked from bindLaunch's new check. Those fixtures
|
||||
write a `user:alice` thread with no access function, and with no document no grant covers it.
|
||||
Mos ruled option (a) in mos-1436: old-test setup only.
|
||||
|
||||
### Assertion-preservation record (mos-1436 conditions 7-9)
|
||||
|
||||
- message-filter.test.mjs gains `aliceAccess` with one grant: user alice, business demo, instances
|
||||
`['assistant']` (the thread's instance), collaborator level. projects is `['*']` because both
|
||||
tests make their project after the broker. `setup(t, { access } = {})` passes it to `new Broker`.
|
||||
Only :117 passes it; every other `setup(t)` gives `access: undefined`, which the constructor's
|
||||
default turns into null, as before.
|
||||
- The governance pin passes `access: aliceAccess` to `fixture()`. No other line of either test
|
||||
changes. The bindLaunch lines (:119, :169 before; :126, :176 after) and every assertion are
|
||||
byte-identical. The diff's removed lines are only `function setup(t) {`, the two setup calls and
|
||||
the two helper lines below.
|
||||
- spec-fixtures.mjs (11 importers) gains one optional parameter with a null default, which goes to
|
||||
`new Broker` unchanged. No other caller changes.
|
||||
|
||||
-export async function fixture(t, { adapter = true, roles = {}, arbiters = { technical: 'reviewer', delivery: 'reviewer' } } = {}) {
|
||||
+export async function fixture(t, { adapter = true, roles = {}, arbiters = { technical: 'reviewer', delivery: 'reviewer' }, access = null } = {}) {
|
||||
- const broker = new Broker({ store, businesses: { demo: business }, project: adapter ? {
|
||||
+ const broker = new Broker({ store, businesses: { demo: business }, access, project: adapter ? {
|
||||
|
||||
- Condition 4: M8 is the mutant. It deletes the broker.mjs:1371 thread-revoked check in bindLaunch,
|
||||
and its kill test is access-revoke's bind/claim refusal test. The red-first run on 38591cf96
|
||||
(both tests red), the green run and M8 run on Sage's CLEAR, followed by a full gate restart on
|
||||
the new merge with a new manifest.
|
||||
|
||||
### N items
|
||||
|
||||
- N1 (morgana-0167, sage-3318): a revoked run that calls the bus after its claim ends and before the
|
||||
launcher's SIGTERM gets not-holder and exits 22, not stopped (the same shape as #1809). 302's
|
||||
launcher-released path doesn't cover it. Sage decides after 295 lands whether this becomes a row.
|
||||
@@ -15,6 +15,12 @@ import { fixture } from './spec-fixtures.mjs';
|
||||
const AT = '2026-10-21T00:00:00.000Z';
|
||||
const within = (grants) => ({ authority: { withinRole: grants, crossRole: [] } });
|
||||
const options = [{ key: 'yes', text: 'Yes' }, { key: 'no', text: 'No' }];
|
||||
// FED R4 (row 295, mos-1436): a new run on a user's thread binds only while a grant covers it, so the
|
||||
// two tests that launch on alice's thread pass this access document; no other test's broker has one.
|
||||
const aliceAccess = () => ({
|
||||
accessVersion: 1, revision: 1, users: [],
|
||||
grants: [{ id: 'g-alice', user: 'alice', business: 'demo', projects: ['*'], instances: ['assistant'], level: 'collaborator' }],
|
||||
});
|
||||
// Row 264a (#1769): a thread made by hand gets the default session the 3k-3l migration gives a
|
||||
// legacy thread, with the thread's id.
|
||||
const DEFAULT_SESSION = [
|
||||
@@ -55,7 +61,7 @@ const fromAlice = (store, thread, body, extra = {}) =>
|
||||
const toAlice = (store, thread, body, extra = {}) =>
|
||||
put(store, { thread, from_role: 'assistant', from_run: 'assistant-run', to_role: 'user', body, ...extra });
|
||||
|
||||
function setup(t) {
|
||||
function setup(t, { access } = {}) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'bus-message-filter-'));
|
||||
const store = new Store(root);
|
||||
t.after(() => {
|
||||
@@ -64,6 +70,7 @@ function setup(t) {
|
||||
});
|
||||
const b = new Broker({
|
||||
store,
|
||||
access,
|
||||
businesses: {
|
||||
demo: {
|
||||
id: 'demo', human: 'jason', arbiters: { technical: 'chief', delivery: 'chief' }, vars: { 'bus.tester': true },
|
||||
@@ -115,7 +122,7 @@ test('replies on a hidden message id answers exactly as on an unknown id, for th
|
||||
});
|
||||
|
||||
test('trail on a decision keeps the decision and drops the user thread messages, their deliveries and their events', (t) => {
|
||||
const { b, store, call, U } = setup(t);
|
||||
const { b, store, call, U } = setup(t, { access: aliceAccess });
|
||||
const run = b.bindLaunch({ business: 'demo', role: 'assistant', run: 'assistant-run', harness: 'pi', thread: U });
|
||||
b.request(run, { verb: 'role.claim' });
|
||||
const d = b.request(run, {
|
||||
@@ -163,7 +170,7 @@ test('messages in the business human and tester threads are not hidden (row 177
|
||||
// Row 193's user sentence, one assertion per item: "The business owner sees your thread's agent's
|
||||
// decisions, inbox entries, claims, tasks and project files, but not your messages."
|
||||
test('governance pin: the owner sees decisions, inbox entries, claims, tasks and project files, but not the user messages', async (t) => {
|
||||
const f = await fixture(t, { roles: { assistant: { definition: 'assistant', ...within(['message.send', 'record.write']) } } });
|
||||
const f = await fixture(t, { roles: { assistant: { definition: 'assistant', ...within(['message.send', 'record.write']) } }, access: aliceAccess });
|
||||
const project = (await f.call(f.human, 'project.create', { name: 'alice work' })).id;
|
||||
const U = threadOf(f.store, project, 'user:alice', 'alice');
|
||||
const run = f.broker.bindLaunch({ business: 'demo', role: 'assistant', run: 'assistant-run', harness: 'pi', thread: U });
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Broker } from '../src/broker.mjs';
|
||||
import { initProject, readSpec, writeRecord, listProjectFiles, readProjectFile, writeHumanFile, ProjectError } from '../../project/src/index.mjs';
|
||||
export const git = (repo, ...args) => execFileSync('git', ['-c', 'core.hooksPath=/dev/null', '-C', repo, ...args], { encoding: 'utf8' }).trim();
|
||||
const options = [{ key: 'yes', text: 'Yes' }, { key: 'no', text: 'No' }];
|
||||
export async function fixture(t, { adapter = true, roles = {}, arbiters = { technical: 'reviewer', delivery: 'reviewer' } } = {}) {
|
||||
export async function fixture(t, { adapter = true, roles = {}, arbiters = { technical: 'reviewer', delivery: 'reviewer' }, access = null } = {}) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'bus-spec-'));
|
||||
const store = new Store(root);
|
||||
t.after(() => { store.close(); rmSync(root, { recursive: true, force: true }); });
|
||||
@@ -19,7 +19,7 @@ export async function fixture(t, { adapter = true, roles = {}, arbiters = { tech
|
||||
...roles,
|
||||
} };
|
||||
const { repo, commit } = await initProject({ business, project: 'stack', dataRoot: root });
|
||||
const broker = new Broker({ store, businesses: { demo: business }, project: adapter ? {
|
||||
const broker = new Broker({ store, businesses: { demo: business }, access, project: adapter ? {
|
||||
readSpec: context => readSpec({ ...context, dataRoot: root }),
|
||||
writeRecord: context => writeRecord({ ...context, dataRoot: root }),
|
||||
listFiles: context => listProjectFiles({ ...context, dataRoot: root }),
|
||||
|
||||
Reference in new issue
Block a user