create-principles-disciple 1.133.0 → 1.133.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/codex-adapter/dist/ingestion/ingestion.js +3 -3
- package/codex-adapter/dist/ingestion/transcript-locate.d.ts +6 -11
- package/codex-adapter/dist/ingestion/transcript-locate.js +5 -73
- package/codex-adapter/dist/ingestion/transcript-path.d.ts +2 -2
- package/codex-adapter/dist/ingestion/transcript-path.js +4 -21
- package/codex-adapter/dist/worker/workspace-worker.d.ts +1 -12
- package/codex-adapter/dist/worker/workspace-worker.js +4 -34
- package/codex-adapter/package.json +1 -1
- package/console/dist/server/models/CodexGovernanceHealthModel.d.ts +97 -0
- package/console/dist/server/models/CodexGovernanceHealthModel.js +81 -0
- package/console/dist/server/models/EvidenceChainConsoleModel.js +16 -2
- package/console/dist/server/routes/health.js +59 -3
- package/console/dist/ui/i18n/en.json +4 -0
- package/console/dist/ui/i18n/zh-CN.json +4 -0
- package/console/dist/ui/pages/pain/PainPage.js +1 -1
- package/console/dist/ui/utils/validators.d.ts +2 -0
- package/console/dist/ui/utils/validators.js +7 -0
- package/console/dist/web/assets/app.js +15 -1
- package/core/dist/host/index.d.ts +2 -0
- package/core/dist/host/index.d.ts.map +1 -1
- package/core/dist/host/index.js +3 -0
- package/core/dist/host/index.js.map +1 -1
- package/core/dist/host/legacy-registration.d.ts +28 -0
- package/core/dist/host/legacy-registration.d.ts.map +1 -0
- package/core/dist/host/legacy-registration.js +49 -0
- package/core/dist/host/legacy-registration.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-host-kind.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-host-kind.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-host-kind.test.js +49 -0
- package/core/dist/runtime-v2/__tests__/evidence-chain-host-kind.test.js.map +1 -0
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +6 -0
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.js +12 -0
- package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/installers/codex-host-installer.d.ts +17 -7
- package/dist/installers/codex-host-installer.d.ts.map +1 -1
- package/dist/installers/codex-host-installer.js +78 -194
- package/dist/installers/codex-host-installer.js.map +1 -1
- package/host-runtime/dist/codex-disclosure.d.ts +23 -0
- package/host-runtime/dist/codex-disclosure.js +60 -0
- package/host-runtime/dist/codex-ingestion-consent.d.ts +111 -0
- package/host-runtime/dist/codex-ingestion-consent.js +223 -0
- package/host-runtime/dist/codex-legacy-registration.d.ts +18 -0
- package/host-runtime/dist/codex-legacy-registration.js +34 -0
- package/host-runtime/dist/codex-transcript-locate.d.ts +16 -0
- package/host-runtime/dist/codex-transcript-locate.js +106 -0
- package/host-runtime/dist/codex-worker-status.d.ts +24 -0
- package/host-runtime/dist/codex-worker-status.js +52 -0
- package/host-runtime/dist/governance-observation-store.d.ts +77 -1
- package/host-runtime/dist/governance-observation-store.js +188 -3
- package/host-runtime/dist/governance-signal-admission.d.ts +26 -0
- package/host-runtime/dist/governance-signal-admission.js +47 -0
- package/host-runtime/dist/index.d.ts +5 -0
- package/host-runtime/dist/index.js +14 -0
- package/host-runtime/package.json +1 -1
- package/package.json +1 -1
- package/pd-cli/dist/commands/codex-ingest-quarantine.d.ts +12 -0
- package/pd-cli/dist/commands/codex-ingest-quarantine.d.ts.map +1 -0
- package/pd-cli/dist/commands/codex-ingest-quarantine.js +116 -0
- package/pd-cli/dist/commands/codex-ingest-quarantine.js.map +1 -0
- package/pd-cli/dist/commands/codex-setup.d.ts +46 -0
- package/pd-cli/dist/commands/codex-setup.d.ts.map +1 -0
- package/pd-cli/dist/commands/codex-setup.js +423 -0
- package/pd-cli/dist/commands/codex-setup.js.map +1 -0
- package/pd-cli/dist/commands/health-codex.d.ts.map +1 -1
- package/pd-cli/dist/commands/health-codex.js +350 -67
- package/pd-cli/dist/commands/health-codex.js.map +1 -1
- package/pd-cli/dist/index.js +51 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/bundle.js +331 -331
- package/release-manager/dist/installers/codex-host-installer.d.ts +17 -7
- package/release-manager/dist/installers/codex-host-installer.d.ts.map +1 -1
- package/release-manager/dist/installers/codex-host-installer.js +78 -194
- package/release-manager/dist/installers/codex-host-installer.js.map +1 -1
- package/release-manager/package.json +1 -1
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import fs from 'node:fs';
|
|
28
28
|
import path from 'node:path';
|
|
29
|
+
import { createHash } from 'node:crypto';
|
|
29
30
|
import Database from 'better-sqlite3';
|
|
30
31
|
import { sanitizeString, sanitizeValue } from '@principles/core/runtime-v2';
|
|
31
32
|
// ─── Retention policy constants (Owner-approved, SPEC rev 2 §11) ────────────
|
|
@@ -33,7 +34,7 @@ export const GOVERNANCE_RETENTION_MAX_TURNS = 32;
|
|
|
33
34
|
export const GOVERNANCE_RETENTION_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
34
35
|
export const GOVERNANCE_PROMOTION_PRECEDING_TURNS = 12;
|
|
35
36
|
export const GOVERNANCE_PENDING_TAIL_STALE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
36
|
-
const GOVERNANCE_OBSERVATION_SCHEMA_VERSION =
|
|
37
|
+
const GOVERNANCE_OBSERVATION_SCHEMA_VERSION = 3;
|
|
37
38
|
const MAX_TEXT_BOUND = 200; // matches MAX_EVIDENCE_VALUE_CHARS; guards stored identity fields
|
|
38
39
|
const MAX_JSON_COLUMN = 8_000;
|
|
39
40
|
function isRecord(value) {
|
|
@@ -154,11 +155,19 @@ const V2_ADDED_COLUMNS = [
|
|
|
154
155
|
{ table: 'governance_observations', name: 'source_order', type: 'INTEGER' },
|
|
155
156
|
{ table: 'governance_observations', name: 'source_ordinal', type: 'INTEGER' },
|
|
156
157
|
];
|
|
158
|
+
/** Column additions in v3 (Slice D §15 quarantine: audited recovery metadata). */
|
|
159
|
+
const V3_ADDED_COLUMNS = [
|
|
160
|
+
{ table: 'governance_observations', name: 'quarantined_at', type: 'TEXT' },
|
|
161
|
+
{ table: 'governance_observations', name: 'quarantine_reason', type: 'TEXT' },
|
|
162
|
+
{ table: 'governance_observations', name: 'quarantine_digest', type: 'TEXT' },
|
|
163
|
+
{ table: 'governance_observations', name: 'quarantine_operator', type: 'TEXT' },
|
|
164
|
+
{ table: 'governance_observations', name: 'quarantine_gap', type: 'TEXT' },
|
|
165
|
+
];
|
|
157
166
|
function ensureGovernanceObservationSchema(db) {
|
|
158
167
|
db.transaction(() => {
|
|
159
168
|
for (const statement of CREATE_STATEMENTS)
|
|
160
169
|
db.exec(statement);
|
|
161
|
-
for (const column of V2_ADDED_COLUMNS) {
|
|
170
|
+
for (const column of [...V2_ADDED_COLUMNS, ...V3_ADDED_COLUMNS]) {
|
|
162
171
|
try {
|
|
163
172
|
db.exec(`ALTER TABLE ${column.table} ADD COLUMN ${column.name} ${column.type}`);
|
|
164
173
|
}
|
|
@@ -460,7 +469,7 @@ export function ingestGovernanceObservations(input) {
|
|
|
460
469
|
})();
|
|
461
470
|
if (result === 'conflict') {
|
|
462
471
|
return {
|
|
463
|
-
ok: false, reason: 'logical_key_content_conflict', nextAction: 'the first committed content was preserved and the observation is marked partial; run
|
|
472
|
+
ok: false, reason: 'logical_key_content_conflict', nextAction: 'the first committed content was preserved and the observation is marked partial; run `pd codex ingest quarantine --workspace <path> --rollout <id> --record <id>` (audited, dry-run default) or re-ingest from a fresh rollout',
|
|
464
473
|
inserted, enriched, duplicates, checkpointCommitted: false, warnings: [`conflict:${conflictKey}`],
|
|
465
474
|
};
|
|
466
475
|
}
|
|
@@ -694,3 +703,179 @@ export function promoteGovernanceEvidence(input) {
|
|
|
694
703
|
close();
|
|
695
704
|
}
|
|
696
705
|
}
|
|
706
|
+
const QUARANTINE_REASON_MAX = 200;
|
|
707
|
+
const QUARANTINE_OPERATOR_MAX = 80;
|
|
708
|
+
function observationDigest(row) {
|
|
709
|
+
// Digest the row's stored content exactly as persisted (rc-8: hashing
|
|
710
|
+
// string columns only — never JSON.stringify of untrusted unknowns). The
|
|
711
|
+
// digest lets a future audit recognize the same record if it reappears.
|
|
712
|
+
const hash = createHash('sha256');
|
|
713
|
+
for (const column of ['rollout_identity', 'logical_key', 'transcript_record_key', 'kind', 'source', 'completeness', 'visible_text', 'sanitized_tool_facts_json', 'observed_at']) {
|
|
714
|
+
const value = row[column];
|
|
715
|
+
hash.update(`${column}=`);
|
|
716
|
+
hash.update(value === null || value === undefined ? '<null>' : String(value));
|
|
717
|
+
hash.update('\n');
|
|
718
|
+
}
|
|
719
|
+
return hash.digest('hex');
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Audited quarantine for a permanently invalid governance observation
|
|
723
|
+
* (SPEC §15). Dry run is the contract default: without `confirm` the store
|
|
724
|
+
* reports what WOULD happen and mutates nothing. With `confirm`:
|
|
725
|
+
* - bodies (visible_text / sanitized_tool_facts_json) are dropped;
|
|
726
|
+
* - retention_class becomes `quarantined` (terminal class — never pruned,
|
|
727
|
+
* never promoted);
|
|
728
|
+
* - digest, reason, operator, timestamp, and the neighbor gap are recorded;
|
|
729
|
+
* - the Codex transcript is never read or touched (this function opens only
|
|
730
|
+
* the workspace trajectory.db).
|
|
731
|
+
* Promoted evidence is refused: Owner-decided evidence leaves only through
|
|
732
|
+
* the Owner governance cleanup commands.
|
|
733
|
+
*/
|
|
734
|
+
export function quarantineGovernanceObservation(args) {
|
|
735
|
+
const { workspaceDir, hostKind, rolloutIdentity, recordId, reason, operator, confirm = false } = args;
|
|
736
|
+
if (!Number.isInteger(recordId) || recordId <= 0) {
|
|
737
|
+
return { ok: false, reason: 'record_id_invalid', nextAction: 'Pass the numeric governance_observations.id (--record <id>); run `pd codex ingest catch-up --json` output or inspect trajectory.db to find it.' };
|
|
738
|
+
}
|
|
739
|
+
if (typeof reason !== 'string' || reason.trim().length === 0 || reason.length > QUARANTINE_REASON_MAX) {
|
|
740
|
+
return { ok: false, reason: 'reason_required', nextAction: `Provide a non-empty reason (≤ ${QUARANTINE_REASON_MAX} chars) describing why the record is permanently invalid.` };
|
|
741
|
+
}
|
|
742
|
+
if (typeof operator !== 'string' || operator.trim().length === 0 || operator.length > QUARANTINE_OPERATOR_MAX) {
|
|
743
|
+
return { ok: false, reason: 'operator_required', nextAction: `Provide the operator identity (≤ ${QUARANTINE_OPERATOR_MAX} chars).` };
|
|
744
|
+
}
|
|
745
|
+
const opened = openStore(workspaceDir, args.databaseFactory);
|
|
746
|
+
if (!('db' in opened))
|
|
747
|
+
return opened;
|
|
748
|
+
const { db, close } = opened;
|
|
749
|
+
try {
|
|
750
|
+
const outcome = db.transaction(() => {
|
|
751
|
+
const rolloutRow = db.prepare('SELECT id FROM governance_rollouts WHERE host_kind = ? AND rollout_identity = ?').get(hostKind, rolloutIdentity);
|
|
752
|
+
if (!isRecord(rolloutRow)) {
|
|
753
|
+
return { ok: false, reason: 'rollout_not_found', nextAction: `No governed rollout '${rolloutIdentity}' for host '${hostKind}' in this workspace; check the identity (see \`pd codex ingest catch-up\` output).` };
|
|
754
|
+
}
|
|
755
|
+
const rolloutRowId = rowField(rolloutRow, 'id');
|
|
756
|
+
const row = db.prepare('SELECT * FROM governance_observations WHERE id = ? AND rollout_row_id = ?').get(recordId, rolloutRowId);
|
|
757
|
+
if (!isRecord(row)) {
|
|
758
|
+
return { ok: false, reason: 'record_not_found', nextAction: `Record ${recordId} does not exist in rollout '${rolloutIdentity}' of this workspace; verify the id.` };
|
|
759
|
+
}
|
|
760
|
+
const retentionClassRaw = String(rowField(row, 'retention_class'));
|
|
761
|
+
// rc-2: the DB column is untrusted — only known classes enter the typed
|
|
762
|
+
// summary; anything else reads as 'expired' semantics for reporting but
|
|
763
|
+
// still fails the quarantinable check below.
|
|
764
|
+
const retentionClass = retentionClassRaw === 'operational' || retentionClassRaw === 'promoted'
|
|
765
|
+
|| retentionClassRaw === 'quarantined' || retentionClassRaw === 'rolled_back'
|
|
766
|
+
? retentionClassRaw
|
|
767
|
+
: 'expired';
|
|
768
|
+
const quarantinedAt = rowField(row, 'quarantined_at');
|
|
769
|
+
const sourceOrder = typeof rowField(row, 'source_order') === 'number' ? rowField(row, 'source_order') : null;
|
|
770
|
+
const neighborQuery = (direction) => {
|
|
771
|
+
if (sourceOrder === null)
|
|
772
|
+
return 'none';
|
|
773
|
+
const comparison = direction === 'prev' ? '<' : '>';
|
|
774
|
+
const ordering = direction === 'prev' ? 'DESC' : 'ASC';
|
|
775
|
+
const neighbor = db.prepare(`SELECT source_order FROM governance_observations
|
|
776
|
+
WHERE rollout_row_id = ? AND source_order IS NOT NULL AND source_order ${comparison} ?
|
|
777
|
+
ORDER BY source_order ${ordering} LIMIT 1`).get(rolloutRowId, sourceOrder);
|
|
778
|
+
const value = isRecord(neighbor) ? rowField(neighbor, 'source_order') : undefined;
|
|
779
|
+
return typeof value === 'number' ? value : 'none';
|
|
780
|
+
};
|
|
781
|
+
const summary = {
|
|
782
|
+
id: recordId,
|
|
783
|
+
kind: String(rowField(row, 'kind')),
|
|
784
|
+
logicalKey: String(rowField(row, 'logical_key')),
|
|
785
|
+
observedAt: String(rowField(row, 'observed_at')),
|
|
786
|
+
retentionClass,
|
|
787
|
+
digest: observationDigest(row),
|
|
788
|
+
gap: `prev=${neighborQuery('prev')};next=${neighborQuery('next')};record=${sourceOrder === null ? 'null' : sourceOrder}`,
|
|
789
|
+
};
|
|
790
|
+
if (typeof quarantinedAt === 'string' && quarantinedAt.length > 0) {
|
|
791
|
+
// Already terminal: report the RECORDED audit digest/gap, not a
|
|
792
|
+
// re-hash of the row (bodies were dropped at quarantine time, so a
|
|
793
|
+
// fresh hash would silently differ from the audited one). dryRun
|
|
794
|
+
// reflects THIS invocation's intent — a dry-run call reports
|
|
795
|
+
// dryRun:true even on an already-quarantined row (review round 3).
|
|
796
|
+
const recordedDigest = rowField(row, 'quarantine_digest');
|
|
797
|
+
const recordedGap = rowField(row, 'quarantine_gap');
|
|
798
|
+
return {
|
|
799
|
+
ok: true, dryRun: !confirm, alreadyQuarantined: true,
|
|
800
|
+
record: {
|
|
801
|
+
...summary,
|
|
802
|
+
digest: typeof recordedDigest === 'string' && recordedDigest.length > 0 ? recordedDigest : summary.digest,
|
|
803
|
+
gap: typeof recordedGap === 'string' && recordedGap.length > 0 ? recordedGap : summary.gap,
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
if (retentionClass === 'promoted') {
|
|
808
|
+
return { ok: false, reason: 'record_is_promoted_evidence', nextAction: 'Promoted evidence is Owner-decided governance evidence; quarantine never touches it. Use the existing Owner governance cleanup commands if the evidence must be removed.' };
|
|
809
|
+
}
|
|
810
|
+
if (retentionClass !== 'operational') {
|
|
811
|
+
return { ok: false, reason: `record_not_quarantinable:${retentionClass}`, nextAction: 'Only operational records can be quarantined; expired and rolled-back rows are already terminal.' };
|
|
812
|
+
}
|
|
813
|
+
if (!confirm) {
|
|
814
|
+
return { ok: true, dryRun: true, alreadyQuarantined: false, record: summary };
|
|
815
|
+
}
|
|
816
|
+
const now = new Date().toISOString();
|
|
817
|
+
db.prepare(`UPDATE governance_observations
|
|
818
|
+
SET visible_text = NULL, sanitized_tool_facts_json = NULL, retention_class = 'quarantined',
|
|
819
|
+
quarantined_at = ?, quarantine_reason = ?, quarantine_digest = ?, quarantine_operator = ?, quarantine_gap = ?
|
|
820
|
+
WHERE id = ? AND retention_class = 'operational'`)
|
|
821
|
+
.run(now, reason, summary.digest, operator, summary.gap, recordId);
|
|
822
|
+
return { ok: true, dryRun: false, alreadyQuarantined: false, record: summary };
|
|
823
|
+
})();
|
|
824
|
+
return outcome;
|
|
825
|
+
}
|
|
826
|
+
catch (error) {
|
|
827
|
+
const detail = error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200);
|
|
828
|
+
return { ok: false, reason: `governance_quarantine_failed:${detail}`, nextAction: 'inspect the workspace trajectory database and retry; the transaction rolled back, nothing was partially mutated' };
|
|
829
|
+
}
|
|
830
|
+
finally {
|
|
831
|
+
close();
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Bounded read-only counts for the §15 health surface. Unknown is reported
|
|
836
|
+
* as a structured degradation — never silently as zero (§15: unknown is not
|
|
837
|
+
* reported as healthy).
|
|
838
|
+
*/
|
|
839
|
+
export function readGovernanceObservationStats(args) {
|
|
840
|
+
const opened = openStore(args.workspaceDir, args.databaseFactory);
|
|
841
|
+
if (!('db' in opened))
|
|
842
|
+
return opened;
|
|
843
|
+
const { db, close } = opened;
|
|
844
|
+
try {
|
|
845
|
+
const counts = db.prepare(`SELECT
|
|
846
|
+
SUM(CASE WHEN retention_class = 'operational' THEN 1 ELSE 0 END) AS operational,
|
|
847
|
+
SUM(CASE WHEN retention_class = 'promoted' THEN 1 ELSE 0 END) AS promoted,
|
|
848
|
+
SUM(CASE WHEN retention_class = 'quarantined' THEN 1 ELSE 0 END) AS quarantined,
|
|
849
|
+
SUM(CASE WHEN retention_class IN ('expired', 'rolled_back') THEN 1 ELSE 0 END) AS terminal_other,
|
|
850
|
+
MIN(CASE WHEN retention_class = 'operational' THEN observed_at END) AS oldest_operational,
|
|
851
|
+
MAX(observed_at) AS last_observation
|
|
852
|
+
FROM governance_observations`).get();
|
|
853
|
+
if (!isRecord(counts)) {
|
|
854
|
+
return { ok: false, reason: 'governance_stats_unavailable', nextAction: 'Inspect the workspace trajectory.db governance_observations table.' };
|
|
855
|
+
}
|
|
856
|
+
const numberOr = (value) => (typeof value === 'number' ? value : 0);
|
|
857
|
+
const stringOr = (value) => (typeof value === 'string' && value.length > 0 ? value : null);
|
|
858
|
+
const oldest = stringOr(own(counts, 'oldest_operational'));
|
|
859
|
+
const nextExpiry = oldest !== null && !Number.isNaN(Date.parse(oldest))
|
|
860
|
+
? new Date(Date.parse(oldest) + GOVERNANCE_RETENTION_MAX_AGE_MS).toISOString()
|
|
861
|
+
: null;
|
|
862
|
+
return {
|
|
863
|
+
ok: true,
|
|
864
|
+
stats: {
|
|
865
|
+
operational: numberOr(own(counts, 'operational')),
|
|
866
|
+
promoted: numberOr(own(counts, 'promoted')),
|
|
867
|
+
quarantined: numberOr(own(counts, 'quarantined')),
|
|
868
|
+
terminalOther: numberOr(own(counts, 'terminal_other')),
|
|
869
|
+
nextExpiryAt: nextExpiry,
|
|
870
|
+
lastObservationAt: stringOr(own(counts, 'last_observation')),
|
|
871
|
+
},
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
const detail = error instanceof Error ? error.message.slice(0, 160) : String(error);
|
|
876
|
+
return { ok: false, reason: `governance_stats_failed:${detail}`, nextAction: 'Inspect the workspace trajectory.db; the health surface degraded without mutating anything.' };
|
|
877
|
+
}
|
|
878
|
+
finally {
|
|
879
|
+
close();
|
|
880
|
+
}
|
|
881
|
+
}
|
|
@@ -225,4 +225,30 @@ export interface ReconcileGovernanceContinuationResult {
|
|
|
225
225
|
* Not a background worker — Slice C's Companion worker and the CLI call this.
|
|
226
226
|
*/
|
|
227
227
|
export declare function reconcileGovernanceContinuation(input: ReconcileGovernanceContinuationInput): Promise<ReconcileGovernanceContinuationResult>;
|
|
228
|
+
export interface GovernanceAdmissionCounts {
|
|
229
|
+
readonly admitted: number;
|
|
230
|
+
/** Admitted pains with no Diagnostician task link — the §15 orphan count. */
|
|
231
|
+
readonly admittedWithoutTask: number;
|
|
232
|
+
readonly pendingTails: number;
|
|
233
|
+
readonly staleTails: number;
|
|
234
|
+
readonly completedTails: number;
|
|
235
|
+
readonly lastAdmissionAt: string | null;
|
|
236
|
+
}
|
|
237
|
+
export type ReadGovernanceAdmissionCountsResult = {
|
|
238
|
+
ok: true;
|
|
239
|
+
counts: GovernanceAdmissionCounts;
|
|
240
|
+
} | {
|
|
241
|
+
ok: false;
|
|
242
|
+
reason: string;
|
|
243
|
+
nextAction: string;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Bounded read-only counts for the §15 health surface: admitted-pain-without-
|
|
247
|
+
* task count and promotion-tail states. Read-only — reconciliation itself
|
|
248
|
+
* stays in `reconcileGovernanceContinuation`.
|
|
249
|
+
*/
|
|
250
|
+
export declare function readGovernanceAdmissionCounts(args: {
|
|
251
|
+
workspaceDir: string;
|
|
252
|
+
databaseFactory?: ObservationDatabaseFactory;
|
|
253
|
+
}): ReadGovernanceAdmissionCountsResult;
|
|
228
254
|
export {};
|
|
@@ -857,3 +857,50 @@ export async function reconcileGovernanceContinuation(input) {
|
|
|
857
857
|
close();
|
|
858
858
|
}
|
|
859
859
|
}
|
|
860
|
+
/**
|
|
861
|
+
* Bounded read-only counts for the §15 health surface: admitted-pain-without-
|
|
862
|
+
* task count and promotion-tail states. Read-only — reconciliation itself
|
|
863
|
+
* stays in `reconcileGovernanceContinuation`.
|
|
864
|
+
*/
|
|
865
|
+
export function readGovernanceAdmissionCounts(args) {
|
|
866
|
+
const opened = openAdmissionStore(args.workspaceDir, args.databaseFactory);
|
|
867
|
+
if (!('db' in opened))
|
|
868
|
+
return opened;
|
|
869
|
+
const { db, close } = opened;
|
|
870
|
+
try {
|
|
871
|
+
const admissions = db.prepare(`SELECT
|
|
872
|
+
SUM(CASE WHEN decision = 'admitted' THEN 1 ELSE 0 END) AS admitted,
|
|
873
|
+
SUM(CASE WHEN decision = 'admitted' AND diagnostician_task_id IS NULL THEN 1 ELSE 0 END) AS admitted_without_task,
|
|
874
|
+
MAX(created_at) AS last_admission
|
|
875
|
+
FROM governance_signal_admissions`).get();
|
|
876
|
+
if (!isRecord(admissions)) {
|
|
877
|
+
return { ok: false, reason: 'governance_admission_counts_unavailable', nextAction: 'Inspect the governance_signal_admissions table in the workspace trajectory.db.' };
|
|
878
|
+
}
|
|
879
|
+
const numberOr = (value) => (typeof value === 'number' ? value : 0);
|
|
880
|
+
const stringOr = (value) => (typeof value === 'string' && value.length > 0 ? value : null);
|
|
881
|
+
const tails = db.prepare(`SELECT
|
|
882
|
+
SUM(CASE WHEN state = 'pending' THEN 1 ELSE 0 END) AS pending,
|
|
883
|
+
SUM(CASE WHEN state = 'stale' THEN 1 ELSE 0 END) AS stale,
|
|
884
|
+
SUM(CASE WHEN state = 'completed' THEN 1 ELSE 0 END) AS completed
|
|
885
|
+
FROM governance_pending_promotion_tails`).get();
|
|
886
|
+
const tailRow = isRecord(tails) ? tails : {};
|
|
887
|
+
return {
|
|
888
|
+
ok: true,
|
|
889
|
+
counts: {
|
|
890
|
+
admitted: numberOr(own(admissions, 'admitted')),
|
|
891
|
+
admittedWithoutTask: numberOr(own(admissions, 'admitted_without_task')),
|
|
892
|
+
pendingTails: numberOr(own(tailRow, 'pending')),
|
|
893
|
+
staleTails: numberOr(own(tailRow, 'stale')),
|
|
894
|
+
completedTails: numberOr(own(tailRow, 'completed')),
|
|
895
|
+
lastAdmissionAt: stringOr(own(admissions, 'last_admission')),
|
|
896
|
+
},
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
const detail = error instanceof Error ? error.message.slice(0, 160) : String(error);
|
|
901
|
+
return { ok: false, reason: `governance_admission_counts_failed:${detail}`, nextAction: 'Inspect the workspace trajectory.db; the health surface degraded without mutating anything.' };
|
|
902
|
+
}
|
|
903
|
+
finally {
|
|
904
|
+
close();
|
|
905
|
+
}
|
|
906
|
+
}
|
|
@@ -24,6 +24,11 @@ export * from './product-telemetry/eligibility.js';
|
|
|
24
24
|
export * from './product-telemetry/exporter.js';
|
|
25
25
|
export * from './product-telemetry/milestone-readers.js';
|
|
26
26
|
export * from './product-telemetry/service.js';
|
|
27
|
+
export * from './codex-disclosure.js';
|
|
28
|
+
export * from './codex-ingestion-consent.js';
|
|
29
|
+
export * from './codex-worker-status.js';
|
|
30
|
+
export * from './codex-legacy-registration.js';
|
|
31
|
+
export * from './codex-transcript-locate.js';
|
|
27
32
|
export declare const HOST_RUNTIME_ROUTES: readonly ['before_prompt_build', 'before_tool_call', 'after_tool_call'];
|
|
28
33
|
export type HostRuntimeRoute = (typeof HOST_RUNTIME_ROUTES)[number];
|
|
29
34
|
export type HostRuntimePort = (event: HostEvent) => HostEventResult | Promise<HostEventResult>;
|
|
@@ -33,6 +33,20 @@ export * from './product-telemetry/eligibility.js';
|
|
|
33
33
|
export * from './product-telemetry/exporter.js';
|
|
34
34
|
export * from './product-telemetry/milestone-readers.js';
|
|
35
35
|
export * from './product-telemetry/service.js';
|
|
36
|
+
// PRI-625 Slice D: Codex conversation-ingestion consent — G2A frozen
|
|
37
|
+
// disclosure SSoT constant + workspace consent record (governance layer; the
|
|
38
|
+
// runtime gate remains the feature flag alone).
|
|
39
|
+
export * from './codex-disclosure.js';
|
|
40
|
+
export * from './codex-ingestion-consent.js';
|
|
41
|
+
// PRI-625 Slice D: ONE §15 worker-mode authority, moved from codex-adapter so
|
|
42
|
+
// the CLI, the Console, and the worker share the same semantics.
|
|
43
|
+
export * from './codex-worker-status.js';
|
|
44
|
+
// PRI-625 Slice D: ONE legacy-registration predicate (installer refusal,
|
|
45
|
+
// health dualRegistration, and future setup flows all read the same fact).
|
|
46
|
+
export * from './codex-legacy-registration.js';
|
|
47
|
+
// PRI-625 Slice D: transcript locator moved here so the §15 health service
|
|
48
|
+
// computes per-rollout lag with the SAME locator the catch-up path uses.
|
|
49
|
+
export * from './codex-transcript-locate.js';
|
|
36
50
|
export const HOST_RUNTIME_ROUTES = [
|
|
37
51
|
'before_prompt_build',
|
|
38
52
|
'before_tool_call',
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface CodexIngestQuarantineOptions {
|
|
2
|
+
workspace?: string;
|
|
3
|
+
rollout?: string;
|
|
4
|
+
record?: string;
|
|
5
|
+
reason?: string;
|
|
6
|
+
operator?: string;
|
|
7
|
+
confirm?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function handleCodexIngestQuarantine(options: CodexIngestQuarantineOptions): Promise<void>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=codex-ingest-quarantine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-ingest-quarantine.d.ts","sourceRoot":"","sources":["../../src/commands/codex-ingest-quarantine.ts"],"names":[],"mappings":"AAuBA,UAAU,4BAA4B;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAUD,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFtG"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pd codex ingest quarantine — audited recovery for permanently invalid
|
|
3
|
+
* governance observations (Codex Governance Closure Slice D, PRI-625;
|
|
4
|
+
* SPEC rev 2 §15).
|
|
5
|
+
*
|
|
6
|
+
* Contract (§15 verbatim requirements):
|
|
7
|
+
* - dry run by DEFAULT; `--confirm` is required to actually quarantine;
|
|
8
|
+
* - the quarantine record captures digest, reason, operator, timestamp, and
|
|
9
|
+
* the neighbor gap;
|
|
10
|
+
* - the Codex transcript is NEVER edited or read (only the workspace
|
|
11
|
+
* trajectory.db opens — asserted by the store tests via a port spy);
|
|
12
|
+
* - promoted (Owner-decided) evidence is refused;
|
|
13
|
+
* - --json emits exactly one documented object; failed validation mutates
|
|
14
|
+
* nothing.
|
|
15
|
+
*
|
|
16
|
+
* CLI gate compliance: cli-1 (single JSON object), cli-2 (exit paths stop),
|
|
17
|
+
* cli-5 (failed validation performs no mutation), cli-6 (reason + nextAction
|
|
18
|
+
* on every refusal).
|
|
19
|
+
*/
|
|
20
|
+
import * as os from 'os';
|
|
21
|
+
import { quarantineGovernanceObservation } from '@principles/host-runtime';
|
|
22
|
+
import { resolveWorkspaceDir } from '../resolve-workspace.js';
|
|
23
|
+
function defaultOperator() {
|
|
24
|
+
try {
|
|
25
|
+
return os.userInfo().username.slice(0, 40) || 'unknown';
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return 'unknown';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function handleCodexIngestQuarantine(options) {
|
|
32
|
+
const generatedAt = new Date().toISOString();
|
|
33
|
+
const refuse = (reason, nextAction) => {
|
|
34
|
+
const report = { generatedAt, host: 'codex', op: 'quarantine', status: 'refused', confirmed: options.confirm === true, reason, nextAction };
|
|
35
|
+
if (options.json) {
|
|
36
|
+
console.log(JSON.stringify(report));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log('Codex observation quarantine');
|
|
40
|
+
console.log(` status: ${report.status}`);
|
|
41
|
+
console.log(` reason: ${reason}`);
|
|
42
|
+
console.log(` next action: ${nextAction}`);
|
|
43
|
+
}
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
};
|
|
46
|
+
const rollout = typeof options.rollout === 'string' ? options.rollout.trim() : '';
|
|
47
|
+
if (rollout.length === 0) {
|
|
48
|
+
refuse('rollout_required', 'Pass --rollout <id> (the rollout identity whose record is invalid).');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const recordRaw = typeof options.record === 'string' ? options.record.trim() : '';
|
|
52
|
+
const recordId = /^\d+$/.test(recordRaw) ? Number.parseInt(recordRaw, 10) : Number.NaN;
|
|
53
|
+
if (!Number.isInteger(recordId) || recordId <= 0) {
|
|
54
|
+
refuse('record_required', 'Pass --record <id> with the numeric governance_observations.id to quarantine.');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const reason = typeof options.reason === 'string' ? options.reason.trim() : '';
|
|
58
|
+
if (reason.length === 0 || reason.length > 200) {
|
|
59
|
+
refuse('reason_required', 'Pass --reason "<why>" (1-200 chars) describing why the record is permanently invalid.');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const operator = (typeof options.operator === 'string' && options.operator.trim().length > 0 ? options.operator.trim() : defaultOperator()).slice(0, 80);
|
|
63
|
+
// resolveWorkspaceDir throws when no workspace can be determined — wrap so
|
|
64
|
+
// --json still emits exactly one structured refusal (cli-1/cli-6).
|
|
65
|
+
let workspaceDir;
|
|
66
|
+
try {
|
|
67
|
+
workspaceDir = resolveWorkspaceDir(options.workspace);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const message = error instanceof Error ? error.message.slice(0, 160) : String(error);
|
|
71
|
+
refuse('workspace_unresolved: ' + message, 'Run from inside a PD workspace or pass -w/--workspace <path> with an initialized .pd directory.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const result = quarantineGovernanceObservation({
|
|
75
|
+
workspaceDir,
|
|
76
|
+
hostKind: 'codex',
|
|
77
|
+
rolloutIdentity: rollout,
|
|
78
|
+
recordId,
|
|
79
|
+
reason,
|
|
80
|
+
operator,
|
|
81
|
+
confirm: options.confirm === true,
|
|
82
|
+
});
|
|
83
|
+
if (!result.ok) {
|
|
84
|
+
refuse(result.reason, result.nextAction);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const report = {
|
|
88
|
+
generatedAt,
|
|
89
|
+
host: 'codex',
|
|
90
|
+
op: 'quarantine',
|
|
91
|
+
status: 'ok',
|
|
92
|
+
dryRun: result.dryRun,
|
|
93
|
+
alreadyQuarantined: result.alreadyQuarantined,
|
|
94
|
+
confirmed: options.confirm === true,
|
|
95
|
+
record: result.record,
|
|
96
|
+
...(result.dryRun ? { nextAction: 'Dry run only — nothing was mutated. Re-run with --confirm to quarantine this record.' } : {}),
|
|
97
|
+
transcriptTouched: false,
|
|
98
|
+
};
|
|
99
|
+
if (options.json) {
|
|
100
|
+
console.log(JSON.stringify(report));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log('Codex observation quarantine');
|
|
104
|
+
console.log(` status: ${result.dryRun ? 'dry-run' : 'quarantined'}`);
|
|
105
|
+
if (result.alreadyQuarantined)
|
|
106
|
+
console.log(' note: record was already quarantined (idempotent)');
|
|
107
|
+
console.log(` record id: ${result.record.id} (${result.record.kind}, ${result.record.retentionClass})`);
|
|
108
|
+
console.log(` logical key: ${result.record.logicalKey}`);
|
|
109
|
+
console.log(` observed at: ${result.record.observedAt}`);
|
|
110
|
+
console.log(` digest: ${result.record.digest}`);
|
|
111
|
+
console.log(` gap: ${result.record.gap}`);
|
|
112
|
+
if (result.dryRun)
|
|
113
|
+
console.log(' next action: Dry run only — nothing was mutated. Re-run with --confirm to quarantine this record.');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=codex-ingest-quarantine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-ingest-quarantine.js","sourceRoot":"","sources":["../../src/commands/codex-ingest-quarantine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type CodexIngestionConsentDecision, type CodexIngestionConsentState } from '@principles/host-runtime';
|
|
2
|
+
export interface CodexSetupOptions {
|
|
3
|
+
workspace?: string;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
lang?: string;
|
|
6
|
+
accept?: boolean;
|
|
7
|
+
decline?: boolean;
|
|
8
|
+
showDisclosure?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface CodexSetupReport {
|
|
11
|
+
generatedAt: string;
|
|
12
|
+
host: 'codex';
|
|
13
|
+
workspace: string;
|
|
14
|
+
status: 'ok' | 'degraded';
|
|
15
|
+
decision?: CodexIngestionConsentDecision;
|
|
16
|
+
consentStateBefore: CodexIngestionConsentState;
|
|
17
|
+
consentState: CodexIngestionConsentState;
|
|
18
|
+
disclosureVersion: string;
|
|
19
|
+
ingestionFlag: {
|
|
20
|
+
name: 'codex_conversation_ingestion';
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
source: string;
|
|
23
|
+
};
|
|
24
|
+
hostCodexFlagEnabled: boolean;
|
|
25
|
+
warnings: string[];
|
|
26
|
+
reason?: string;
|
|
27
|
+
nextAction?: string;
|
|
28
|
+
}
|
|
29
|
+
type FlagWriteResult = {
|
|
30
|
+
ok: true;
|
|
31
|
+
enabled: boolean;
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
reason: string;
|
|
35
|
+
nextAction: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Enable/disable `features.codex_conversation_ingestion.enabled` in the
|
|
39
|
+
* workspace config.yaml with a line-targeted edit that preserves all other
|
|
40
|
+
* content (comments included). Atomic write; round-trip verified with the
|
|
41
|
+
* production loader, restored on any mismatch.
|
|
42
|
+
*/
|
|
43
|
+
export declare function setCodexConversationIngestionFlag(workspaceDir: string, enabled: boolean): FlagWriteResult;
|
|
44
|
+
export declare function handleCodexSetup(options: CodexSetupOptions): Promise<void>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=codex-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-setup.d.ts","sourceRoot":"","sources":["../../src/commands/codex-setup.ts"],"names":[],"mappings":"AAoCA,OAAO,EAQL,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAEhC,MAAM,0BAA0B,CAAC;AAGlC,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,IAAI,GAAG,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,6BAA6B,CAAC;IACzC,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,YAAY,EAAE,0BAA0B,CAAC;IACzC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE;QAAE,IAAI,EAAE,8BAA8B,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,oBAAoB,EAAE,OAAO,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,KAAK,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAuB1G;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe,CAyIzG;AA2BD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6MhF"}
|