Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/sync-acr-contracts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ const ARTIFACT_ROOT = path.join(ROOT, "src/contracts");
// WIDENING ONLY, and load-bearing: acr main mints this claim, so without the
// bump a response carrying it is rejected whole as `acr_contract_violation`
// instead of rendering.
export const SOURCE_COMMIT = "fe3fe467afb91323eaa8d122be7f78a5e6758e3b";
export const SOURCE_COMMIT = "74d8fc4c32a288fcb5b20fbeac335e17cf642be9";

const PRETTIER_OPTIONS = Object.freeze({
parser: "typescript",
Expand Down
33 changes: 33 additions & 0 deletions src/components/DeterministicAnswerView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,36 @@ describe("DeterministicAnswerView: a refused continuation still shows the servic
expect(withText).toBe(withoutText);
});
});

/**
* The user-facing wording of the organization-scope refusal is the service's
* own fixed sentence (ACR `ContextFabricOrganizationScopeUnsupportedLimitation`):
* it says organization-wide analysis of status, health or drivers is not
* supported, and that organization-wide counts are. The view renders it as
* visible text under Limitations; the basis itself is a machine field the view
* does not key off.
*/
describe("DeterministicAnswerView: an organization-scope refusal shows what is and is not supported", () => {
const SENTENCE =
"This question was read as being about the organization as a whole. Organization-wide analysis of status, health or drivers is not supported; organization-wide counts of one kind of subject, such as how many repositories or teams there are, are supported. No canonical facts were read.";

function refusedOrganizationQuestion(): InvestigationResult {
const base = mockScenarios().find((s) => s.id === "complete")!.result;
return {
...structuredClone(base),
status: "no_match",
refusal_basis: "organization_scope_unsupported",
limitations: [SENTENCE],
} as unknown as InvestigationResult;
}

it("renders the sentence as visible text, including what IS supported", () => {
render(<DeterministicAnswerView result={refusedOrganizationQuestion()} />);
const article = screen.getByRole("article", { name: "Deterministic answer" });
const text = visibleText(article);
expect(text).toContain(SENTENCE);
expect(text).toContain("organization-wide counts");
expect(text).not.toContain("The server refused this question on the basis");
expect(screen.getByRole("heading", { name: "Limitations" })).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion src/contracts/generated/error.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable */
/**
* GENERATED by scripts/sync-acr-contracts.mjs. DO NOT EDIT.
* Source: full-chaos/dev-health-acr @ fe3fe467afb91323eaa8d122be7f78a5e6758e3b
* Source: full-chaos/dev-health-acr @ 74d8fc4c32a288fcb5b20fbeac335e17cf642be9
* Regenerate with `pnpm acr:contracts:generate --source <acr worktree>`.
*/

Expand Down
2 changes: 1 addition & 1 deletion src/contracts/generated/investigation-request.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable */
/**
* GENERATED by scripts/sync-acr-contracts.mjs. DO NOT EDIT.
* Source: full-chaos/dev-health-acr @ fe3fe467afb91323eaa8d122be7f78a5e6758e3b
* Source: full-chaos/dev-health-acr @ 74d8fc4c32a288fcb5b20fbeac335e17cf642be9
* Regenerate with `pnpm acr:contracts:generate --source <acr worktree>`.
*/

Expand Down
8 changes: 5 additions & 3 deletions src/contracts/generated/investigation-result.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable */
/**
* GENERATED by scripts/sync-acr-contracts.mjs. DO NOT EDIT.
* Source: full-chaos/dev-health-acr @ fe3fe467afb91323eaa8d122be7f78a5e6758e3b
* Source: full-chaos/dev-health-acr @ 74d8fc4c32a288fcb5b20fbeac335e17cf642be9
* Regenerate with `pnpm acr:contracts:generate --source <acr worktree>`.
*/

Expand Down Expand Up @@ -146,7 +146,8 @@ export type ACRContextFabricInvestigationResultV1 = {
| "frame_invariant_violated"
| "unspecified"
| "continuation_context_unverifiable"
| "declared_kind_unmatched";
| "declared_kind_unmatched"
| "organization_scope_unsupported";
};
export type InterpretedQuestion = {
[k: string]: unknown | undefined;
Expand Down Expand Up @@ -2839,7 +2840,8 @@ export type AnswerCompleteness = {
| "frame_invariant_violated"
| "unspecified"
| "continuation_context_unverifiable"
| "declared_kind_unmatched";
| "declared_kind_unmatched"
| "organization_scope_unsupported";
};

export interface FactRequirement {
Expand Down
6 changes: 3 additions & 3 deletions src/contracts/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"source_commit": "fe3fe467afb91323eaa8d122be7f78a5e6758e3b",
"source_commit": "74d8fc4c32a288fcb5b20fbeac335e17cf642be9",
"source_repository": "full-chaos/dev-health-acr",
"files": [
{
Expand Down Expand Up @@ -28,15 +28,15 @@
},
{
"path": "schemas/context_fabric_common.v1.schema.json",
"sha256": "695065e0da7c731d1ee2d8efcc3fed9a7c6b4a95c58b99d1c76025185706e803"
"sha256": "707acb7ee25e1dbd252847740e3383ec4b204b77e8f0276e33f6911693afcfb8"
},
{
"path": "schemas/context_fabric_investigation_request.v1.schema.json",
"sha256": "db34def69344d0293cbd5e6373735bada695bbfdcaf40af2222c6456e6bb6486"
},
{
"path": "schemas/context_fabric_investigation_result.v1.schema.json",
"sha256": "e8ef8ce7a446e17684371ad0279de20783a0e207877d763d8557f20f1a57843f"
"sha256": "47d6dd017133b29db1d11775d99b8e6d08614c7d759c112f5899eb1a63b65c86"
},
{
"path": "schemas/error.v1.schema.json",
Expand Down
3 changes: 2 additions & 1 deletion src/contracts/schemas/context_fabric_common.v1.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3268,7 +3268,8 @@
"frame_invariant_violated",
"unspecified",
"continuation_context_unverifiable",
"declared_kind_unmatched"
"declared_kind_unmatched",
"organization_scope_unsupported"
],
"description": "CHAOS-5442: names WHY the server refused to act on this question's frame, over a closed vocabulary. ABSENT on every turn that was not refused -- absence means \"not refused\", never \"refused for a reason nobody recorded\" (that state is the `unspecified` member). Orthogonal to terminal_reason, which names the CHANNEL an explanation travelled through rather than the decision taken: a refused frame carries both. `continuation_context_unverifiable` refuses a window-only continuation whose prior semantic context the server could not verify; it is not a frame refusal, and the document carries its own fixed limitation sentence."
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@
"frame_invariant_violated",
"unspecified",
"continuation_context_unverifiable",
"declared_kind_unmatched"
"declared_kind_unmatched",
"organization_scope_unsupported"
],
"description": "CHAOS-5442: names WHY the server refused to act on this question's frame, over a closed vocabulary. ABSENT on every turn that was not refused -- absence means \"not refused\", never \"refused for a reason nobody recorded\" (that state is the `unspecified` member). Orthogonal to terminal_reason, which names the CHANNEL an explanation travelled through rather than the decision taken: a refused frame carries both. `continuation_context_unverifiable` refuses a window-only continuation whose prior semantic context the server could not verify; it is not a frame refusal, and the document carries its own fixed limitation sentence."
}
Expand Down
104 changes: 102 additions & 2 deletions src/lib/acr/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1346,8 +1346,8 @@ describe("investigation result contract — the continuation-refusal basis (cons
).$defs.AnswerCompleteness.properties.refusal_basis.enum;
expect(resultEnum).toContain("continuation_context_unverifiable");
expect(commonEnum).toContain("continuation_context_unverifiable");
expect(resultEnum).toHaveLength(5);
expect(commonEnum).toHaveLength(5);
expect(resultEnum).toHaveLength(6);
expect(commonEnum).toHaveLength(6);
expect([...resultEnum].sort()).toEqual([...commonEnum].sort());
});

Expand Down Expand Up @@ -1494,6 +1494,106 @@ describe("investigation result contract — the declared-kind terminal basis (co
});
});

/**
* `refusal_basis` gains a 6th member, `organization_scope_unsupported`: the
* question made the organization itself the subject and asked for something
* other than a count -- its state, health or drivers -- which is not a
* capability the service has. Organization-wide counts of one kind of subject
* are supported, and the document's own fixed sentence says so.
*
* It is NOT `declared_kind_unmatched`, which refuses a question because none of
* the options found could be chosen to answer it: for an organization-wide
* health question no option could ever be the answer, because its subject is
* the organization itself.
* It is not a frame refusal either. The field is carried at the same two places
* as every other member, and the prior pin rejects the value, so the bump is
* what turns this truthful refusal into an answer this workbench can render.
*/
describe("investigation result contract — the organization-scope refusal basis (consumer pin)", () => {
const RESULT = "context_fabric_investigation_result.v1.schema.json";
const MEMBER = "organization_scope_unsupported";

function withRefusalBasis(value: string): Record<string, unknown> {
return { ...structuredClone(canonicalResult), refusal_basis: value };
}

it("GREEN: organization_scope_unsupported validates at this pin", () => {
const validation = validateContract(RESULT, withRefusalBasis(MEMBER));
expect(validation.errors).toEqual([]);
expect(validation.valid).toBe(true);
});

it("every earlier member still validates alongside it", () => {
for (const value of [
"member_kind_unservable",
"frame_invariant_violated",
"unspecified",
"continuation_context_unverifiable",
"declared_kind_unmatched",
]) {
const validation = validateContract(RESULT, withRefusalBasis(value));
expect(validation.errors).toEqual([]);
expect(validation.valid).toBe(true);
}
});

it("the vocabulary stays CLOSED around the new member: near-misses are rejected", () => {
for (const value of [
"organization_scope_unsupported_",
"ORGANIZATION_SCOPE_UNSUPPORTED",
"organization_scope",
]) {
expect(validateContract(RESULT, withRefusalBasis(value)).valid).toBe(false);
}
});

it("both vocabularies carry the member — as enum values, not as description text", () => {
const resultEnum = (
investigationResultSchema as unknown as {
properties: { refusal_basis: { enum: string[] } };
}
).properties.refusal_basis.enum;
const commonEnum = (
commonSchema as unknown as {
$defs: {
AnswerCompleteness: { properties: { refusal_basis: { enum: string[] } } };
};
}
).$defs.AnswerCompleteness.properties.refusal_basis.enum;
expect(resultEnum).toContain(MEMBER);
expect(commonEnum).toContain(MEMBER);
expect([...resultEnum].sort()).toEqual([...commonEnum].sort());
});

it("BEHAVIOURAL: the new value validates at completeness.refusal_basis too", () => {
const doc = structuredClone(canonicalResult) as unknown as Record<string, unknown>;
doc.completeness = {
...(doc.completeness as Record<string, unknown>),
refusal_basis: MEMBER,
};
const validation = validateContract(RESULT, doc);
expect(validation.errors).toEqual([]);
expect(validation.valid).toBe(true);
});

it("EXECUTED repro: the prior pin's own schema rejects the new value", () => {
const priorResult = structuredClone(investigationResultSchema) as unknown as {
properties: { refusal_basis: { enum: string[] } };
};
expect(priorResult.properties.refusal_basis.enum).toContain(MEMBER);
priorResult.properties.refusal_basis.enum =
priorResult.properties.refusal_basis.enum.filter((value) => value !== MEMBER);

const ajv = new Ajv2020({ allErrors: true, strictSchema: false, strictTypes: false });
ajv.addSchema(commonSchema, "context_fabric_common.v1.schema.json");
const validate = ajv.compile(priorResult);

expect(validate(withRefusalBasis(MEMBER))).toBe(false);
// The stand-in still accepts the previous member, so it is faithful.
expect(validate(withRefusalBasis("declared_kind_unmatched"))).toBe(true);
});
});

/**
* `CoverageDetail.code` gains a 17th closed-vocabulary member,
* `fact_read_origin_state`: the code the service publishes when a requirement's
Expand Down