fix(docs): require document_type and audience before publishing
Documents could be set to visibility: 'public' without document_type, audience, or status fields — either via bulk migration scripts or the upload-document.js script. This allowed internal session logs to appear in the public docs UI. Safeguards added: - Document.publish() now rejects if document_type or audience is missing - Document.publish() now sets status: 'current' automatically - upload-document.js requires --type and --category flags (was optional) - upload-document.js sets status: 'current' and document_type on insert Also archived 2 internal Phase 5 PoC session documents that were incorrectly public, and set status: 'current' on 4 legitimate public documents that were missing it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4c6c72847d
commit
4557f4b420
2 changed files with 40 additions and 1 deletions
|
|
@ -41,8 +41,10 @@ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
||||||
Usage: node scripts/upload-document.js <markdown-file> [options]
|
Usage: node scripts/upload-document.js <markdown-file> [options]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--category <cat> Category: getting-started, technical-reference, research-theory,
|
--category <cat> REQUIRED. Category: getting-started, technical-reference, research-theory,
|
||||||
advanced-topics, case-studies, business-leadership
|
advanced-topics, case-studies, business-leadership
|
||||||
|
--type <type> REQUIRED. Document type: working-paper, case-study, technical-report,
|
||||||
|
guide, reference, brief
|
||||||
--audience <aud> Audience: general, researcher, implementer, leader, advocate, developer
|
--audience <aud> Audience: general, researcher, implementer, leader, advocate, developer
|
||||||
--title <title> Override document title (extracted from H1 if not provided)
|
--title <title> Override document title (extracted from H1 if not provided)
|
||||||
--author <author> Document author (default: Agentic Governance Research Team)
|
--author <author> Document author (default: Agentic Governance Research Team)
|
||||||
|
|
@ -67,12 +69,14 @@ Examples:
|
||||||
# Upload research paper
|
# Upload research paper
|
||||||
node scripts/upload-document.js docs/research/my-paper.md \\
|
node scripts/upload-document.js docs/research/my-paper.md \\
|
||||||
--category research-theory \\
|
--category research-theory \\
|
||||||
|
--type working-paper \\
|
||||||
--audience researcher \\
|
--audience researcher \\
|
||||||
--tags "ai-safety,governance,research"
|
--tags "ai-safety,governance,research"
|
||||||
|
|
||||||
# Upload technical guide (no PDF)
|
# Upload technical guide (no PDF)
|
||||||
node scripts/upload-document.js docs/guides/setup.md \\
|
node scripts/upload-document.js docs/guides/setup.md \\
|
||||||
--category getting-started \\
|
--category getting-started \\
|
||||||
|
--type guide \\
|
||||||
--audience developer \\
|
--audience developer \\
|
||||||
--no-pdf
|
--no-pdf
|
||||||
|
|
||||||
|
|
@ -96,6 +100,7 @@ if (!mdFilePath) {
|
||||||
const options = {
|
const options = {
|
||||||
category: null,
|
category: null,
|
||||||
audience: 'general',
|
audience: 'general',
|
||||||
|
document_type: null,
|
||||||
title: null,
|
title: null,
|
||||||
author: 'Agentic Governance Research Team',
|
author: 'Agentic Governance Research Team',
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
@ -115,6 +120,9 @@ for (let i = 1; i < args.length; i++) {
|
||||||
case '--audience':
|
case '--audience':
|
||||||
options.audience = args[++i];
|
options.audience = args[++i];
|
||||||
break;
|
break;
|
||||||
|
case '--type':
|
||||||
|
options.document_type = args[++i];
|
||||||
|
break;
|
||||||
case '--title':
|
case '--title':
|
||||||
options.title = args[++i];
|
options.title = args[++i];
|
||||||
break;
|
break;
|
||||||
|
|
@ -481,6 +489,17 @@ async function uploadDocument() {
|
||||||
try {
|
try {
|
||||||
console.log('\n=== Tractatus Document Upload ===\n');
|
console.log('\n=== Tractatus Document Upload ===\n');
|
||||||
|
|
||||||
|
// SECURITY: Require --category and --type for public documents
|
||||||
|
const validTypes = ['working-paper', 'case-study', 'technical-report', 'guide', 'reference', 'brief'];
|
||||||
|
if (!options.category) {
|
||||||
|
console.error('❌ Error: --category is required. Available: getting-started, resources, research-theory, technical-reference, advanced-topics, business-leadership');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (!options.document_type || !validTypes.includes(options.document_type)) {
|
||||||
|
console.error(`❌ Error: --type is required. Available: ${validTypes.join(', ')}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify markdown file exists
|
// Verify markdown file exists
|
||||||
const mdPath = path.resolve(mdFilePath);
|
const mdPath = path.resolve(mdFilePath);
|
||||||
try {
|
try {
|
||||||
|
|
@ -559,7 +578,9 @@ async function uploadDocument() {
|
||||||
quadrant: null,
|
quadrant: null,
|
||||||
persistence: 'HIGH',
|
persistence: 'HIGH',
|
||||||
audience: options.audience,
|
audience: options.audience,
|
||||||
|
document_type: options.document_type,
|
||||||
visibility: 'public',
|
visibility: 'public',
|
||||||
|
status: 'current',
|
||||||
category: options.category,
|
category: options.category,
|
||||||
licence: options.licence,
|
licence: options.licence,
|
||||||
order: options.order,
|
order: options.order,
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,23 @@ class Document {
|
||||||
return { success: false, message: 'Document must have content before publishing' };
|
return { success: false, message: 'Document must have content before publishing' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SECURITY: Require document_type for public docs
|
||||||
|
const docType = doc.document_type;
|
||||||
|
if (!docType) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: 'Document must have a document_type before publishing. Set document_type to one of: working-paper, case-study, technical-report, guide, reference, brief'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECURITY: Require audience for public docs
|
||||||
|
if (!doc.audience) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: 'Document must have an audience before publishing. Set audience to one of: researcher, implementer, leader, general'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// SECURITY: Require valid category for public docs
|
// SECURITY: Require valid category for public docs
|
||||||
const category = options.category || doc.category;
|
const category = options.category || doc.category;
|
||||||
if (!category || category === 'none') {
|
if (!category || category === 'none') {
|
||||||
|
|
@ -241,6 +258,7 @@ class Document {
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
visibility: 'public',
|
visibility: 'public',
|
||||||
|
status: 'current',
|
||||||
category,
|
category,
|
||||||
order: options.order !== undefined ? options.order : doc.order,
|
order: options.order !== undefined ? options.order : doc.order,
|
||||||
workflow_status: 'published',
|
workflow_status: 'published',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue